为什么我需要17位有效数字(而不是16位)才能代表双倍数?

Ond*_*tík 14 c floating-accuracy

有人能给我一个浮点数(双精度)的例子,需要超过16个有效十进制数来表示它吗?

我在这个帖子中发现,有时候你需要多达17位,但我无法找到这样一个数字的例子(16对我来说似乎足够了).

有人可以澄清一下吗?

非常感谢!

Nem*_*emo 10

我的另一个答案是错误的.

#include <stdio.h>

int
main(int argc, char *argv[])
{
    unsigned long long n = 1ULL << 53;
    unsigned long long a = 2*(n-1);
    unsigned long long b = 2*(n-2);
    printf("%llu\n%llu\n%d\n", a, b, (double)a == (double)b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译并运行以查看:

18014398509481982
18014398509481980
0
Run Code Online (Sandbox Code Playgroud)

a和b只是2*(2 ^ 53-1)和2*(2 ^ 53-2).

这些是17位数的基数为10的数字.四舍五入到16位时,它们是相同的.然而a和b显然只需要53位精度来表示base-2.因此,如果你拿a和b并将它们加倍,你得到反例.

  • 顺便说一下,这是一个简单的方法来证明为什么我们需要17位数:如果可以加到1的最小双数是epsilon~2e-16,那么1 + epsilon = 1.0000000000000002,这显然需要17位数来表示. (4认同)