2013-02-22 34 views
0

爲什麼這段代碼打印2.4099999999999997,而不是僅僅2.41的Java模塊操作

public class Main 
{ 
    public static void main(String args[]) 
    { 
     double d = 5.55%3.14; 
     System.out.println(d); 
    } 
} 
+5

[每個計算機科學家應該知道什麼關於浮點運算](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)。 – Pshemo 2013-02-22 18:49:48

+2

爲什麼你們所有人都低估了這一點,你需要深入理解浮點算術才能理解這一點。 – cIph3r 2013-02-22 18:51:38

+3

「浮點數/雙精度表示幾個字節的實數,它們必須做近似才能做到這一點。 」。這是基本的計算機科學。 – 2013-02-22 18:54:35

回答

1

的Java double可以有精度的問題。

你爲什麼不試試BigDecimal

+8

「精度問題」使它聽起來像一個錯誤;這不是問題,它是一個浮點。 – LittleBobbyTables 2013-02-22 18:51:09

+0

而BigDecimal並沒有解決這個問題: 'import java.math.BigDecimal; public class main { \t public static void main(String [] args){ \t \t final BigDecimal d = new BigDecimal(5。55); \t \t final BigDecimal APPROXPI = new BigDecimal(3.14); \t \t System.out.println(d.remainder(APPROXPI)); \t \t //2.409999999999999698019337301957421004772186279296875 \t} }' – cIph3r 2013-02-22 19:12:25

+1

@ cIph3r實際上BigDecimal的解決它,但是我們需要用數字的字符串表示構造函數的參數,比如'的BigDecimal( 「5.55」)'和'的BigDecimal( 「3.14」)'獲得準確的價值。看看[這個解釋](http://www.youtube.com/watch?feature=player_detailpage&v=wbp-3BJWsU8#t=373s)。 – Pshemo 2013-02-22 20:36:20

2
import java.text.DecimalFormat; 

double d = 5.55%3.14;  
DecimalFormat df = new DecimalFormat("#.##"); 
System.out.println(df.format(d)); 

添加的DecimalFormat

編輯:

您還可以

double d = 5.55%3.14; 
    System.out.printf("%1$.2f", d); 
+1

好,其實這並不能真正解決問題, 十進制格式只是舍不準確了...... 'DecimalFormat的DF =新的DecimalFormat (「##。###################」);' 會顯示你.. – cIph3r 2013-02-22 19:03:59

+0

公平地說,在很多情況下,這是一個完全可以接受的解決方案。 – Medo42 2013-02-22 19:08:12

3

的問題不是模運算符,而是浮點數的性質。一個double不能保持5.55,3.14或2.41的精確值,所以你可以得到一個近似的答案。

爲了更好地理解這一點,當您僅在紙張上寫入空間有限時,嘗試寫下1/3值作爲小數。你最終會得到類似於0.33333的東西,這是實際值的近似值。當你用二進制編寫它時,5.55會發生同樣的情況 - 它會變成101.10001100110011001100110011...,它會在某處被切斷以適應雙精度的空間。

1

原因是java不像我們這樣做數學。 java使用二進制數字(從Horstmann的大Java書籍的第4章)到計算機,435 = 4 * 10^2 + 3 * 10^1 + 5 * 10^0

它這樣做是因爲二進制數或0)更容易操作,因爲計算機中的開關處於打開或關閉狀態(1或0)。

這會導致偶然舍入問題。如果你想迫使它變圓,那麼就像使用十進制格式一樣,或者如果你只需要顯示的值四捨五入,你可以使用String.format或printf