2011-11-14 74 views
5

在C:相同的條件下在C和Java中,不同的結果

float a = 1.3; 
if (a == 1.3) 
    printf("Hello c"); 
else 
    printf("Bye c"); 

//output: Bye c 

在Java:

float a = 1.3; 
if (a == 1.3) 
    System.out.println("Hello java"); 
else 
    System.out.println("Bye java"); 

//output: Hello java 

爲什麼會這樣呢?

+2

I'我已經在代碼中完成了幾個[小的更正](http://programmers.stackexchange.com/posts/119596/revisions),您的原始代碼無法工作。你看過你的代碼產生輸出還是你從某處複製了它? – yannis

回答

21

您不能準確地將「1.3」表示爲二進制浮點數。

將文字1.3轉換爲浮點數將導致浮點數接近但不完全等於1.3。

在Java的情況下,你很幸運,因爲JVM將「1.3」解釋爲一個標準的Java浮點數並轉換爲幾乎1.3。二進制數。在C的情況下,標準說1.3應該被解釋爲一個「double」並將其轉換爲一個二進制浮點,它比普通浮點更接近十進制值1.3。

底線是,你永遠不應該比較浮動平等作爲存儲的小變化,計算順序等將產生稍有不同的結果。你應該總是「支架」任何浮動比較像這樣:

if (a > 1.299 && a < 1.301) // something close to 1.3 
+7

只是一個完美的挑剔:在C中,'1.3'總是雙倍的。 (單精度)float文字的語法是'1.3f'。 – tdammers

+0

@tdammmers - 謝謝。我不確定這是編譯器特定的還是由標準強制的。 –

1

只是爲了幫助你環繞回答你的大腦,讓我給你一個簡單的比喻。請記住,浮點數是近似值。許多數字不能準確表示。現在,想象我們用小數點做同樣的事情,比如說我們在小數點後面用了六位數字。

我們如何表示1/3? .333333是我們能做的最好的。但現在3 * 1/3將不等於1.

我們如何表示2/3? .666666將至少確保2 * 1/3 = 2/3。但是2/3 + 1/3不等於1.

我們可以把2/3代表爲.666667。但2 * 1/3將不等於2/3。但至少1/3 + 2/3將等於1。

所以重點是,用近似表示,你不能確保完全正確的答案,只有足夠接近的答案。一般來說,除非你100%肯定地理解你在做什麼以及爲什麼,否則你不應該爲浮點數進行比較。

0

關於C必須知道的第一件事是,由於編譯器實現了浮點數,所以測試2個浮點數是否相等是非常錯誤的。 '1.3'當存儲在浮點變量中時,您尚未填滿編譯器存儲的所有小數位,並且可能會填充一些數字,從而導致相等性測試失敗

相關問題