适用于Python 2.6的浮动比较解决方案

时间:2019-01-25 17:54:25

标签: python floating-point comparison python-2.x 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是多项式函数的结果,但是我不认为这里有任何截断或舍入。

这里是计算minValue的函数

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

2 个答案:

答案 0 :(得分:1)

请注意,通常,如果没有Decimal,这是无法解决的;浮点数学运算在许多计算中本质上都是不精确的,并且逻辑上应该到达-1.234的内容很容易变成-1.2339999999999998-1.2340000000000002(仅用于说明,您的计算机可能有所不同,但它们是最接近的我机器上任一侧的-1.234的值都不会四舍五入为-1.234的规范表示;您的计算可能就那么接近了,或者可能还差了一点,但是误差仍然可能小于0.00000000001)。

也就是说,如果您确切地知道自己的值永远不需要超过X个小数位精度,那么通常可以通过{ {3}},以确保您的值实际上是与逻辑上最接近的可表示值。由于floatminValue似乎是预先计算的,因此只需更改最后一步以将它们四舍五入,例如:

maxValue

消除了任何多余的精度。哎呀,如果您不确定要达到的精确度,只需将最佳猜测加倍即可;在大多数情况下,您可能会看到的不精确度通常在小数点后10位以内,因此,如果您仅认为需要三位数字,便会担心仍会删除有效数据(例如,也许除以minValue = round(min(y), 3) maxValue = round(max(y), 3) 可能会在结尾处留下一个额外的有效8),再增加一点,四舍五入到125,甚至舍去6小数位。

类似地,更改执行比较的代码也将9标准化,例如:

value

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

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

充分利用了Python的链式比较运算符(等同于键入if not minValue <= round(float(value), 3) <= maxValue: ,只是if not (minValue <= round(float(value), 3) and round(float(value), 3) <= maxValue):仅计算一次)。

答案 1 :(得分:-2)

它不起作用的原因是因为-1.234不大于或小于-1.234-1.234 > 1.234为假,-1.234 < 1.234也为假。如果还想使它们相等,则需要使用=>=<,这意味着“大于或等于”

>>> 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