将大双(17位数)转换为整数时,我得到精度损失。
#include <stdio.h>
int main() {
int n = 20;
double acum = 1;
while (n--) acum *= 9;
printf("%.0f\n", acum);
printf("%llu\n", (unsigned long long)acum);
return 0;
}
此代码的输出为:
12157665459056929000
12157665459056928768
我不能使用无符号long long进行计算,因为这只是一个伪代码,我需要实数代码的精度,其中包含了分区。
如果我增加小数,则第一个输出变为,例如12157665459056929000.0000000000。 我尝试过圆(acum)和trunc(acum),在这两种情况下结果与第二个输出相同。它们不应该等于第一个??
我知道浮点数的精度只有6位小数,而双精度数大约为17.但数字有什么问题?!?
答案 0 :(得分:1)
实际上,当我将acum的类型更改为 unsigned long long 时:
unsigned long long acum = 1;
结果是:
12157665459056928801
当我使用Python计算准确答案时:
>>9**20
12157665459056928801L
12157665459056929000
根本不是一个准确的答案,实际上是准确答案的近似值。
然后我改变代码:
printf("%llu\n", (unsigned long long)1.2157665459056929e+019);
printf("%llu\n", (unsigned long long)1.2157665459056928e+019);
printf("%llu\n", (unsigned long long)1.2157665459056927e+019);
printf("%llu\n", (unsigned long long)1.2157665459056926e+019);
结果是:
12157665459056928768
12157665459056928768
12157665459056926720
12157665459056926720
事实上,19位数字超过了cpp的数字位数限制,转换这么大的数字的结果是无法预料和不安全的。