对于IEEE-754算术,倒数的最后位置精度是否保证0或1个单位?从那开始,是否有一个保证的误差限制在倒数的倒数上?
答案 0 :(得分:9)
[以下所有内容均采用固定的IEEE 754二进制格式,并采用某种形式的舍入模式作为舍入模式。]
由于倒数(计算为1/x
)是一个基本的算术运算,1
是完全可表示的,并且算术运算保证由标准正确舍入,相互结果保证在{ {1}}单位在真值的最后一个位置。 (这适用于标准中指定的基本算术运算的任何。)
一般来说,值0.5
的倒数的倒数不能保证等于x
。 IEEE 754 binary64格式的快速示例:
x
但是,假设避免溢出和下溢,并且>>> x = 1.8
>>> 1.0 / (1.0 / x)
1.7999999999999998
>>> x == 1.0 / (1.0 / x)
False
是有限的,非零的,并且可以精确表示,则以下结果是正确的:
x
的值与1.0 / (1.0 / x)
的值相差不超过最后一个单位。
如果x
的有效位数(通常标准化为x
范围内)小于[1.0, 2.0)
,那么倒数 往返:sqrt(2)
。
证明草图:在不失一般性的情况下,我们可以假设1.0 / (1.0 / x) == x
为正,并将x
缩放为2的幂,使其位于x
范围内。在[1.0, 2.0)
是2的精确幂的情况下,上述结果显然是正确的,所以我们假设它不是(这将在下面的第二步中有用)。下面的证明是针对IEEE 754 binary64格式的特定精度给出的,但它直接适应任何IEEE 754二进制格式。
在舍入之前,将x
写为倒数的 true 值,并让1 / x
成为(唯一的,事实证明)最接近的可表示的binary64 float to { {1}}。然后:
因为y
是距离1 / x
最近的浮点数,y
和1 / x
都位于binade y
中,其间的间距为1/x
连续的浮点数恰好是[0.5, 1.0]
,我们有2^-53
。事实上,我们可以做得更好:
我们实际上有一个严格的不平等:|y - 1/x| <= 2^-54
。如果|y - 1/x| < 2^-54
完全等于|y - 1/x|
,则2^-54
将在任意精度二进制浮点中完全表示(因为1/x
和y
是)。但是唯一的2^-54
二进制浮点x
在某种程度上可以精确表示,是2的幂,我们已经排除了这种情况。
如果1/x
然后x < sqrt(2)
,因此(将两者四舍五入到最近的可表示的浮点数),我们有1 / x > x / 2
,所以y >= x / 2
。
现在x / y <= 2
,以及x - 1/y = (y - 1/x) x/y
和|y - 1/x|
上的界限(仍然假设x/y
)我们得到x < sqrt(2)
。因此,|x - 1/y| < 2^-53
是距离x
最近的可表示浮点数,1/y
向1/y
舍入并且往返成功。这样就完成了第2部分的证明。
在一般情况x
中,我们有x < 2
,因此x / y < 4
。这使得|x - 1/y| < 2^-52
距离1/y
最多1 ulp,这样就完成了第1部分的证明。
这里是x
阈值的演示:使用Python,我们在sqrt(2)
范围内采用了一百万个随机浮点数,并识别那些不通过倒数往返的浮点数。所有小于[1.0, 2.0)
的样本都会通过往返。
sqrt(2)
并且证明最大误差不超过1 ulp,一般来说(对于binary64格式,在binade [1.0,2.0中],最后一个位置的1个单位是2 ^ -52):
>>> import random
>>> samples = [random.uniform(1.0, 2.0) for _ in range(10**6)]
>>> bad = [x for x in samples if 1.0 / (1.0 / x) != x]
>>> len(bad)
171279
>>> min(bad)
1.4150519879892107
>>> import math
>>> math.sqrt(2)
1.4142135623730951
以下是IEEE 754二进制64格式的示例,表明有必要限制避免下溢:
>>> samples = [random.uniform(1.0, 2.0) for _ in range(10**6)]
>>> max(abs(x - 1.0 / (1.0 / x)) for x in samples)
2.220446049250313e-16
>>> 2**-52
2.220446049250313e-16
此处>>> x = 1.3e308
>>> x_roundtrip = 1.0 / (1.0 / x)
>>> x.hex()
'0x1.72409614c1e6ap+1023'
>>> x_roundtrip.hex()
'0x1.72409614c1e6cp+1023'
结果与原始结果的不同之处在于最后一个位置的两个单位,因为x_roundtrip
小于最小的正常可表示浮点数,因此未表示为与{{{{1}相同的精度1}}。
最后注意事项:由于IEEE 754-2008也涵盖了十进制浮点类型,我应该提到上述证明几乎逐字逐句地表示十进制情况,确定对于有效数小于1 / x
的浮点数,发生往返,而对于一般的十进制浮点数(再次避免溢出和下溢),我们在最后一个地方永远不会被多个单位关闭。然而,需要一些数论理论才能证明关键不等式x
总是严格的:最终必须证明数量sqrt(10)
永远不是一个平方数(这是是的,但它可能超出了本网站的范围,在此处包含证明。)
|x - 1/y| < 1/2 10^(1-p)