检查浮点数是否相等时无限循环

Tot*_*e99 12 python loops floating-accuracy while-loop

运行此代码时出现无限循环:

intensity = 0.50
while intensity != 0.65:
    print(intensity)
    intensity = intensity + 0.05
Run Code Online (Sandbox Code Playgroud)

强度值应该像 0.50 -> 0.55 -> 0.60 -> 0.65 然后它应该退出循环。为什么程序会执行无限循环?

pax*_*blo 9

由于浮点不精确,您最终可能不会得到精确的 0.65.

要解决此问题,请使用<而不是!= (a)

intensity = 0.50
while intensity < 0.65:
    print(intensity)
    intensity = intensity + 0.05
Run Code Online (Sandbox Code Playgroud)

其输出(也显示了我所说的不精确)是:

0.5
0.55
0.6000000000000001
Run Code Online (Sandbox Code Playgroud)

如果你继续前进,你会看到:

0.6500000000000001
0.7000000000000002
0.7500000000000002
0.8000000000000003
Run Code Online (Sandbox Code Playgroud)

这就是为什么它永远不等于0.65.


(a)您可能想知道如果下一个值是0.6499...9而不是0.650..1,情况会怎样,您的担心可能是正确的。

虽然使用<将解决后一种情况,但对于前一种情况,您几乎肯定会得到太多的迭代。

您可以通过多种可能的不同策略来解决这个问题,其中一些是:

  • 在比较之前将数字四舍五入到正确的小数位数,例如round(intensity, 2).
  • 将其与“足够接近”的检查进行比较,例如绝对差异小于(例如) - 类似.10-4if abs(intensity - 0.65) < 0.0001
  • 仅使用整数值并根据需要缩放该值(例如,初始化intensity50、添加5、比较为65和打印round(intensity / 100, 2).

Python 文档中有一篇有趣的文章,您可以阅读该文章以进一步了解这些限制。