根据维基百科

机器epsilon定义为最小的数字,当加到一个数字时,得出的结果不同于一个

在Python中,可以使用sys.float_info.epsilon找到sys.float_info.epsilon并返回等于2 ^ -52的值。 但是,我可以将大于2 ^ -53的任何数字加到1,但仍然得到与1不同的结果。 但是,根据以上对epsilon的定义,将小于epsilon的任何值加到一个值上应该得到一个值。 这是否意味着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

结果输出是

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

===============>>#1 票数:3 已采纳

我认为您所看到的是Python的float类型在精度不够时如何处理舍入。 您引用的描述epsilon的Wikipedia文本似乎忽略了这一部分。

在您的示例中, 1 + delta取整为1 + epsilon 即使float可以指定deltaepsilon之间的差异,也不能表示1 + delta1 + epsilon之间的差异。 您已经注意到(使用delta2测试),四舍五入为1而不是1 + epsilon的最大数字似乎是1 + epsilon/2

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

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

===============>>#2 票数:1

这个定义是错误的: 机器epsilon是数字eps,因此1 + eps是1之后的下一个数字。因此,对于标准舍入,u = eps / 2是最小的数字,当加到1时得出的值大于1。数量u通常称为单位舍入机器单位 (对于IEEE64,eps = 2 ^(-52),u = 2 ^(-53)。)

顺便说一下,对于大多数实际目的,单位四舍五入u比eps更有用:例如,当将值四舍五入为标准机器编号时,u是最大相对误差。

参考: 数值算法的高, 精度和稳定性 ,第37、38页。

  ask by Bull translate from so

未解决问题?本站智能推荐: