2015-05-06 45 views
3

我知道,我可以使用BigDecimal.divide()方法來設置固定精度:集BigDecimal的精度,如果小數重複

BigDecimal a1 = new BigDecimal(1); 
BigDecimal a2 = new BigDecimal(3); 
BigDecimal division = a1.divide(a2,5,1); //equals 0.33333 

但是,如果劃分結果是準確的:

BigDecimal a1 = new BigDecimal(1); 
BigDecimal a2 = new BigDecimal(4); 
BigDecimal division = a1.divide(a2,5,1); //equals 0.25000 

如何設置除法結果如果分部以一個確切的結果結束,它只會給出0.25而不是0.25000的輸出?

我也試着不這樣做指定精度:

BigDecimal division = a1.divide(a2); 

它成功地做1/4時給出結果0.25,但是當它象師或1/32/3導致運行時ArithmeticException

a1a2從用戶輸入實例化。

有什麼辦法解決這個問題嗎?

+0

您應該更喜歡['RoundingMode'](https://docs.oracle.com/javase/8/docs/api/java/math/RoundingMode.html)類傳遞整數舍入模式值。即使無論出​​於何種原因必須使用整數方法,也可以使用「BigDecimal」中的常量,例如['BigDecimal.ROUND_DOWN'](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#ROUND_DOWN)。 – dimo414

+0

哦,我明白了,我不確定選擇哪一個,所以我只是用int來代替。但是,現在我明白了。 – user3411184

回答

6

你得到一個ArithmeticException作爲BigDecimal.divide(BigDecimal)描述 - 「如果準確的商值沒有十進制擴展」,因爲正確代表1/3結果將採取無限懷念。通過使用BigDecimal.divide(BigDecimal,int,RoundingMode),您明確設置了您可以容忍的精度,這意味着任何分區都可以在內存中近似。

爲保持一致性,此版本的除法總是將比例尺設置爲您指定的比例,即使該值可以用較低的精度準確表示。如果沒有,那麼你很難推斷使用該結果進行未來計算的精確程度。

爲了減少您的精度,使用.stripTrailingZeros();這有效地將規模降至最低。儘可能在過程中儘可能地做到這一點(即在打印之前),以保持上面提到的一致性。

如果您試圖很好地顯示這些值,您可能還需要.toPlainString(),因爲.stripTrailingZeros()本身會顯示1001E+2

+0

類似:http://stackoverflow.com/questions/25541684/how-to-remove-trailing-zero-in-a-string-value-and-remove-decimal-point/25542023#25542023(是的,這是無恥的自我推銷) – jdphenix

+0

可能值得一提的是BigDecimal(string)與BigDecimal(double)的比較,以及後者如何對格式輸出產生負面影響 – jdphenix

+0

@jdphenix OP使用['BigDecimal(int)'](https: //docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#BigDecimal-int-)這是無損的 - 我不明白['BigDecimal(double)'' ](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#BigDecimal-double-)構造函數與此問題相關,但如果它存在與構造函數文檔的鏈接幫助任何人。 – dimo414