什么导致BigDecimal.divide的“非终止十进制扩展”异常?

时间:2012-05-15 15:07:15

标签: java exception bigdecimal

我之前使用过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);

但是,我一直得到同样的例外。有谁能告诉我我犯了哪个错误?

6 个答案:

答案 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)

由于分割,您收到此错误:

  1. 默认情况下,BigDecimal总是尝试返回操作的确切结果。
  2. 由于这一点,某些除法运算如1除以3,精确商将具有无限长的十进制扩展。这将导致除法操作失败并抛出错误,如上所述。
  3. 在分割方法中提供缩放和舍入模式(就像你在创建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);