为什么Java中两个BigDecimal数字的划分会抛出ArithmeticException?

时间:2012-04-05 17:07:30

标签: java

让我们看一下Java中的以下代码片段。

package division;

import java.math.BigDecimal;

final public class Main
{
    public static void main(String[] args)
    {
        BigDecimal a = new BigDecimal(2);
        BigDecimal b = new BigDecimal(3);

        System.out.println(a.multiply(b));
        System.out.println(a.add(b));
        System.out.println(b.subtract(a));
        System.out.println(a.divide(b));
    }
}

在上面的代码片段中,除了最后一个(除法)之外的所有操作都成功执行。试图在Java中划分两个BigDecimal数字会引发java.lang.ArithmeticException。为什么?这个问题的解决方案是什么?

4 个答案:

答案 0 :(得分:13)

来自BigDecimal#divide(BigDecimal) documentation

  

...如果无法表示确切的商(因为它具有非终止的十进制扩展),则抛出ArithmeticException。

在您的特定情况下,“2/3”具有非终止的十进制扩展(0.6666 ...),因此您必须使用divide()的形式,其中需要一个比例和/或{{3解决无限表示。例如:

BigDecimal a = new BigDecimal(2);
BigDecimal b = new BigDecimal(3);
a.divide(b, 4, RoundingMode.CEILING); // => 0.6667
a.divide(b, 4, RoundingMode.FLOOR);   // => 0.6666

答案 1 :(得分:2)

你得到了例外,因为没有确切的代表结果。为了解决这个问题,你需要使用scale和rounding模式的重载,如下所示:

System.out.println(a.divide(b, 20, RoundingMode.HALF_UP));

这是your modified code on ideone

6
5
1
0.66666666666666666667

答案 2 :(得分:1)

如果您阅读javadoc,则表示如果确切的商没有终止十进制扩展,它将抛出java.lang.ArithmeticException。 2/3 = .666666666 ...并且不会终止

答案 3 :(得分:1)

返回一个BigDecimal,其值为(this / divisor),其首选标度为(this.scale() - divisor.scale());如果无法表示确切的商(因为它具有非终止的十进制扩展),则抛出ArithmeticException。

2/3 = 0.666666666666666666666 ........等等,无法表示。正如JavaDoc所说,它是一个非终止的十进制扩展