为什么以下代码会引发如下所示的异常?
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.
#1楼
你可以做
a.divide(b, MathContext.DECIMAL128)
您可以选择想要的位数32、64、128。
查看此链接:
#2楼
我遇到了同样的问题,因为我的代码行是:
txtTotalInvoice.setText(var1.divide(var2).doubleValue() + "");
我改为之前阅读的答案,因为我没有写十进制精度:
txtTotalInvoice.setText(var1.divide(var2,4, RoundingMode.HALF_UP).doubleValue() + "");
4是十进制精度
AND RoundingMode是Enum常数,您可以选择以下任意一种: UP, DOWN, CEILING, FLOOR, HALF_DOWN, HALF_EVEN, HALF_UP
在这种情况下,HALF_UP将具有以下结果:
2.4 = 2
2.5 = 3
2.7 = 3
您可以在此处查看RoundingMode
信息: http : //www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/
#3楼
为了解决这个问题,我使用了以下代码
a.divide(b, 2, RoundingMode.HALF_EVEN)
2是精度。 现在问题已解决。
#4楼
BigDecimal的答案引发ArithmeticException
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")));
}
在您的除法方法调用中添加MathContext对象,并调整精度和舍入模式。 这应该可以解决您的问题
#5楼
这是因为Bigdecimal不会丢失,例如,如果将1/3除,则将导致重复的十进制到无穷大。 0.33333333 ...从理论上讲,如果再相乘,您将得到准确的结果。 但是,无穷大数将生成堆栈溢出,在这种情况下,将引发异常。
一个办法:
try {
result = n1.divide(n2);
} catch (ArithmeticException e){
Log.d("Error bigdecimal", e.toString());
result = (n1.doubleValue() / n2.doubleValue());
};
要么
n1.divide(n2,RoundingMode.HALF_UP);
在这种情况下,您的结果将不会被舍入
#6楼
从Java 8文档中:
当为MathContext对象提供的精度设置为0(例如MathContext.UNLIMITED)时,算术运算是精确的,不采用MathContext对象的算术方法也是如此。 (这是5之前的版本中唯一支持的行为。)
作为计算精确结果的必然结果,不使用精度设置为0的MathContext对象的舍入模式设置,因此不相关。 在除法的情况下,精确的商可能具有无限长的十进制扩展; 例如1除以3。
如果商具有无终止的十进制扩展,并且指定了该操作以返回精确的结果,则抛出ArithmeticException。 否则,将返回除法的精确结果,就像其他操作一样。
要解决此问题,您需要执行以下操作 :
a.divide(b, 2, RoundingMode.HALF_UP)
where 2 is scale and RoundingMode.HALF_UP is rounding mode
更多详细信息: http : //jaydeepm.wordpress.com/2009/06/04/bigdecimal-and-non-terminated-decimal-expansion-error/
#7楼
因为您没有指定精度和舍入模式。 BigDecimal抱怨它可以使用10、20、5000或无穷小数位,但仍然无法为您提供数字的精确表示。 因此,它不会给您错误的BigDecimal,而是会向您发脾气。
但是,如果您提供RoundingMode和精度,则它将能够将(例如1.333333333-to-infinity)转换为类似1.3333的值……但是作为程序员,您需要告诉它您对“精度”感到满意'。
#8楼
您的程序不知道使用十进制数字的精度,因此它抛出:
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
#9楼
这是对结果进行四舍五入的问题,以下是我的解决方案。
divider.divide(dividend,RoundingMode.HALF_UP);