2012-05-09 40 views
3

我發現了一個有趣的情況,其中相同的C++代碼在不同的系統上產生不同的結果。相同的C++'if'語句,Linux/Windows上的不同結果

#include <cstdio> 
int main() 
{ 
    int a=20, b=14; 
    if(a*1.0/b*(a+1)/(b+1)==2) printf("YES!"); 
    else printf("NO!"); 
} 

編譯在Ubuntu Linux 12.04使用GCC 4.6.3它輸出YES!

編譯在Windows 7上使用GCC 4.6.2它輸出NO!

但是,使用:

double c = a*1.0/b*(a+1)/(b+1); 
if (c==2) printf("YES!"); 
... 

將返回YES!兩臺機器上的

爲什麼這種差異出現的任何想法?這是由編譯器版本不匹配造成的(pathlevel版本號應該不重要)?爲什麼它實際上輸出不!在Windows機器上,而這種情況顯然是正確的?

+8

浮點數! – Skizz

+2

大家應該知道的關於浮點算術的東西:http://docs.sun.com/source/806-3568/ncg_goldberg.html – chris

+0

與floatin點數的精確比較是壞主意 – Tibor

回答

12

這只是一個猜測,您需要查看編譯器的彙編輸出以確認。

有可能一個編譯器留下中間結果在一個浮點寄存器中,而另一個編譯器將結果寫到內存中,將其從80位舍入到64位。也有可能是一個使用SSE,另一個不是。

+1

+1(幾乎)每個人都知道FP問題,但你試圖猜測**原因**的差異! –

+0

是的,確切地說,謝謝你提出這個問題的原因:-) – rafalcieslak

+2

爲了澄清,20/14可以完全使用80位精度表示,但不是32位精度(未嘗試64)。 Windows構建將中間值存儲在RAM中或使用SSE,而Ubuntu構建將FPU中的中間值保留。 – Skizz

14

因爲你正在做的浮點類型,其通常不應當在特定比特精確行爲依賴從機器到機器的相等比較(或因編譯器,等等)。

可能的原因包括編譯器選擇何時將浮點結果從寬(80位)浮點寄存器中移出(語言標準和IEEE-754浮點標準都沒有提出任何特定要求,AFAIK )。

+6

我認爲知道什麼屬性會很有趣的編譯器或處理器負責區別。如果不確切,IEEE浮點應該是一致的。 –

+0

@MarkRansom:由於數字不準確,所以不能保證一致性。僅僅因爲所涉及的值的準確性,重新排列操作順序(在數學上應該一致)可以產生不同的結果。編譯器只保證數學一致性,而不是精度一致性 –

+0

@LokiAstari,當結果無法保證匹配時,gcc有一個編譯器開關,用於重新排列數學運算。 –

2

這是因爲浮點運算的,請嘗試使用小量comparisions代替:

#define EPSILON_EQUAL(a,b) (fabs((a)-(b)) < (0.0001f)) 

float f = a*1.0/b*(a+1)/(b+1); 
if(EPSILON_EQUAL(f,2.0f)) printf("YES!"); 
+0

感謝您提供epsilon比較,即使您的答案不能解釋爲什麼會發生此問題 – rafalcieslak

+0

我想這與第一個示例中使用float(在if語句中)的事實有關,在第二個示例中使用雙。這裏是看起來類似於你的問題:http://stackoverflow.com/questions/7702177/error-due-to-limited-precision-of-float-and-double – marcinj

1

,因爲它是不正確的一樣,浮點數由於精度問題比較。

在數學三分之二=(0.6666666 .....到無窮大)//小學數學:)不問任何問題。

在計算該計算是浮點單元(類似於CPU,但專用於浮點計算)上進行的。現在這個浮點單元(FPU)可能會給你一個非常接近你的實際答案的數字,但它們並不完全相同。因爲它會截斷結果。有一個專門用於浮點運算的整個領域。總之,從不在比較中使用浮點數,因爲您可能會得到相互衝突的結果。

+0

這是真的,但不能解釋爲什麼它不同於平臺。 –

0

測試浮點數之間的平等是有問題的。這是因爲四捨五入的錯誤,並且在互聯網上有很多這樣的文字。

您可以在谷歌搜索floating point equality看到這個hereherehereherehere,基本上任何結果。

+0

這是事實,但並不能解釋爲什麼它從平臺到平臺各不相同。 –

+0

@OliCharlesworth,就像我說的那樣,這裏有很多文字。在我看來,再次解釋它毫無意義。 – Shahbaz

相關問題