鱼C论坛

 找回密码
 立即注册
查看: 805|回复: 13

[已解决]函数当作表达式时,为什么不能参与复合的赋值运算

[复制链接]
发表于 2020-6-7 19:12:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include<stdio.h>
#include<math.h>
int main()
{
    int t;
    unsigned long long int  sum=0,weight;
    for(t=0;t<64;t++)
    {
        sum+=pow(2,t);
    }
    weight=sum/25000;
    printf("舍罕王应给予达依尔%llu粒麦子!\n",sum);
    printf("如果一公斤小麦有25000粒,舍罕王应给予达依尔%llu公斤麦子!\n",weight);
    return 0;
}
这个结果就不对!(原因在第九行那个pow()),请大神解释一下。万分感谢!
最佳答案
2020-6-7 20:24:53
永恒的蓝色梦想 发表于 2020-6-7 20:22
好吧,我发现了,9223372036854775807 和 9223372036854775807.0 加法出现错误的结果。

      2251799813685247 +       2251799813685248 =       4503599627370495
      4503599627370495 +       4503599627370496 =       9007199254740991
      9007199254740991 +       9007199254740992 =      18014398509481983  // 看这
     18014398509481984 +      18014398509481984 =      36028797018963968 // 事实上,在这里莫名其妙错了
     36028797018963968 +      36028797018963968 =      72057594037927936
     72057594037927936 +      72057594037927936 =     144115188075855872
    144115188075855872 +     144115188075855872 =     288230376151711744
    288230376151711744 +     288230376151711744 =     576460752303423488
    576460752303423488 +     576460752303423488 =    1152921504606846976
   1152921504606846976 +    1152921504606846976 =    2305843009213693952
   2305843009213693952 +    2305843009213693952 =    4611686018427387904
   4611686018427387904 +    4611686018427387904 =    9223372036854775808
   9223372036854775808 +    9223372036854775808 =                      0
舍罕王应给予达依尔0粒麦子!
int bar() {
    int t;
    unsigned long long sum = 0, weight;
    for (t = 0; t < 64; t++) {
        unsigned long long current = pow(2, t);
        printf("%22llu + %22llu = %22llu\n", sum, current, sum + current);
        sum += pow(2, t);
    }
    weight = sum / 25000;
    printf("舍罕王应给予达依尔%llu粒麦子!\n", sum);
    printf("如果一公斤小麦有25000粒,舍罕王应给予达依尔%llu公斤麦子!\n", weight);
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-7 19:20:57 | 显示全部楼层
我不清楚,为什么不把错误信息一起放出来,是在考验我们吗?

但是,一个明显的错误是,你的程序有溢出漏洞。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 19:44:28 | 显示全部楼层
赚小钱 发表于 2020-6-7 19:20
我不清楚,为什么不把错误信息一起放出来,是在考验我们吗?

但是,一个明显的错误是,你的程序有溢出漏 ...

很明显,这个数卡在了 unsigned long long 的边上,没溢出。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:15:10 | 显示全部楼层
pow -> powl
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:18:53 | 显示全部楼层
本帖最后由 赚小钱 于 2020-6-7 20:20 编辑
永恒的蓝色梦想 发表于 2020-6-7 19:44
很明显,这个数卡在了 unsigned long long 的边上,没溢出。


pow 的返回值是 double,和 unsigned long long 运算就可能会出现精度问题。
这就是漏洞。

这也是我讨厌 c,python 的原因,不是强类型语言,不同类型之间竟然可以运算。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:22:35 | 显示全部楼层
赚小钱 发表于 2020-6-7 20:18
pow 的返回值是 double,和 unsigned long long 运算就可能会出现精度问题。
这就是漏洞。

好吧,我发现了,9223372036854775807 和 9223372036854775807.0 加法出现错误的结果。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:23:03 | 显示全部楼层

powl 的返回值是 long double,结果不会有任何差别。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:24:53 | 显示全部楼层    本楼为最佳答案   
永恒的蓝色梦想 发表于 2020-6-7 20:22
好吧,我发现了,9223372036854775807 和 9223372036854775807.0 加法出现错误的结果。

      2251799813685247 +       2251799813685248 =       4503599627370495
      4503599627370495 +       4503599627370496 =       9007199254740991
      9007199254740991 +       9007199254740992 =      18014398509481983  // 看这
     18014398509481984 +      18014398509481984 =      36028797018963968 // 事实上,在这里莫名其妙错了
     36028797018963968 +      36028797018963968 =      72057594037927936
     72057594037927936 +      72057594037927936 =     144115188075855872
    144115188075855872 +     144115188075855872 =     288230376151711744
    288230376151711744 +     288230376151711744 =     576460752303423488
    576460752303423488 +     576460752303423488 =    1152921504606846976
   1152921504606846976 +    1152921504606846976 =    2305843009213693952
   2305843009213693952 +    2305843009213693952 =    4611686018427387904
   4611686018427387904 +    4611686018427387904 =    9223372036854775808
   9223372036854775808 +    9223372036854775808 =                      0
舍罕王应给予达依尔0粒麦子!
int bar() {
    int t;
    unsigned long long sum = 0, weight;
    for (t = 0; t < 64; t++) {
        unsigned long long current = pow(2, t);
        printf("%22llu + %22llu = %22llu\n", sum, current, sum + current);
        sum += pow(2, t);
    }
    weight = sum / 25000;
    printf("舍罕王应给予达依尔%llu粒麦子!\n", sum);
    printf("如果一公斤小麦有25000粒,舍罕王应给予达依尔%llu公斤麦子!\n", weight);
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:25:49 | 显示全部楼层
赚小钱 发表于 2020-6-7 20:18
pow 的返回值是 double,和 unsigned long long 运算就可能会出现精度问题。
这就是漏洞。

因为 Python 有 radd

C 的类型转换也是一大槽点,各种奇葩操作
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:25:49 | 显示全部楼层
永恒的蓝色梦想 发表于 2020-6-7 20:23
powl 的返回值是 long double,结果不会有任何差别。

你试一下,it works on my machine.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:28:57 | 显示全部楼层
赚小钱 发表于 2020-6-7 20:25
你试一下,it works on my machine.

试了一下你 8L 的代码,在我这里,pow 和 powl 没出现区别。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-7 20:29:03 | 显示全部楼层
赚小钱 发表于 2020-6-7 19:20
我不清楚,为什么不把错误信息一起放出来,是在考验我们吗?

但是,一个明显的错误是,你的程序有溢出漏 ...

抱歉啊,本来是想贴图的(但我还不会贴图。。。)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:31:35 | 显示全部楼层
永恒的蓝色梦想 发表于 2020-6-7 20:28
试了一下你 8L 的代码,在我这里,pow 和 powl 没出现区别。

好吧,毕竟 c 不是跨平台的语言,我就没办法了。我的是 gcc 10.1.0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 20:35:17 | 显示全部楼层
赚小钱 发表于 2020-6-7 20:31
好吧,毕竟 c 不是跨平台的语言,我就没办法了。我的是 gcc 10.1.0

我是 Visual Studio 2019 。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-13 15:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表