算术例外:“非终止十进制展开;没有确切的可表示的十进制结果”

2022-08-31 04:13:34

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

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

来自 Java 11 BigDecimal 文档

当为对象提供精度设置为 0(例如,MathContext.UNLIMITED)时,算术运算是精确的,不带对象的算术方法也是精确的。(这是 5 之前的版本中唯一支持的行为。MathContextMathContext

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

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

要修复,您需要执行以下操作

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

其中 2 是刻度,RoundingMode.HALF_UP是舍入模式

有关更多详细信息,请参阅此博客文章


答案 2

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

但是,如果您提供舍入模式和精度,那么它将能够转换为(例如1.333333333到无穷大到1.3333...但是作为程序员,你需要告诉它你“满意”的精度。


推荐