奇怪的Python while循环在<比较时的行为

1 投票
6 回答
689 浏览
提问于 2025-04-17 10:32

我对这段代码有点困惑:

t=0
while  t<5:  #currently loop runs for 10 seconds
    print "in loop",t
    if (t<5):
        print "true"
    t=t+0.01

在循环的最后一次运行时打印:

in loop 5.0 
true

现在,如果在循环的最后一次运行时 t = 5.0,那么在 if 语句中 t < 5 的条件不应该不成立吗?而且,t=5 的时候,循环应该也不会执行,因为它应该也不满足 while 的条件吧?

6 个回答

1

在最后一次循环中,t的值接近5.0,但实际上稍微低于5.0。因为在计算机中,0.01不能被精确表示,所以每次把0.01加到t上时,就会产生一点小误差。Python认为这个结果已经足够接近5.0,所以显示为“5.0”,但实际上它并不完全等于5.0。

如果你想让它按你预期的那样工作,可以使用Decimal,它不会出现这些舍入误差。

from decimal import Decimal
t=Decimal("0")
while  t<5:
    print "in loop",t
    if (t<5):
        print "true"
    t=t+Decimal("0.01")
1

这是因为在打印的时候,数值会被四舍五入。这是完全可以预料到的结果。

如果你想避免这种情况,可以换一种方式来格式化你的输出,或者使用一个合适的误差值来进行比较,比如 5.0 - t < delta

delta 是你可以随意选择的任何数字值——它定义了在你的需求下,多少接近5就可以算作等于5,因为一般来说,十进制的数值不能用纯二进制的方式完全准确地表示。

如果在你的应用中这样做不可接受,另一种选择是使用一个内部使用十进制表示的十进制类。

3

5 不一定就是 5:

t=0
while  t<5:  #currently loop runs for 10 seconds
    print "in loop",t, repr(t)
    if (t<5):
        print "true"
    t=t+0.1

会产生

in loop 0 0
true
in loop 0.1 0.1
true
in loop 0.2 0.2
true
in loop 0.3 0.30000000000000004

[...]

in loop 4.8 4.799999999999999
true
in loop 4.9 4.899999999999999
true
in loop 5.0 4.999999999999998
true

0.1 在二进制中不能被精确表示。

[哦,我刚注意到我用了 0.1 而不是 0.01,就像你那样。好吧,这其实是同样的问题。]

关于“浮点数是怎么工作的”有两个参考资料:经典的更温和的

撰写回答