【问题标题】:Greater than or equal for floats failed大于或等于浮点数失败
【发布时间】:2017-01-17 07:00:34
【问题描述】:

我正在运行一个针对一些数据编写的小型 python 测试,并得到了一些奇怪的结果。归结为:

priceDiff = 219.92 - 219.52
if(priceDiff >= .40):
   print "YES"
else:
   print "NO"

结果是“否”

为什么 0.40 不 >= .40?

【问题讨论】:

  • 试试print(219.92 - 219.52)。你会感到惊讶。
  • 我尝试了 float.hex(priceDiff) 和 float.hex(.40),是的,我很惊讶,尽管我想我应该如此。自从我不得不争论浮点数以来已经有一段时间了,但我只是认为这会起作用(因为我只是在比较包含价格的数据)
  • 您不必走那么远。 priceDiff 是 0.39999999999997726,小于 0.4。
  • “永远不要测试浮点数是否相等”。在这种情况下,一种选择可能是编写一点回旋余地,将边界设置为意义较小且可能“不可能”的值,例如priceDiff >= 0.3995(或0.39999995)。为了获得完全的可预测性和准确性,请使用 Decimal 而不是 float。

标签: python floating-accuracy floating


【解决方案1】:

Python 以“Decimal”的形式提供了使用浮点数的受控环境。它提供了多种选项来控制/调整舍入量以及不同的策略。(https://docs.python.org/3.5/library/decimal.html#rounding-modes)。

from decimal import Decimal, ROUND_HALF_EVEN
a = Decimal(219.92).quantize(Decimal('.01'), rounding=ROUND_HALF_EVEN)
b = Decimal(219.52).quantize(Decimal('.01'), rounding=ROUND_HALF_EVEN)
priceDiff = a - b
cmp = Decimal(0.40).quantize(Decimal('.01'), rounding=ROUND_HALF_EVEN)

if priceDiff.compare(cmp) >= 0:
    print "YES"
else:
    print "NO"

print(d)
print(d2)
print(priceDiff)
print(cmp)

恕我直言,这在可读性和对精度敏感的 w.r.t 应用程序的计算实施方面更好。希望这会有所帮助

【讨论】:

    【解决方案2】:

    来自文档

    表示错误是指某些(实际上是大多数)小数 分数不能完全表示为二进制(以 2 为底)分数。 这就是为什么 Python(或 Perl、C、C++、Java、Fortran、 和许多其他人)通常不会显示您的确切十进制数 期望:

    0.1 + 0.2
    0.30000000000000004
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 2018-09-26
      • 2013-09-02
      相关资源
      最近更新 更多