2012-05-16 56 views
-1

可能重複時:
Retain precision with Doubles in java
Moving decimal places over in a double表觀不精確遞增和顯示雙重價值

類是不言而喻的。如果你執行這個代碼,double值看起來有些溢出,但是對於所有值都不會發生,而且,如果直接輸出數字,那麼輸出是OK。

public class test { 
    public static void main(String[] args){ 

     for (double f=1.36; f<1.40; f+=0.01) System.out.println(f); 
      //Prints 1.36 
      //  1.37 
      //  1.3800000000000001 ??????? 
      //  1.3900000000000001 ??????? 

      System.out.println(1.36); //Prints 1.36 
      System.out.println(1.37); //Prints 1.37 
      System.out.println(1.38); //Prints 1.38 
      System.out.println(1.39); //Prints 1.39 
    } 
} 

有人可以點亮嗎?如果這是一個bug,那麼在代碼中修復它的最好方法是什麼?任何魔術解決方法?

+6

http://docs.oracle.com/cd/E19957-01/806-3568 /ncg_goldberg.html – NPE

+0

即使JEval沒有正確處理像「1400 * 0.001」這樣的操作(這就是我追蹤錯誤的原因),因此我不認爲是如此愚蠢的問題,因爲它是投票否定 – Whimusical

+1

@ user1352530它是妥善處理的意義上,輸出是完全符合規定的(就downvotes而言,這可能是因爲這個問題可能每天問一次,所以通過一些搜索,你可能會發現一些東西,比如我上面發佈的鏈接[Java常見問題](http://stackoverflow.com/tags/java/info))。 – assylias

回答

2

如果格式化這樣的打印輸出,你不會看到所有的小數位:

System.out.printf("%.2f",yourVariable); 
+0

謝謝,但我的變種來自一個字符串像2.333333333333,我不知道maxDecimals,所以我不能限制/四捨五入和格式化 – Whimusical

+0

不用擔心這將適用於所有的小數點。 –

+0

我的意思是,如果我沒有錯,你的解決方案舍入到2位小數,這是完美的,如果我的值在var是1.300000000001 = 1.30,但不是如果var保留1.34565667777,因爲那麼我鬆散所有precission – Whimusical

1

嘗試

for (int i= 136; i <= 140; i++) 
    System.out.println(i/100.0); 

打印

1.36 
1.37 
1.38 
1.39 
1.4 

當你打印出來一個雙重的,它彌補了表示錯誤,所以你沒有看到它。當您對浮點值執行多個算術運算時,您可能會添加舍入誤差以及變得明顯(要對其進行很多糾正)

+0

我要去通過aix(answerer)鏈接來研究基礎,但我真的無法理解最流行的編程語言如何處理安全和透明的任何計算器都可以執行的基本操作......甚至不像JEval那樣起作用。謝謝你! – Whimusical

+0

它使用http://en.wikipedia。org/wiki/IEEE_754-2008各種主流編程語言和CPU支持的浮點運算。計算器通常會隱藏更多數字並執行其他操作來減少明顯的舍入誤差。 Java只使用你的CPU支持的float和double類型。顯着改變功能會增加開銷並使其與其他語言不一致。 –

+0

哇,我簡直不敢相信。今天我瞭解到,2012年計算機沒有最佳方法來解決基本的14 * 0.1(1.4000000000000001)並將其存儲在一個變種:) – Whimusical