首页 > 解决方案 > Python如何处理浮点数的重复减法?

问题描述

我有一个非常简单的代码,它接受一个浮点数,并使用一个 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 时,不会发生这种情况。

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

标签: pythonpython-3.xfloating-point

解决方案


执行后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 附近,分辨率更高,因此附近的二进制浮点数更多,必须使用更多的数字来区分值。


推荐阅读