非终止十进制展开;没有精确的可表示的十进制结果;

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

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.
429115 次浏览

Java 11 BigDecimal文档:

MathContext对象的精度设置为0时(例如,MathContext.UNLIMITED),算术操作是精确的,不接受MathContext对象的算术方法也是精确的。(这是5之前版本中唯一支持的行为。)

作为计算准确结果的必然结果,没有使用精度设置为0的MathContext对象的舍入模式设置,因此不相关。在除法的情况下,精确商可以有一个无限长的十进制展开;例如,1除以3。

如果商具有不终止的十进制展开,并且指定操作返回精确的结果,则抛出ArithmeticException。否则,返回除法的准确结果,就像其他操作一样。

# EYZ0:

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

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

更多细节见这篇博文

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

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

你可以这样做

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

我也有同样的问题,因为我的代码行是:

txtTotalInvoice.setText(var1.divide(var2).doubleValue() + "");

我改为这个,阅读之前的答案,因为我没有写十进制精度:

txtTotalInvoice.setText(var1.divide(var2,4, RoundingMode.HALF_UP).doubleValue() + "");

4是十进制精度

AND RoundingMode是Enum常量,你可以选择其中任何一个 # EYZ0 < / p >

在本例中,HALF_UP的结果如下:

2.4 = 2
2.5 = 3
2.7 = 3

您可以在这里检查RoundingMode信息:http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/

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

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

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

回答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.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

这是一个舍入结果的问题,对我来说解决方案如下。

divider.divide(dividend,RoundingMode.HALF_UP);

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

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


a.divideToIntegralValue(b).setScale(2)