Why does the following code raise the exception shown below?
BigDecimal a = new BigDecimal("1.6"); BigDecimal b = new BigDecimal("9.2"); a.divide(b) // results in the following exception.
Exception:
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
Non-Terminating, Non-Repeating Decimal. A non-terminating, non-repeating decimal is a decimal number that continues endlessly, with no group of digits repeating endlessly. Decimals of this type cannot be represented as fractions, and as a result are irrational numbers. Examples.
Non-terminating decimals are the one that does not have an end term. It has an infinite number of terms. Example: 0.5444444….., 0.1111111….., etc.
A number has a terminating decimal expansion if the digits after the decimal point terminate or are finite. The fraction 5/10 has the decimal expansion of 0.5, which is a terminating decimal expansion because digits after the decimal point end after one digit.
A BigDecimal consists of an arbitrary precision integer unscaled value and a 32-bit integer scale. If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale.
From the Java 11 BigDecimal
docs:
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 noMathContext
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.
To fix, you need to do something like this:
a.divide(b, 2, RoundingMode.HALF_UP)
where 2 is the scale and RoundingMode.HALF_UP is rounding mode
For more details see this blog post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With