2015-05-27 152 views
3

我正在研究一個計算8位小數點的物品價格的項目。 但有時計算結果不同。使用float和double進行計算,給出不同的結果

我嘗試了一些樣品,但得到不同的計算結果:

public static void main(String[] args) { 
     double value1 = 0.999939f * 0.987792f; 
     double value2 = 0.999939 * 0.987792; 
     double value3 = (double)0.999939f * 0.987792f;  
     System.out.println("value 1 : "+ value1); 
     System.out.println("value 2: "+ value2); 
     System.out.println("value 3 : "+ value3); 
    } 

輸出是:

value 1 : 0.9877317547798157 
value 2 : 0.9877317446880001 
value 3 : 0.9877317839126931 

這三者是不同的結果。

我很困惑。任何人都可以請澄清我在這裏發生了什麼?
謝謝。

我經歷了一些已經回答,但我只想要一些方法,我可以用float和double來計算。否則我不得不改變很多地方。這將是痛苦的。

+2

不要對貨幣金額表示使用雙重或浮動型變量。你會得到許多與四捨五入有關的問題,等等。使用'BigDecimal'類。 –

+0

謝謝@RafaelOsipov。我還有一些疑問。我們能否確定小數點位置?它會影響計算和舍入? java提供了哪些可以幫助你的API? –

+0

@RealSkeptic這個鏈接是關於爲什麼我們不應該使用double或float來表示。它非常有用,下次我不會使用浮動和雙打。但現在我的問題是「我可以做一些浮動和雙打,這不會影響結果」 –

回答

3

由於如何表示浮點數和小數,鑄造可能會導致不同的結果。

對於:double value1 = 0.999939f * 0.987792f你正在乘以兩個浮體,然後將它鑄造成雙。由此產生的浮點表示是被轉換爲double的浮點表示。

對於:double value2 = 0.999939 * 0.987792;你倍增兩個雙打,並保存在一個雙。這是沒有鑄造的時候,因此表示從不改變(即不會因數據表示的變化而導致潛在的數據丟失)。

對於:double value3 = (double)0.999939f * 0.987792f;您正在乘以從浮點數轉換的double值,乘以浮點數。由於Java數學運作的原因,第二個浮點數可能也會被轉換爲雙精度浮點數,所以現在您將乘以兩個浮點數的雙精度浮點數,從而產生第三個浮點數。

因爲float和double有不同的精度,每個精度都會得到不同的結果。有關浮點運算的更多信息,請參閱here

+0

爲什麼說當涉及到雙打時,有_no潛在的數據丟失?這根本不是事實。 – Amit

+0

@Amit你是對的,當數字記錄在Double表示中時有可能會丟失數據,並且在乘法和保存時有機會丟失數據,但所有內容都在Double的工作方式的定義範圍內。我的意思是不會因爲表示的改變而丟失數據。我會編輯這樣說。 –

1

當你寫一個帶「f」字符的數字時,它被認爲是float,這意味着它用32位編碼,而沒有它,它是一個double,用64位編碼。

位數越多,就越準確地表示十進制數。這對於小數點後的數字沒有什麼不同,但在你的情況下它是重要的。

總之,在代碼中只能使用double變量。

+0

這並不準確。無論小數點是多少,浮點表示的精度(單倍或雙倍)都是有限的。事實上,自然數也可能不準確。 – Amit

相關問題