具有17位或更多位数的双数精度

时间:2014-07-17 00:58:41

标签: c floating-point double precision digits

将大双(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.但数字有什么问题?!?

1 个答案:

答案 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的数字位数限制,转换这么大的数字的结果是无法预料和不安全的。