发布网友 发布时间:2022-08-17 06:30
共1个回答
热心网友 时间:2023-10-10 15:03
经测试,这个问题与xcode无关,因为用codeblocks测试,也会出现相同的现象。
因为没有查到相关理论,下面说一说推测:
(1)直接用sum += pow,累计了计算误差,使得最终计算结果溢出。因为sum最终值为2^64,这是unsigned long long能够表示的最大值,所以只要误差累积超过1,就会溢出,使得sum为0。
(2)添加tmp变量,通过tmp=pow(2,i)截断了pow函数的计算结果(因为pow函数返回值类型为double),这样就不会累积误差了,所以最后得到了sum=2^64的正确结果。
---
以下是对上述推测的测试分析:
考虑到二进制数特征:sum = 2^0 + 2^1 + …… + 2^(n-1) = 2^n - 1
如上图1所示,采用sum += pow(2,i)计算,当i=54时,sum值与2^55值相等,这是错误的,实际上sum值应该为2^55 - 1。由此推断计算误差累积导致最终结果溢出。从此处开始,sum值便不正确了。
如上图2,从i=54开始进行tmp=pow(2,i)计算。因为tmp=pow(2,i)在后续计算之前便做了截断,所以最终得到sum=2^64这个正确结果。这与一开始就用tmp=pow(2,i)计算的结果是一致的。