我之前使用过BigDecimals但不经常使用BigDecimals,今天早上我正在处理某些事情并且我一直遇到以下异常:
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion;
no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1594)
我试图设置比例并使用舍入来消除这样的问题:
BigDecimal bd1 = new BigDecimal(1131).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd2 = new BigDecimal(365).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd3 = bd1.divide(bd2).setScale(2,BigDecimal.ROUND_HALF_UP);
System.out.println("result: " + bd3);
但是,我一直得到同样的例外。有谁能告诉我我犯了哪个错误?
答案 0 :(得分:51)
使用divide
时,如果确切结果具有无限小数(您的情况),则应使用MathContext
:
MathContext mc = new MathContext(2, RoundingMode.HALF_UP);
BigDecimal bd3 = bd1.divide(bd2, mc);
或者:
BigDecimal bd3 = bd1.divide(bd2, RoundingMode.HALF_UP);
答案 1 :(得分:4)
这是问题
bd1.divide(bd2)
你需要使用一个采用舍入模式的重载divide()
方法(以各种形式) - 你不能在除法后进行舍入,因为对于非终止分数,中间结果要么已经需要圆形,或需要无限的存储空间。
答案 2 :(得分:2)
默认情况下,BigDecimal会尝试返回给定除法表达式的确切值。因此,如果由于无限的十进制扩展而无法确定确切的值,则抛出ArithmeticException。一个基本的例子是将1除以3,得到三分之一,这个值不能用十进制表示法精确表示。
答案 3 :(得分:1)
由于分割,您收到此错误:
在分割方法中提供缩放和舍入模式(就像你在创建BigDecimals时所做的那样)以防止这种情况。
取自here。还提供了工作部门的示例代码。
另请参阅:Java docs on BigDecimal。
答案 4 :(得分:1)
问题是由导致重复小数的操作(除法)引起的。
解决方案是在执行除法时指定比例,例如:
BigDecimal one = new BigDecimal("1");
BigDecimal three = new BigDecimal("3");
BigDecimal oneDivThree = one.divide(three, 200, RoundingMode.HALF_UP);
答案 5 :(得分:0)
要修复,你应该改变第三个方面如下:
BigDecimal bd1 = new BigDecimal(1131).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd2 = new BigDecimal(365).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd3 = bd1.divide(bd2, 2, BigDecimal.ROUND_HALF_UP);
System.out.println("result: " + bd3);