我搞砸了代碼執行結果。令人驚訝的雙重比較
代碼:
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:
我可以預言導致沒有編譯器類似的問題?
我搞砸了代碼執行結果。令人驚訝的雙重比較
代碼:
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:
我可以預言導致沒有編譯器類似的問題?
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
nr4bt解釋了爲什麼* System.out.println(0.3 == 0.1 + 0.1 + 0.1)*返回false。但我沒有回答爲什麼* System.out.println(0.2 == 0.1 + 0.1)*返回true – gstackoverflow
根據你的結果 - 這是非常奇怪的 – gstackoverflow
關於你的更新:我可以預測沒有編譯器的結果嗎? – gstackoverflow
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
我正要添加評論,這可能是。 – Hosch250
爲什麼確定'0.1 + 0.1'? – herohuyongtao
每次使用浮動執行附加計算時,答案中會出現越來越多的錯誤。當你只添加2個浮點數時,錯誤不夠大,不能被考慮!=。 – csmckelvey
你看到的是一個事實,即浮點值都不太準確,並使用==
運營商不應該例如對它們進行比較。爲了比較你應該使用epsilon比較,即。兩個浮點值f1和f2
if (Math.abs(f1 - f2) < EPSILON) {
// they are equal
}
哪裏EPSILON是一些非常小的浮點值
...其中EPSILON是一些非常小的浮點值_reflecting必要的比較精度但不低於this_ –
你不能依靠==
帶來良好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
也保持'C++'。 – herohuyongtao
php同樣的結果! –
我不知道javascript – gstackoverflow