2012-07-06 87 views
4

我想實現一個新的四捨五入BigDecimal類,並且我得到一個可能的錯誤,可能我做錯了什麼。下面的代碼暴露了我的問題:Java BigDecimal錯誤與字符串構造函數四捨五入ROUND_HALF_UP

public static void main(String[] args) throws IOException { 
    BigDecimal valDouble = new BigDecimal(0.35); 
    valDouble = valDouble.setScale(1, BigDecimal.ROUND_HALF_UP); 
    System.out.println(valDouble.doubleValue()); // prints 0.3 

    BigDecimal valString = new BigDecimal(new String("0.35")); 
    valString = valString.setScale(1, BigDecimal.ROUND_HALF_UP); 
    System.out.println(valString.doubleValue()); // prints 0.4 
} 

我的疑問是,BigDecimal對於double和String構造函數是不同的嗎?

我無法理解這樣的「錯誤」,至少,我只是用一個簡單的字符串連接到「解決」了,如下圖所示:

BigDecimal valDouble = new BigDecimal("" + 0.35); 

任何想法,這可能是造成這種奇怪的行爲?

+0

不知道你在這裏問什麼。請澄清問題所在。 – 2012-07-06 19:27:47

+0

[This](http://www.youtube.com/watch?v=wbp-3BJWsU8&feature=player_detailpage#t=243s)可能會讓你感興趣。 – Pshemo 2012-07-06 19:32:44

回答

7

這不是一個錯誤。作爲雙字面量的0.35表示一個不完全等於0.35的值;它可能是0.349999995之類的東西。所以它下降。

該字符串構造函數允許您使用「0.35」精確指定0.35,然後向上舍入。

不要在這裏使用double構造函數;當它足夠重要使用BigDecimal時,您需要保持浮點狀態。

+1

我在Google I/O上看到了這個Java puzzlers 。 – nullpotent 2012-07-06 19:29:02

+0

我這是[this](http://www.youtube.com/watch?v=wbp-3BJWsU8&feature=player_detailpage#t=243s)益智遊戲:) – Pshemo 2012-07-06 19:32:04

+0

是的。值得關注,每個人。 – nullpotent 2012-07-06 19:34:16

3

你不需要猜測是0.35代表作爲

BigDecimal valDouble = new BigDecimal(0.35); 
System.out.println(valDouble); 

打印

0.34999999999999997779553950749686919152736663818359375 

這將向下舍入到1位小數爲0.3

你不需要要轉換爲字符串,可以使用valueOf

BigDecimal valDouble = BigDecimal.valueOf(0.35); 
System.out.println(valDouble); 

打印

0.35 

爲了圓半升到小數點後一位,你可以使用

double d = 0.35; 
double d1 = Math.round(d * 10)/10.0; 
System.out.println(d1); 

打印

0.4 
0

0.35已經是不準確的,成爲FP的二進制基數的。使用新的BigDecimal(「0.35」),這正是由於小數基數。