2017-07-16 57 views
-2

10年後,我重新學習Java,並且編寫簡單的代碼來檢查語法並驗證簡單的行爲。 我在玩數字類型,我不明白爲什麼浮動在Java(以及我後來驗證的C#)中表現的行爲與Python(或其他腳本語言,如JavaScript或PHP)不同。 的一點是,從我的知識,花車是不可靠的精度問題時,我腦子裏想的最簡單的例子之一是總和:爲什麼float在Python/PHP/Javascript和Java/C之間的行爲不同#

float(0.1) + float(0.2) 

不同於人們可以想到的是不是float(0.3),但float(0.30000000000000004)由於「背後的問題四捨五入」。 所以,在我的虛擬Java代碼中我寫道:

float wrongResult = 0.1f + 0.2f; 
if (wrongResult != 0.3f) { 
    System.out.println("float sucks"); 
} 
else { 
    System.out.println("float works"); 
} 

double rightResult = 0.1 + 0.2; 
if (rightResult != 0.3) { 
    System.out.println("double sucks"); 
} 
else { 
    System.out.println("double works"); 
} 

但產量是驚人的:

float works 
double sucks 

驅動我瘋了,因爲雙是一個64位的類型和float只有32位類型,所以我期望得到相反的結果,因爲double應該更加精確。 因此,我的巨大困境是:爲什麼像Python,PHP和Javascript這樣的腳本語言會以某種方式運行,並且像Java和C#這樣的編譯語言的行爲有所不同?

+0

可能重複[爲什麼不使用Double或Float來表示貨幣?](https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency) –

+0

不!我的問題完全不同! – daveoncode

+1

爲什麼讓你驚訝的是,一個不太精確的'0.1f + 0.2f'可能完全等於一個不太精確的'0.3f'?這將表明它們都被四捨五入,以致產生相同的數字。 – khelwood

回答

9

腳本語言和Java/C#沒有區別。但是,floatdouble之間存在差異。一個小混亂來自這樣一個事實,即在腳本語言中(至少在Python中)float的基本類型通常具有64位的精度(即Java中的double)。其原因那麼,對於不同的行爲是舍入後的最接近的值將不相同,這可以從以下可以看出:

fl64(.1) == 0.10000000000000001 
fl64(.2) == 0.20000000000000001 
fl64(.3) == 0.29999999999999999 
fl64(.1) + fl64(.2) == 0.30000000000000004 

fl32(.1) == 0.1 
fl32(.2) == 0.2 
fl32(.3) == 0.30000001 
fl32(.1) + fl32(.2) == 0.30000001 

因此,與較低精度(32位),它只是恰好是那個0.1 + 0.2 == 0.3。然而,這不是一個普遍的結果,對於許多其他的數字來說,這不會成立。因此漂浮物對於精確的精度仍然不可靠。

相關問題