Python 2.6的浮点比较方案

Float comparison solution for Python 2.6

我正在对字符串值和浮点数 minValue 和 maxValue 进行简单比较,以检查值是否超出特定范围

if float(value) < minValue or float(value) > maxValue:
    # show error and exit

除非 value 和 minValue 相同,否则它工作正常。因此,当 value = -1.234minValue = -1.234 时,它进入 if 语句内部,因为由于某种原因 -1.234 < -1.234 计算为 True.

我的解决方法是使用十进制

if Decimal(value) < Decimal(str(minValue)) or Decimal(str(value) > Decimal(maxValue):
    # show error and exit

但是 Decimal(str(minValue)) 看起来有点乱,所以我想知道是否有更好的方法来比较两个浮点数,当它们是相同的值时不会失败,而不必将浮点数转换为字符串再转换为十进制首先转换。

编辑

value 来自 csv 文件,因此那里没有截断。你所看到的就是你得到的。然而,minValue 是多项式函数的结果,但我不认为那里有任何截断或舍入。

这是计算最小值的函数

f = numpy.poly1d(coefficients)
x = range(int(low), int(high), 1)
y = f(x)
minValue = min(y)
maxValue = max(y)

它不起作用的原因是因为 -1.234 不大于或小于 -1.234-1.234 > 1.234 为假,-1.234 < 1.234 也为假。如果你想在它们相等的情况下也使它成立,你需要使用 =>=< ,这意味着 "greater then or equal to"

>>> value=-1.234
>>> maxValue=-1.234
>>> minValue=-1.234
>>> float(value)
-1.234
>>> float(value) < minValue or float(value) > maxValue
False
>>> float(value) <= minValue or float(value) >= maxValue
True

请注意,一般来说,如果没有 Decimal,这将无法解决;浮点数学在许多计算中本质上是不精确的,逻辑上应该到达 -1.234 的结果很容易变成 -1.2339999999999998-1.2340000000000002 (仅供说明,您的计算机可能不同,但那些是最接近的我机器上任何一侧的 -1.234 值都不会四舍五入到 -1.234 的规范表示;您的计算可能非常接近,或者可能相差更多,但是可能仍然小于 0.00000000001).

的错误

就是说,如果您碰巧确切地知道您的值永远不需要超过 X 个小数位的精度,您通常可以使用更快的 float,通过 the round function,以确保您的值确实是最接近逻辑上应有的可表示值。由于 minValuemaxValue 是预先计算一次的,只需更改最后一步以将它们也四舍五入即可,例如:

minValue = round(min(y), 3)
maxValue = round(max(y), 3)

这会消除任何虚假的过高精度。哎呀,如果您不确定需要多精确,只需将您的最佳猜测加倍即可;在大多数情况下,您可能会看到的不精确性通常远远超过小数点后 10 位数字,因此如果您认为只需要三位数字,但又担心您可能仍会删除有效数据(例如,也许您有除以 8 可能会在末尾留下一个额外的有效 125),再向上一点,四舍五入到 6,甚至 9 小数位。

同样,将执行比较的代码也更改为规范化 value,例如:

if round(float(value), 3) < minValue or round(float(value), 3) > maxValue:

甚至更好(避免将转换代码加倍):

if not minValue <= round(float(value), 3) <= maxValue:

利用了 Python 的链式比较运算符(相当于输入 if not (minValue <= round(float(value), 3) and round(float(value), 3) <= maxValue):,除了 round(float(value), 3) 只计算一次)。