| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
x
 
#include <stdio.h> 
#include <math.h> 
 
double sum(int start , int end) 
{ 
    double ret = 0; 
    int i = start; 
 
    while (i < end) 
    { 
        ret = ret + pow(2,i); 
        i++; 
    } 
     
    return ret; 
} 
 
int main(void) 
{ 
    double result; 
    double weight; 
 
    result = sum(0,64); 
    weight = result / 25000; 
 
    printf("舍罕王应该给予达依尔%.0f粒麦子!\n",result); 
    printf("如果每25000粒麦子为1kg,那么应该给%.0fkg麦子!\n",weight); 
 
    return 0; 
}
 本帖最后由 jackz007 于 2025-4-17 01:00 编辑 
        应该是采用 double 数据类型累加所产生的计算误差。 
        请编译、运行下面的代码,这个代码会按长整型和双精度浮点数分别计算累加结果,从打印结果看,一开始,二者累加结果均一致,但是,当 i = 53 的时候,累加结果开始出现错位,双精度数的累加结果比长整型大 1。
 - #include <math.h>
 
  
- double sum(int start , int end)
 
 - {
 
 -     double ret1 = 0.0                                                   ;
 
 -     unsigned long long ret2 = 0LL                                       ;
 
 -     int i = start                                                       ;
 
  
-     while (i < end)
 
 -     {
 
 -         ret1 += pow(2 , i)                                              ;
 
 -         ret2 += 1LL << i                                                ;
 
 -         printf("%2d , %.0lf , %llu\n" , i , ret1 , ret2)                ;
 
 -         i ++                                                            ;
 
 -     }
 
 -     return ret1                                                         ;
 
 - }
 
  
- int main(void)
 
 - {
 
 -     double result ,  weight                                             ;
 
 -     result = sum(0 , 64)                                                ;
 
 -     weight = result / 25000                                             ;
 
  
-     printf("舍罕王应该给予达依尔%.0lf粒麦子!\n" , result)              ;
 
 -     printf("如果每25000粒麦子为1kg,那么应该给%.0lfkg麦子!\n",weight)  ;
 
 -     return 0                                                            ;
 
 - }
 
  复制代码
        编译、运行实况:
 - D:\[00.Exercise]\[C]>g++ -o x x.c
 
  
- D:\[00.Exercise]\[C]>x
 
 -  0 , 1 , 1
 
 -  1 , 3 , 3
 
 -  2 , 7 , 7
 
 -  3 , 15 , 15
 
 -  4 , 31 , 31
 
 -  5 , 63 , 63
 
 -  6 , 127 , 127
 
 -  7 , 255 , 255
 
 -  8 , 511 , 511
 
 -  9 , 1023 , 1023
 
 - 10 , 2047 , 2047
 
 - 11 , 4095 , 4095
 
 - 12 , 8191 , 8191
 
 - 13 , 16383 , 16383
 
 - 14 , 32767 , 32767
 
 - 15 , 65535 , 65535
 
 - 16 , 131071 , 131071
 
 - 17 , 262143 , 262143
 
 - 18 , 524287 , 524287
 
 - 19 , 1048575 , 1048575
 
 - 20 , 2097151 , 2097151
 
 - 21 , 4194303 , 4194303
 
 - 22 , 8388607 , 8388607
 
 - 23 , 16777215 , 16777215
 
 - 24 , 33554431 , 33554431
 
 - 25 , 67108863 , 67108863
 
 - 26 , 134217727 , 134217727
 
 - 27 , 268435455 , 268435455
 
 - 28 , 536870911 , 536870911
 
 - 29 , 1073741823 , 1073741823
 
 - 30 , 2147483647 , 2147483647
 
 - 31 , 4294967295 , 4294967295
 
 - 32 , 8589934591 , 8589934591
 
 - 33 , 17179869183 , 17179869183
 
 - 34 , 34359738367 , 34359738367
 
 - 35 , 68719476735 , 68719476735
 
 - 36 , 137438953471 , 137438953471
 
 - 37 , 274877906943 , 274877906943
 
 - 38 , 549755813887 , 549755813887
 
 - 39 , 1099511627775 , 1099511627775
 
 - 40 , 2199023255551 , 2199023255551
 
 - 41 , 4398046511103 , 4398046511103
 
 - 42 , 8796093022207 , 8796093022207
 
 - 43 , 17592186044415 , 17592186044415
 
 - 44 , 35184372088831 , 35184372088831
 
 - 45 , 70368744177663 , 70368744177663
 
 - 46 , 140737488355327 , 140737488355327
 
 - 47 , 281474976710655 , 281474976710655
 
 - 48 , 562949953421311 , 562949953421311
 
 - 49 , 1125899906842623 , 1125899906842623
 
 - 50 , 2251799813685247 , 2251799813685247
 
 - 51 , 4503599627370495 , 4503599627370495
 
 - 52 , 9007199254740991 , 9007199254740991
 
 - 53 , 18014398509481984 , 18014398509481983               <--- 【请注意这一行】
 
 - 54 , 36028797018963968 , 36028797018963967
 
 - 55 , 72057594037927936 , 72057594037927935
 
 - 56 , 144115188075855872 , 144115188075855871
 
 - 57 , 288230376151711744 , 288230376151711743
 
 - 58 , 576460752303423488 , 576460752303423487
 
 - 59 , 1152921504606846976 , 1152921504606846975
 
 - 60 , 2305843009213693952 , 2305843009213693951
 
 - 61 , 4611686018427387904 , 4611686018427387903
 
 - 62 , 9223372036854775808 , 9223372036854775807
 
 - 63 , 18446744073709551616 , 18446744073709551615
 
 - 舍罕王应该给予达依尔18446744073709551616粒麦子!
 
 - 如果每25000粒麦子为1kg,那么应该给737869762948382kg麦子!
 
  
- D:\[00.Exercise]\[C]>
 
  复制代码 
        为了进一步证明是数据类型误差,本人编写了下面的代码:
 - #include <stdio.h>
 
  
- int main(void)
 
 - {
 
 -         double r1                                    ;
 
 -         unsigned long long r2                        ;
 
  
-         r1 = 9007199254740991.0 + 9007199254740992.0 ;
 
 -         r2 = 9007199254740991   + 9007199254740992   ;
 
 -         printf("%.0lf , %llu\n" , r1 , r2)           ;
 
 - }
 
  复制代码
        这个代码分别用双精度浮点数和无符号长整形计算 9007199254740991 + 9007199254740992,运算结果显示,双精度浮点数的计算结果与无符号长整形数的计算结果真的不同,很显然,双精度浮点数的计算结果是错误的,这也是楼主计算结果有误差的根本原因。 
        下面是编译、运行实况:
 - D:\[00.Exercise]\[C]>g++ -o x x.c
 
  
- D:\[00.Exercise]\[C]>x
 
 - 18014398509481984 , 18014398509481983
 
  
- D:\[00.Exercise]\[C]>
 
  复制代码 
         
         所以,解决方案就是,对麦粒进行计数要使用 unsigned long long,避免使用 double,下面是参考代码:
 - #include <stdio.h>
 
  
- int main(void)
 
 - {
 
 -         unsigned long long result = 0LL                                     ;
 
 -         double weight                                                       ;
 
 -         for(int i = 0 ; i < 64 ; i ++) result += 1LL << i                   ;
 
 -         weight = result / 25000                                             ;
 
  
-         printf("舍罕王应该给予达依尔%llu粒麦子!\n" , result)               ;
 
 -         printf("如果每25000粒麦子为1kg,那么应该给%.0lfkg麦子!\n",weight)  ;
 
 -         return 0                                                            ;
 
 - }
 
  复制代码 
 
 
 |   
 
 
 
 |