2017-06-19 29 views
4

對於IEEE-754算術,在倒數的最後一位準確度中是否有0或1個單位的保證?那麼,對於互惠的倒數是否有保證的誤差?浮點相互總是往返嗎?

+0

這個問題是隱隱恆定的倒數,然後取整到單精度,也由馬克回答了有關實施單精度乘法的問題由雙精度乘法:https://開頭計算器.com/questions/19589973 /實現單精度分割爲雙精度乘法 –

回答

9

[下面一切假定固定的IEEE 754的二進制格式,以某種形式的舍入到最近的作爲舍入模式。]

由於倒數(計算爲1/x)是一種基本的算術運算,1是完全可表示,並且算術運算保證按標準正確舍入,倒數結果保證在真值的最後位置處於0.5單位內。 (這適用於在標準中規定的基本的算術運算的任何。)

x不保證等於x,在一般的倒數的倒數。一個簡單的例子與IEEE 754 binary64格式:避免

>>> x = 1.8 
>>> 1.0/(1.0/x) 
1.7999999999999998 
>>> x == 1.0/(1.0/x) 
False 

然而,假定溢和下溢,並且x是有限的,非零值,和精確表示,下面的結果都爲真:

  1. 1.0/(1.0/x)的值與x的差異不會超過1個單位。

  2. 如果x尾數(歸一化至處在範圍[1.0, 2.0)照例)比sqrt(2)小,則倒數確實往返:1.0/(1.0/x) == x

證明素描:不失一般性,我們可以假設x爲正,並且通過兩個功率尺度x,使其處於範圍[1.0, 2.0)。上述結果在x是2的精確冪的情況下顯然是正確的,所以我們假設它不是(這將在下面的第二步中有用)。以下證明是針對IEEE 754二進制64格式的特定精度給出的,但它直接適用於任何IEEE 754二進制格式。

真正值倒數的舍入之前,寫1/x,讓y是(獨一無二的,因爲它原來)最接近的可表示binary64浮到1/x。然後:

  • 因爲y是最接近浮子1/x,都y1/x都在binade [0.5, 1.0],其中連續彩車之間的間距正好是2^-53,我們有|y - 1/x| <= 2^-54。事實上,我們可以做得更好一些:

  • 我們實際上有一個嚴格的不平等以上:|y - 1/x| < 2^-54。如果|y - 1/x|剛好等於2^-54,那麼1/x將精確地表示爲任意精度二進制浮點數(因爲y2^-54都是)。但唯一的二進制浮點數x其中1/x可以精確地表示一個精度是2的冪,我們已經排除了這種情況。

  • 如果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。因此,x1/y,1/y輪到x最接近的浮點數,並且往返成功。這完成了第2部分的證明。

  • 在一般情況下,我們有x/y < 4,所以|x - 1/y| < 2^-52。這使得1/y至多1 ULP從x遠,完成的部分證明1.

這裏的sqrt(2)門檻的演示:使用Python,我們就範圍[1.0, 2.0)百萬隨機花車,並確定那些不能通過互惠的。所有小於sqrt(2)的樣本均通過往返。

>>> 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 

而一個示範的最大誤差不超過1 ULP,一般來說(對於binary64格式,在binade [1.0,2.0),在最後一個地方1個單元是2^-52) :

>>> 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 

下面是與IEEE 754 binary64格式示出了如何避免下溢的限制是必要的一個例子:

>>> x = 1.3e308 
>>> x_roundtrip = 1.0/(1.0/x) 
>>> x.hex() 
'0x1.72409614c1e6ap+1023' 
>>> x_roundtrip.hex() 
'0x1.72409614c1e6cp+1023' 

這裏x_roundtrip結果從與原來的b的不同之y兩個單位,因爲1/x小於最小的正常可表示的浮點數,因此與x的表示精度相同。最後說明:由於IEEE 754-2008也涵蓋了十進制浮點類型,所以我應該提到,上述證明幾乎是逐字進行到十進制的情況下,確定對於有效數小於sqrt(10)的浮點數,會發生往返,而對於一般的十進制浮點數(再次避免溢出和下溢),我們永遠不會超過一個單位在最後的地方。然而,需要一些數論理論來證明關鍵不等式|x - 1/y| < 1/2 10^(1-p)始終是嚴格的:最終必須證明數量1 + 16 10^(2p-1)永遠不是平方數(這是真的,但它可能超出了本網站的範圍在這裏包括證明)。

>>> from decimal import Decimal, getcontext 
>>> import random 
>>> getcontext().prec = 6 
>>> samples = [+Decimal(random.uniform(1.0, 10.0)) for _ in range(10**6)] 
>>> bad = [x for x in samples if 1/(1/x) != x] 
>>> min(bad) 
Decimal('3.16782') 
+1

嗯......我不得不查找「ambit」。 –