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.234
和 minValue = -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,以确保您的值确实是最接近逻辑上应有的可表示值。由于 minValue
和 maxValue
是预先计算一次的,只需更改最后一步以将它们也四舍五入即可,例如:
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)
只计算一次)。
我正在对字符串值和浮点数 minValue 和 maxValue 进行简单比较,以检查值是否超出特定范围
if float(value) < minValue or float(value) > maxValue:
# show error and exit
除非 value 和 minValue 相同,否则它工作正常。因此,当 value = -1.234
和 minValue = -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,以确保您的值确实是最接近逻辑上应有的可表示值。由于 minValue
和 maxValue
是预先计算一次的,只需更改最后一步以将它们也四舍五入即可,例如:
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)
只计算一次)。