2014-01-25 104 views
4

我搞砸了代碼執行結果。令人驚訝的雙重比較

代碼:

System.out.println(0.2==0.1+0.1); 
System.out.println(0.3==0.1+0.1+0.1); 

輸出:

true 
false 

我知道,0.2和0.3不能轉化爲二進制正確。

爲什麼我看到不同的結果?

UPDATE:

我可以預言導致沒有編譯器類似的問題?

+0

也保持'C++'。 – herohuyongtao

+1

php同樣的結果! –

+0

我不知道javascript – gstackoverflow

回答

0

PHP的鏈接給了這一點:

<?php 

printf("%0.20f\n", 0.1+0.1); 
printf("%0.20f\n", 0.1+0.1+0.1); 

?> 
0.20000000000000001110 
0.30000000000000004441 

<?php 
    echo 0.2==0.1+0.1?"true\n":"false\n"; 
    echo 0.3==0.1+0.1+0.1?"true\n":"false\n"; 
?> 
true 
false 

第一個是 「真」 的reaseon:

<?php 
    printf("%0.20f\n", 0.1+0.1); 
    printf("%0.20f\n", 0.1+0.1+0.1); 
    echo "\n"; 
    printf("%0.20f\n", 0.2); 
    printf("%0.20f\n", 0.3); 
?> 

輸出

0.20000000000000001110 
0.30000000000000004441 

0.20000000000000001110 
0.29999999999999998890 
+0

nr4bt解釋了爲什麼* System.out.println(0.3 == 0.1 + 0.1 + 0.1)*返回false。但我沒有回答爲什麼* System.out.println(0.2 == 0.1 + 0.1)*返回true – gstackoverflow

+0

根據你的結果 - 這是非常奇怪的 – gstackoverflow

+0

關於你的更新:我可以預測沒有編譯器的結果嗎? – gstackoverflow

9
System.out.println(0.1+0.1+0.1); 

輸出

0.30000000000000004 

上有浮點算術舍入誤差。有些值不能用基數2表示,你不能依靠比較浮點數。基數爲2的0.1與基數爲10的1/3相似。

你可以看到下面

What Every Computer Scientist Should Know About Floating-Point Arithmetic

+0

我正要添加評論,這可能是。 – Hosch250

+2

爲什麼確定'0.1 + 0.1'? – herohuyongtao

+0

每次使用浮動執行附加計算時,答案中會出現越來越多的錯誤。當你只添加2個浮點數時,錯誤不夠大,不能被考慮!=。 – csmckelvey

2

你看到的是一個事實,即浮點值都不太準確,並使用==運營商不應該例如對它們進行比較。爲了比較你應該使用epsilon比較,即。兩個浮點值f1和f2

if (Math.abs(f1 - f2) < EPSILON) { 
    // they are equal 
} 

哪裏EPSILON是一些非常小的浮點值

+0

...其中EPSILON是一些非常小的浮點值_reflecting必要的比較精度但不低於this_ –

0

你不能依靠==帶來良好float數字,其結果是不可靠的,因爲他們不能準確地代表工作在電腦上。當您想要檢查兩個float數字是否相等時,請改爲使用fabs(a-b) < epsilon

P.S.下面的測試是C++下,這給了驚人的結果(只是爲了好玩,顯示它是多麼未可靠):

cout << (0.1==0.1) << endl;        // true 
cout << (0.2==0.1+0.1) << endl;       // true 
cout << (0.3==0.1+0.1+0.1) << endl;      // false 
cout << (0.4==0.1+0.1+0.1+0.1) << endl;     // true 
cout << (0.5==0.1+0.1+0.1+0.1+0.1) << endl;    // true 
cout << (0.6==0.1+0.1+0.1+0.1+0.1+0.1) << endl;   // true 
cout << (0.7==0.1+0.1+0.1+0.1+0.1+0.1+0.1) << endl;  // true   
cout << (0.8==0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1) << endl; // false 
相關問題