为什么下面的代码会引发如下所示的异常?

BigDecimal a = new BigDecimal("1.6");
BigDecimal b = new BigDecimal("9.2");
a.divide(b) // results in the following exception.

例外:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

当前回答

来自Java 11 BigDecimal文档:

When a MathContext object is supplied with a precision setting of 0 (for example, MathContext.UNLIMITED), arithmetic operations are exact, as are the arithmetic methods which take no MathContext object. (This is the only behavior that was supported in releases prior to 5.) As a corollary of computing the exact result, the rounding mode setting of a MathContext object with a precision setting of 0 is not used and thus irrelevant. In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3. If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown. Otherwise, the exact result of the division is returned, as done for other operations.

要修复,你需要做这样的事情:

a.divide(b, 2, RoundingMode.HALF_UP)

其中2是比例和round mode。HALF_UP是舍入模式

欲了解更多细节,请参阅这篇博客文章。

其他回答

对我来说,它是这样工作的:

BigDecimal a = new BigDecimal("9999999999.6666",precision);
BigDecimal b = new BigDecimal("21",precision);

a.divideToIntegralValue(b).setScale(2)

为了解决这个问题,我使用了下面的代码

a.divide(b, 2, RoundingMode.HALF_EVEN)

其中2是比例。现在问题应该解决了。

你的程序不知道十进制数的精度是多少,所以抛出:

java.lang.ArithmeticException: Non-terminating decimal expansion

绕过异常的解决方案:

MathContext precision = new MathContext(int setPrecisionYouWant); // example 2
BigDecimal a = new BigDecimal("1.6",precision);
BigDecimal b = new BigDecimal("9.2",precision);
a.divide(b) // result = 0.17

你可以这样做

a.divide(b, MathContext.DECIMAL128)

你可以选择你想要的比特数:32、64或128。

看看这个链接:

http://edelstein.pebbles.cs.cmu.edu/jadeite/main.php?api=java6&state=class&package=java.math&class=MathContext

因为你没有指定精度和舍入模式。BigDecimal抱怨说,它可以使用10位、20位、5000位或无穷大的小数位,但它仍然不能给您一个精确的数字表示。所以它不会给你一个不正确的BigDecimal,而是会向你抱怨。

然而,如果你提供了一个RoundingMode和一个精度,那么它将能够转换(例如。从1.333333333到无穷到1.3333……但作为程序员,你需要告诉它你“满意”的精度是多少。