8

让我们看一下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

4 回答 4

15

BigDecimal#divide(BigDecimal)文档中:

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

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

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
于 2012-04-05T17:11:42.947 回答
2

您会得到例外,因为没有除法结果的确切表示。为了解决这个问题,您需要使用带有比例和舍入模式的重载,如下所示:

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

这是您在 ideone 上修改后的代码

6
5
1
0.66666666666666666667
于 2012-04-05T17:13:57.377 回答
1

如果您阅读javadocjava.lang.ArithmeticException ,它说如果确切的商没有终止的十进制扩展,它将抛出一个。2/3 = .666666666...并且不终止

于 2012-04-05T17:12:03.443 回答
1

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

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

于 2012-04-05T17:12:08.873 回答