math.isclose()
的存在是为了确定两个值之间的差异是否在公差范围内。
据我了解,此公差的默认值为:
rel_tol = 1e-09
abs_tol = 0.0
如果我将两个值都设置为0.0
,则应该测试两个值是否相同。
这似乎适用于较小的值:
import math
math.isclose(1000, 1000, rel_tol=0.0, abs_tol=0.0) # True
math.isclose(1000, 1001, rel_tol=0.0, abs_tol=0.0) # False
但是它以非常大的值失败:
import math
import sys
math.isclose(sys.maxsize, sys.maxsize, rel_tol=0.0, abs_tol=0.0) # True
math.isclose(sys.maxsize, sys.maxsize-1, rel_tol=0.0, abs_tol=0.0) # True
math.isclose(sys.maxsize, sys.maxsize-100, rel_tol=0.0, abs_tol=0.0) # True
math.isclose(sys.maxsize, sys.maxsize-1000, rel_tol=0.0, abs_tol=0.0) # False
似乎还有相对的容忍度?
为什么会发生这种行为?
上面的代码是在Python 3.5.2。上运行的。
更新1:
使用非常大的float值时,似乎会发生类似的行为:
import math
import sys
m = sys.float_info.max # type 'float'
math.isclose(m, m) # True
math.isclose(m, m-1.0) # True
math.isclose(m, m-1e100) # True
math.isclose(m, m-1e300) # False
math.isclose(m, m, rel_tol=0.0, abs_tol=0.0) # True
math.isclose(m, m-1.0, rel_tol=0.0, abs_tol=0.0) # True
math.isclose(m, m-1e100, rel_tol=0.0, abs_tol=0.0) # True
math.isclose(m, m-1e300, rel_tol=0.0, abs_tol=0.0) # False
另一方面,比较运算符在这里也不起作用。
import math
import sys
m = sys.float_info.max # type 'float'
m == m # True
m < m # False
m > m # False
m == m-1.0 # True
m < m-1.0 # False
m > m-1.0 # False
m == m-1e100 # True
m < m-1e100 # False
m > m-1e100 # False
m == m-1e300 # False
m > m-1e300 # True
m < m-1e300 # False
更新2:
给出了对“ UPDATE 1”的答案here。
答案 0 :(得分:6)
sys.maxsize
是一个整数,但是math.isclose()
适用于浮点值。在64位框中,sys.maxsize
的精度比浮点数所能代表的精度高,因此float(sys.maxsize - N) == float(sys.maxsize)
用于所有足够小的正整数N
。
>>> from sys import maxsize as m
>>> m
9223372036854775807
>>> float(m)
9.223372036854776e+18
>>> float(m - 1) # identical
9.223372036854776e+18
>>> float(m - 100) # identical
9.223372036854776e+18
>>> float(m - 1000) # finally subtracting enough to make a tiny difference
9.223372036854775e+18
短期课程:当您想比较整数是否相等时,首先转换为float根本没有意义。