'What causes "Non-terminating decimal expansion" exception from BigDecimal.divide? [duplicate]
I've used BigDecimals before but not very often and I was working on something this morning and I kept getting the following exception:
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion;
no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1594)
I was attempting to set the scale and use rounding to eliminate the problem like so:
BigDecimal bd1 = new BigDecimal(1131).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd2 = new BigDecimal(365).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd3 = bd1.divide(bd2).setScale(2,BigDecimal.ROUND_HALF_UP);
System.out.println("result: " + bd3);
However, I keep getting the same exception. Anyone able to show me where I have made a mistake?
Solution 1:[1]
Non-terminating decimal need rounding
When using divide you should use a MathContext with RoundingMode in case the exact result has an infinite number of decimals.
Such is your case:
MathContext mc = new MathContext(2, RoundingMode.HALF_UP) ;
BigDecimal bd3 = bd1.divide(bd2, mc);
Alternatively call divide with a rounding mode to use the scale of the numerator (bd1 in the example below):
BigDecimal bd3 = bd1.divide(bd2, RoundingMode.HALF_UP);
Solution 2:[2]
Here's the problem
bd1.divide(bd2)
You need to use one of the overloaded divide() methods that takes a rounding mode (in various forms) - you cannot do the rounding after the division because with a nonterminating fraction the intermediate result would either already need to be rounded, or require infinite storage space.
Solution 3:[3]
The problem is caused by an operation (division) that would result in a recurring decimal.
The solution is to specify a scale when performing a division, for example:
BigDecimal one = new BigDecimal("1");
BigDecimal three = new BigDecimal("3");
BigDecimal oneDivThree = one.divide(three, 200, RoundingMode.HALF_UP);
Solution 4:[4]
By default, BigDecimal attempts to return the exact value of the given division expression. Because of this, if the exact value cannot be determined due to an infinite decimal expansion, an ArithmeticException is thrown. A basic example of this is dividing 1 by 3, resulting in one third, a value which cannot be represented exactly in decimal notation.
Solution 5:[5]
You are getting this error because of the division:
- The BigDecimal by default always tries to return the exact result of an operation.
- Due to this, certain division operations like 1 divided by 3, the exact quotient will have an infinitely long decimal expansion. This will cause the division operation to fail and throw the error as described above.
Provide a scale and a rounding mode (as you've done when creating the BigDecimals) within the division method to prevent this.
Taken from here. Example code for working division is also provided.
See also: Java docs on BigDecimal.
Solution 6:[6]
To fix, you should change the third stament as follow:
BigDecimal bd1 = new BigDecimal(1131).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd2 = new BigDecimal(365).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd3 = bd1.divide(bd2, 2, BigDecimal.ROUND_HALF_UP);
System.out.println("result: " + bd3);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Michael Borgwardt |
| Solution 3 | Neil Coffey |
| Solution 4 | FThompson |
| Solution 5 | |
| Solution 6 | The Tran |
