| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
x
 
 本帖最后由 hankc 于 2019-3-24 11:03 编辑  
 
正常代码: 
- #include <stdio.h>
 
 - #include <math.h>
 
  
- int main()
 
 - {
 
 -   unsigned long long sum = 0;
 
 -   unsigned long long temp;
 
 -   unsigned long long weight;
 
 -   int i;
 
  
-   for (i = 0; i < 64; i++)
 
 -   {
 
 -     temp = pow(2, i);
 
 -     sum = sum + temp;
 
 -   }
 
  
-   weight = sum / 25000;
 
  
-   printf("舍罕王应该给予达依尔%llu粒麦子!\n", sum);
 
 -   printf("如果每25000粒麦子为1kg,那么应该给%llu公斤麦子!\n", weight);
 
  
-   return 0;
 
 - }
 
  复制代码 
 
输出: 
- gcc -lm p1.c -o p1 && ./p1
 
 - 舍罕王应该给予达依尔18446744073709551615粒麦子!
 
 - 如果每25000粒麦子为1kg,那么应该给737869762948382公斤麦子!
 
  复制代码 
 
 
然后舍去 临时变量就会出现 溢出? 
-   for (i = 0; i < 64; i++)
 
 -   {
 
 -     sum = sum + pow(2, i);
 
 -   }
 
 
  复制代码 
 
输出: 
- gcc -lm p1.c -o p1 && ./p1
 
 - 舍罕王应该给予达依尔0粒麦子!
 
 - 如果每25000粒麦子为1kg,那么应该给0公斤麦子!
 
  复制代码 
 
这两段代码不是等价的吗? 
-   for (i = 0; i < 64; i++)
 
 -   {
 
 -     temp = pow(2, i);
 
 -     sum = sum + temp;
 
 -   }
 
  
-   for (i = 0; i < 64; i++)
 
 -   {
 
 -     sum = sum + pow(2, i);
 
 -   }
 
  复制代码 
 
至少在 63的循环内是等价的 
-   for (i = 0; i < 63; i++)
 
 -   {
 
 -     temp = pow(2, i);
 
 -     sum = sum + temp;
 
 -   }
 
 -  // 输出:
 
 - // gcc -lm p1.c -o p1 && ./p1
 
 - // 舍罕王应该给予达依尔9223372036854775808粒麦子!
 
 - // 如果每25000粒麦子为1kg,那么应该给368934881474191公斤麦子!
 
  
-  for (i = 0; i < 63; i++)
 
 -   {
 
 -     sum = sum + pow(2, i);
 
 -   }
 
 - // 输出:
 
 - // gcc -lm p1.c -o p1 && ./p1
 
 - // 舍罕王应该给予达依尔9223372036854775808粒麦子!
 
 - // 如果每25000粒麦子为1kg,那么应该给368934881474191公斤麦子!
 
  
  复制代码 
 
/* ---------------------------------------------------------------------- 后记 ----------------------------------------------------------------------*/ 
基于上述问题 和 答案 pow 函数是返回 double 的 又做了一次测试 
-   printf("short: %ld\n", sizeof(short));
 
 -   printf("unsigned short: %ld\n", sizeof(unsigned short));
 
 -   printf("int: %ld\n", sizeof(int));
 
 -   printf("unsigned int: %ld\n", sizeof(unsigned int));
 
 -   printf("long: %ld\n", sizeof(long));
 
 -   printf("unsigned long: %ld\n", sizeof(unsigned long));
 
 -   printf("long long: %ld\n", sizeof(long long));
 
 -   printf("unsigned long long: %ld\n", sizeof(unsigned long long));
 
 -   printf("float: %ld\n", sizeof(float));
 
 -   printf("double: %ld\n", sizeof(double));
 
  复制代码 
 
输出 
- short: 2
 
 - unsigned short: 2
 
 - int: 4
 
 - unsigned int: 4
 
 - long: 8
 
 - unsigned long: 8
 
 - long long: 8
 
 - unsigned long long: 8
 
 - float: 4
 
 - double: 8
 
  复制代码 
 
结果 unsigned long long 和 double 的 内存空间大小是一样的 
 
 
- // 1
 
 - temp = pow(2, i);
 
 - sum += temp;
 
  
- // 2
 
 - sum += (unsigned long long) pow(2, i);
 
  复制代码 
 
从 1和2两个运算 来看 这就很神奇了, `=` 赋值,看起来并没有隐式转换, 
 
`+` 运算,才是导致 `sum` 的数据类型发生转换的元凶。 
 
 本帖最后由 jackz007 于 2019-3-23 19:11 编辑 
      power() 返回 double 型结果,楼主把下面这一句:
 
      改成:
 -          sum = sum + (unsigned long long) pow(2 , i)  ;
 
  复制代码
      试试看是否有效果  
 
 
 |   
 
 
 
 |