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

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.

当前回答

BigDecimal的答案抛出算术异常

public static void main(String[] args) {
        int age = 30;
        BigDecimal retireMentFund = new BigDecimal("10000.00");
        retireMentFund.setScale(2,BigDecimal.ROUND_HALF_UP);
        BigDecimal yearsInRetirement = new BigDecimal("20.00");
        String name = " Dennis";
        for ( int i = age; i <=65; i++){
            recalculate(retireMentFund,new BigDecimal("0.10"));
        }
        BigDecimal monthlyPension =   retireMentFund.divide(
                yearsInRetirement.divide(new BigDecimal("12"), new MathContext(2, RoundingMode.CEILING)), new MathContext(2, RoundingMode.CEILING));      
        System.out.println(name+ " will have £" + monthlyPension +" per month for retirement");
    }
public static void recalculate (BigDecimal fundAmount, BigDecimal rate){
        fundAmount.multiply(rate.add(new BigDecimal("1.00")));
    }

在divide方法调用中添加MathContext对象,并调整精度和舍入模式。这应该可以解决您的问题

其他回答

来自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抱怨说,它可以使用10位、20位、5000位或无穷大的小数位,但它仍然不能给您一个精确的数字表示。所以它不会给你一个不正确的BigDecimal,而是会向你抱怨。

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

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

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, 2, RoundingMode.HALF_EVEN)

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

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

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

a.divideToIntegralValue(b).setScale(2)