Python 的 epsilon 值正确吗?

Bul*_*ull 6 python numpy numeric numerical-methods

根据维基百科

机器 epsilon 被定义为最小的数字,当它与 1 相加时,会产生与 1 不同的结果

在 Python 中,可以使用 epsilon 找到它sys.float_info.epsilon并返回相当于 2^-52 的值。但是,我可以将任何大于 2^-53 的数字与 1 相加,但仍然得到与 1 不同的结果。但根据上面 epsilon 的定义,将任何小于 epsilon 的值加到 1 应该得到 1。这是否意味着sys.float_info.epsilon返回了错误的值,或者 Python 正在使用 epsilon 的其他定义?

以下代码说明了这一点,并以十六进制格式打印出浮点数。

import sys
import numpy
print 'epsilon=%g' % sys.float_info.epsilon
# output: 2.22045e-16
epsilon = sys.float_info.epsilon
print 'epsilon(hex) = %s' % float.hex(epsilon)
# output:  0x1.0000000000000p-52

one = numpy.float64(1.0)

delta = float.fromhex('0x1.fffffffffffffp-53')
print 'delta = %s' % float.hex(delta)

print 'epsilon - delta = %s' % (float.hex(epsilon-delta))
#output: 0x1.0000000000000p-105

print '\n1.0 + epsilon = %s' % (float.hex(one+numpy.float64(epsilon)))
#output: 0x1.0000000000001p+0

print '\n1.0 + delta = %s' % (float.hex(one+numpy.float64(delta)))
#output: 0x1.0000000000001p+0
# since delta is smaller than epsilon, I expected 0x1.0000000000001p+0

delta1 = float.fromhex('0x1.0000000000001p-53')
print '\n1.0 + %s = %s' % (float.hex(delta1), float.hex(one+delta1))
#output: 0x1.0000000000001p+0
# since delta is smaller than epsilon, I expected 0x1.0000000000001p+0

delta2 = float.fromhex('0x1.0000000000000p-53')
# note: delta2 = epsilon / 2.0
print '\n1.0 + %s = %s' % (float.hex(delta2), float.hex(one+delta2))
# 0x1.0000000000000p+0
Run Code Online (Sandbox Code Playgroud)

结果输出是

epsilon=2.22045e-16
epsilon(hex) = 0x1.0000000000000p-52
delta = 0x1.fffffffffffffp-53
epsilon - delta = 0x1.0000000000000p-105

1.0 + epsilon = 0x1.0000000000001p+0

1.0 + delta = 0x1.0000000000001p+0

1.0 + 0x1.0000000000001p-53 = 0x1.0000000000001p+0

1.0 + 0x1.0000000000000p-53 = 0x1.0000000000000p+0
Run Code Online (Sandbox Code Playgroud)

Blc*_*ght 7

我认为您所看到的是 Pythonfloat类型在超出精度时如何处理舍入。您引用的维基百科文本描述epsilon似乎忽略了这一部分。

在您的示例中,1 + delta四舍五入为1 + epsilon。尽管 a可以指定和float之间的差异,但它不能代表和之间的差异。正如您所注意到的(通过您的测试),向下舍入而不是向上舍入的最大数字似乎是。deltaepsilon1 + delta1 + epsilondelta211 + epsilon1 + epsilon/2

因此,Python 中含义的正确定义epsilon可能是:

epsilon(1 + epsilon) - 1是等于 的最小正浮点数epsilon

  • 我不认为这是 Python 的规则,而是 IEEE 的规则。我喜欢你的结论,除了零也满足要求。也许如果您将其重申为“最小的*非零*浮点......” (4认同)