ArithmeticException:“非终止十进制扩展;没有精确可表示的十进制结果”
Posted
技术标签:
【中文标题】ArithmeticException:“非终止十进制扩展;没有精确可表示的十进制结果”【英文标题】:ArithmeticException: "Non-terminating decimal expansion; no exact representable decimal result" 【发布时间】:2011-06-03 05:39:18 【问题描述】:为什么下面的代码会引发如下所示的异常?
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】:对我来说,它正在处理这个:
BigDecimal a = new BigDecimal("9999999999.6666",precision);
BigDecimal b = new BigDecimal("21",precision);
a.divideToIntegralValue(b).setScale(2)
【讨论】:
【参考方案2】:来自Java 11 BigDecimal
docs:
当
MathContext
对象的精度设置为 0(例如,MathContext.UNLIMITED
)时,算术运算是精确的,就像不采用MathContext
对象的算术方法一样。 (这是 5 之前的版本中唯一支持的行为。)作为计算精确结果的必然结果,不使用精度设置为 0 的
MathContext
对象的舍入模式设置,因此不相关。在除法的情况下,精确商可以有一个无限长的小数展开;例如,1 除以 3。如果商具有非终止的十进制扩展并且指定操作返回精确结果,则抛出
ArithmeticException
。否则,将返回除法的确切结果,就像其他操作一样。
要修复,您需要执行以下操作:
a.divide(b, 2, RoundingMode.HALF_UP)
其中 2 是比例,RoundingMode.HALF_UP 是舍入模式
更多详情请见this blog post。
【讨论】:
这也适用于 jasper 错误感谢community.jaspersoft.com/questions/528968/… 2 不是precision
;它是scale
。请看docs.oracle.com/javase/7/docs/api/java/math/…
(new BigDecimal(100)).divide(new BigDecimal(0.90), 2,RoundingMode.HALF_UP)
@AnandVarkeyPhilips 这是规模。请参阅Javadoc。编辑被拒绝。
@user207421,我不小心编辑了它并尝试恢复..但没有足够的积分来删除编辑....meta.stackexchange.com/questions/80933/…【参考方案3】:
我遇到了同样的问题,因为我的代码行是:
txtTotalInvoice.setText(var1.divide(var2).doubleValue() + "");
我改成这个,阅读上一个答案,因为我没有写小数精度:
txtTotalInvoice.setText(var1.divide(var2,4, RoundingMode.HALF_UP).doubleValue() + "");
4 是小数精度
AND RoundingMode 是枚举常量,你可以选择其中任何一个
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/
【讨论】:
4 是比例,而不是精度。【参考方案4】:这是一个四舍五入的问题,我的解决方案如下。
divider.divide(dividend,RoundingMode.HALF_UP);
【讨论】:
【参考方案5】:你的程序不知道十进制数字使用什么精度,所以它抛出:
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
【讨论】:
【参考方案6】:回答BigDecimal throws 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")));
在您的 divide 方法调用中添加 MathContext 对象并调整精度和舍入模式。这应该可以解决您的问题
【讨论】:
【参考方案7】:为了解决这个问题,我使用了下面的代码
a.divide(b, 2, RoundingMode.HALF_EVEN)
2 是精度。现在问题已经解决了。
【讨论】:
除代码外,还要提供一些解释。 2 不是precision
;这是scale
。请看docs.oracle.com/javase/7/docs/api/java/math/…
RoundingMode.HALF_EVEN 推荐用于金融应用。这就是银行业务所使用的
对于约翰·曼科斯对精度的评论感到困惑的人,请看这个答案***.com/questions/4591206/…【参考方案8】:
你可以的
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
【讨论】:
如果我想要2个十进制数字后,如何使用MatchContext实现?【参考方案9】:因为您没有指定精度和舍入模式。 BigDecimal 抱怨它可以使用 10、20、5000 或无穷小数位,但它仍然无法为您提供数字的精确表示。因此,它不会给你一个不正确的 BigDecimal,而是对你发牢骚。
但是,如果您提供 RoundingMode 和精度,那么它将能够转换(例如 1.333333333-to-infinity 到 1.3333 之类的东西......但您作为程序员需要告诉它您的精度是多少'高兴'。
【讨论】:
以上是关于ArithmeticException:“非终止十进制扩展;没有精确可表示的十进制结果”的主要内容,如果未能解决你的问题,请参考以下文章
线程“主”java.lang.ArithmeticException 中的异常:/ 为零
在 BigDecimal.divide 期间引发 ArithmeticException
ArithmeticException:“非终止十进制扩展;没有精确可表示的十进制结果”
双击以从 editText 中选择文本导致 ArithmeticException
java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: Non-terminating decimal expansion