Python如何处理重复的浮数减法?

时间:2019-02-11 12:13:24

标签: python python-3.x floating-point

我有一个非常简单的代码,该代码采用浮点数,并使用while循环将1减去直到达到零:

nr = 4.2
while nr > 0:
    print(nr)
    nr -= 1

我希望输出看起来像这样:

4.2
3.2
2.2
etc...

但是,我得到了:

4.2
3.2
2.2
1.2000000000000002
0.20000000000000018

这些奇怪的浮动数字从何而来?为什么只在第三次执行循环后才发生?而且,非常有趣的是,当nr的最后一个小数为5时,不会发生这种情况。

发生了什么事,我该如何预防?

1 个答案:

答案 0 :(得分:0)

执行nr = 4.2后,您的Python将nr设置为正好为4.20000000000000017763568394002504646778106689453125。这是将4.2转换为基于二进制的浮点格式所产生的值。

显示的后续减法结果似乎仅由于格式化决定而在低位数字变化。浮点数的默认格式不会显示所有数字。 Python对浮点行为并不严格,但是我怀疑您的实现可能会显示与唯一区分二进制浮点数所需的一样多的十进制数字。

对于“ 4.2”,“ 3.2”和“ 2.2”,这仅是两个有效数字,因为这些十进制数字接近实际的二进制浮点值。

在1.2附近,浮点格式具有更高的分辨率(因为该值降至2以下,这意味着指数减小了,因此有效位数的有效位置降低了,从而允许它在绝对范围内包含另一位分辨率) 。结果,碰巧在1.2附近有另一个二进制浮点数,因此显示“ 1.2000000000000002”以将nr中当前的数字与该其他数字区分开。

.2附近的分辨率更高,因此附近还有更多的二进制浮点数,并且必须使用更多的数字来区分值。