首页 > 解决方案 > print('%.70f' % (0.2 + 0.1)) 输出中的 36 位补丁

问题描述

我理解为什么0.1 + 0.2在 Python 3 中产生这个:

>>> 0.1 + 0.2
0.30000000000000004

...但我不明白为什么在如下所示的输出中间有一段 36 位(大部分)非零数字:

>>> print('%.70f' % (0.2 + 0.1))
0.3000000000000000444089209850062616169452667236328125000000000000000000

我确实希望 0.1 + 0.2 和最接近 0.1 + 0.2 的二进制 IEEE 754 浮点数之间存在差异,但我不明白为什么这种差异会导致 36 位表示(对应于大约 ~120 位的精度)。

我可以理解错误是否具有更小(< 53 位)的精度,或者具有(明显的)无限精度,可能是由于评估算法的伪影所致'%.70f' % (0.2 + 0.1)。但我无法理解会导致上面显示的 36 位补丁的错误。

标签: pythonfloating-pointieee-754

解决方案


您正在使用的 Python 实现显然将 IEEE-754 binary64 用于浮点。(这很常见,但 Python 没有强制要求。)

在这种格式中,数字表示为 2 的幂的倍数,其中使用的 2 的特定幂取决于数字的大小。(浮点格式也以其他数学上等效的方式描述,例如使用具有固定小数位数的有效位而不是我在此处使用的整数倍数。这种描述更容易解释手。)

对于 0.3 左右的数字,使用的 2 的幂是 2 −54。在舍入以适应浮点格式后添加.1and的结果是 5404319552844596 乘以 2 −54或 5404319552844596 / 2 54.2

这个数字 5404319552844596 / 2 54正好是 0.3000000000000000444089209850062616169452667236328125。


推荐阅读