2012-05-29 23 views
10

假設tab都是雙(IEEE標準754)變量,並a這兩個值,b沒有NaN(但可能是Inf)。 經過t = a - b,我是否一定有a == b + tIEEE Std 754浮點:讓t:= a - b,標準是否保證a == b + t?

+0

我相信下溢的結果將會是未定義的,第二個表達式中的溢出也是如此,因此不會。如果有人可以證實,那會很好。 – chris

+0

嗯,我想這種證實溢出對於浮點也沒有定義:'作爲 與任何其他算術溢出,如果結果沒有在所提供的空間中填入,行爲是未定義的。' – chris

+3

在C實現符合IEEE 754,任何浮點運算都沒有UB。所有結果都嚴格定義。 –

回答

25

絕對不是。一個明顯的例子是a=DBL_MAX,b=-DBL_MAX。那麼t=INFINITY,所以b+t也是INFINITY

更令人驚訝的是,有些情況下這種情況沒有發生溢出。基本上,它們都是a-b不確切的形式。例如,如果是aDBL_EPSILON/4b-1a-b是1(假設缺省舍入模式),a-b+b然後0

我提到這個第二示例的原因是,這是迫使的規範方式四捨五入到IEEE算術的特定精度。例如,如果您有一個範圍[0,1)的數字,並且想強制將它舍入到4位的精度,則可以添加並減去0x1p49

+1

第二個例子很好,因爲它不會引起Inf和NaN。非常感謝。 – updogliu

+1

您可能想澄清一下'0x1p49'常量,我最後一次查看從0到F的十​​六進制數字; – MSalters

+8

@MSalters:「0x1p49」是C標準中定義的十六進制浮點數。格式爲「0x」「p」,其中是十六進制數字,可選地包括句點,並且是十進制數字,可選地包括符號。指數的基數是2,所以0x1p49是2 ** 49。 0x1p-4將爲1/16,0x1.23p8將爲(1 + 2/16 + 3/256)* 2 ** 8 = 291.十六進制浮點提供了一種便於人類和編譯器轉換的格式進出二進制浮點編碼而沒有舍入問題。 –

1

在執行第一個操作的過程中,位可能已經從結果的低端丟失。所以有一個問題,第二次手術是否會重現這些損失?我沒有完全想到這一點。

但是,當然,第一個操作可能溢出到+/-無窮大,使第二個比較不等。

(而且,當然,在使用==浮點值,一般情況下是幾乎總是一個錯誤。)

+1

僅僅通過計數論證,第二次手術不能帶回丟失的東西。如果可以的話,你會在't'中存儲比t中的位數多的信息.​​..... –

+0

@R - 是的。直覺地說,由於你所說的話,人們知道它不起作用,但找到例子比吸引深奧的規則更好的「證據」,無論它有多麼有效。 –

-3

使用花車當你不能保證任何事情。如果兩個數的指數都不相同,則算術運算的結果可能無法在浮點數中完全表示。

考慮以下代碼:

float a = 0.003f; 
float b = 10000000.0f; 
float t = a - b; 
float x = b + t; 

運行在Visual Studio 2010中,你得到t==-10000000.0f,因此x==0

比較浮點數時絕不應該使用相等性。取而代之的是比較兩個值之間的差異的絕對值和足夠小以滿足您的精度需求的epsilon值。

由於不同的浮點實現可能會爲同一操作返回不同的結果,因此它會變得更加怪異。

+5

我從來不喜歡「比較差異的絕對值」的建議。有可能得到錯誤的界限([每個計算機科學家應該知道的關於浮點運算的知識](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)是一個很好的開始),並且應該考慮一下,在盲目轉換任意界限之前,人們想要通過比較來完成什麼。 –

+8

使用IEEE-754浮點數時有很多東西是有保證的。這恰好不是其中之一。 –

+0

當使用IEEE浮點數時有很多保證,有時比較平等不僅是合理的,而且是必不可少的。浮點數學絕對是棘手的,但它不是隨機的或惡意的。以下是我的博客中關於浮點平等測試的一個示例:https://randomascii.wordpress.com/2014/01/27/theres-only-four-billion-floatsso-test-them-all/ –

相關問題