为什么非常大的浮点值之间的比较在 python 中失败?

Why do comparisions between very large float values fail in python?

在我的理解中,sys.float_info.max 是最大可能的浮点值。但是,比较这么大的值似乎失败了

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

我认为这是因为精度有限?如果可以,在什么数值范围内可以安全运行?

上面的代码是 运行 和 Python 3.5.2.

也许如果您尝试打印这些数字,您会更好地理解它们是什么:

>>> sys.float_info.max
1.7976931348623157e+308
>>> sys.float_info.max - 1.0
1.7976931348623157e+308
>>> sys.float_info.max - 1e100
1.7976931348623157e+308
>>> sys.float_info.max - 1e300
1.7976931248623157e+308

请注意,打印输出几乎没有描述浮点数精度可能遇到的所有问题,但在这种情况下,"problems" 是微不足道的。可以看到只有最后一个数字不一样。

在典型的机器上 运行 Python,Python 浮点数有 53 位精度可用。如果您尝试更进一步,Python 将消除最小的部分,以便正确表示数字。

所以值 1 被吸收或取消,以便能够表示您要计算的高值。

通过减去(或加上)乘以 float epsilon 的值获得限制。

在我的机器上:

maxfloat == 1.7976931348623157e+308
epsilon == 2.220446049250313e-16

示例测试代码

import math
import sys

m = sys.float_info.max                        # type 'float'
eps = sys.float_info.epsilon

print(m == m-(m*(eps/10)))   # True
print(m == m-(m*eps))        # False

m*eps 是使比较失败必须减去的最小值。它总是相对于 m 值。