2017-02-23 29 views
3

考慮準確創建在範圍[浮點值A,B)

auto x = a + (b-a)*v; 

其是指由以下因素v[0,1.0)以在範圍[a,b)的值。從純粹的數學角度來看,x>=ax<b。但是,我們如何證明或確保這適用於浮點? abv是(doublefloat)相同類型的非負的有限浮點值和b>a(原稱b>=a這與我對x要求明顯不符),以及v<=netxtafter(1.0,0)(即,它的正下方1.0)。

它似乎很明顯,那b-a >0,因此(b-a)*v >=0,所以我們並不需要檢查:

if (x<a) return a; 

但是,這也是多餘的?

if (x>=b) return std::nextafter(b,a); 

編譯器(優化)是否可以重寫表達式來影響這些問題? 浮點表示的類型是否進入? (我在最常見的(iec559/IEEE 754)最感興趣。

+1

我不明白這個問題。如果你的等式適用於任何(正)實數,它也適用於任何浮點數,因爲Q(有理數)是R(實數)的一個子集,浮點數是Q的子集... –

+0

我猜可能發生的最糟糕的是當你的數字例如無論是v,b還是a(或全部)都非常小或接近邊界,在這種情況下,截斷可能是一個問題..但截斷總是朝向較低的值,並且所有數字都是正數... –

+0

@CedricDruck ,這樣說:如果沒有問題,應該很容易證明。謹慎寫一個答案? –

回答

5

它似乎很明顯,即BA> 0,因此(BA)* V> = 0,這樣我們就不需要檢查:if (x<a) return a;

酒店b - a > 0是IEEE 754正確的,但我不會說這是明顯的在浮點標準化,Kahan的fought for this property resulting from 「gradual underflow」 to be true時其他提議沒有低於正常數量和做。不是這樣,你可以在這些其他建議中有b > ab - a == 0,例如通過a這個最小的正數和b其繼任者。

即使沒有漸進下溢,通過沖洗次歸爲零是錯誤實現IEEE 754的系統上,b > a意味着b - a >= 0,所以沒有必要擔心x低於a

但這是否也是多餘的? if (x>=b) return std::nextafter(b,a);

該試驗不是冗餘的,即使在IEEE 754有關示例採取b是的a繼任者。對於v以上的所有值0.5,在默認的舍入到最近模式下,a + (b-a)*v的結果爲b,您試圖避免這一結果。


我的例子是在不尋常的值專爲ab,因爲從編寫一個程序來找到通過蠻力反例節省了我,但不要以爲其他的可能性較大,對值的ab不會出現問題。如果我正在尋找其他反例,我會特別尋找浮點減法b - a舍入的值對。


編輯:哦,好吧這裏是另一個反例:

採取a是的-1.0的繼任者(即,在雙精度,採用C99的十六進制表示,-0x1.ffffffffffffep-1)的繼任者b3.0。然後b - a四捨五入至4.0,並以v爲前身1.0,a + (b - a) * vrounds up3.0

浮點減法b - a四捨五入不需要的ab製備反例的一些值,如圖here:以a作爲1.0後繼和b作爲2.0也有效。

相關問題