例如,使用IEEE-754 32位二进制浮点,让我们表示1 / 3
的值.虽然不能精确计算,但0x3eaaaaab
生成的值与1 / 3
最接近.您可能希望以十进制形式写入值,并让编译器将十进制文字转换为二进制浮点数.
0.333333f -> 0x3eaaaa9f (0.333332986)
0.3333333f -> 0x3eaaaaaa (0.333333313)
0.33333333f -> 0x3eaaaaab (0.333333343)
0.333333333f -> 0x3eaaaaab (0.333333343)
您可以看到,8位(有效)十进制数字足以表示尽可能正确的值(最接近实际值).
我用π和e(自然对数的基数)进行了测试,两者都需要8位小数才能得到最正确的结果.
3.14159f -> 0x40490fd0 (3.14159012)
3.141593f -> 0x40490fdc (3.14159298)
3.1415927f -> 0x40490fdb (3.14159274)
3.14159265f -> 0x40490fdb (3.14159274)
2.71828f -> 0x402df84d (2.71828008)
2.718282f -> 0x402df855 (2.71828198)
2.7182818f -> 0x402df854 (2.71828175)
2.71828183f -> 0x402df854 (2.71828175)
然而,√2
似乎需要9位数字.
1.41421f -> 0x3fb504d5 (1.41420996)
1.414214f -> 0x3fb504f7 (1.41421402)
1.4142136f -> 0x3fb504f4 (1.41421366)
1.41421356f -> 0x3fb504f3 (1.41421354)
1.414213562f -> 0x3fb504f3 (1.41421354)
https://godbolt.org/z/W5vEcs695
从这些结果来看,一个包含9个有效数字的十进制浮点文字足以生成最正确的32位二进制浮点值,这可能是正确的.在实践中,如果存储额外数字的空间无关紧要,12~15位之类的数字肯定会行得通.
但我对它背后的数学很感兴趣.在这种情况下,如何确保9位数足够?对于double
或任意精度,是否有一个简单的公式来推导所需的位数?
当前的答案和 comments 中的链接证实,9
位数足以 payable most个 case ,但我发现了一个反例,其中9
位数是不够的.事实上,十进制格式的无限精度需要始终正确地转换(四舍五入到最接近的值)为某种二进制浮点格式(IEEE-754 binary32浮点用于讨论).
用9
个有效十进制数字表示的8388609.499
是8388609.50
.转换为float
的数字的值为8388610
.另一方面,用10
或更多数字表示的数字将始终保持原始值,并且转换为float
的数字的值为8388609
.
你可以看到8388609.499
需要超过9
个数字才能最准确地转换为float
.有无限多个这样的数字,以二进制浮点格式放置在非常接近两个可表示值的半点处.