10

Let's look at the following code snippet in Java.

package division;

import java.math.BigDecimal;

final public class Main
{
    public static void main(String[] args)
    {
        BigDecimal a = new BigDecimal(2);
        BigDecimal b = new BigDecimal(3);

        System.out.println(a.multiply(b));
        System.out.println(a.add(b));
        System.out.println(b.subtract(a));
        System.out.println(a.divide(b));
    }
}

In the above code snippet, all of the operations except the last one (division) are performed successfully. An attempt to divide two BigDecimal numbers in Java throws the java.lang.ArithmeticException. Why? What is the solution to this problem?

Lion
  • 18,729
  • 22
  • 80
  • 110
  • 2
    it seems to be the same like this: http://stackoverflow.com/questions/2749375/arithmeticexception-thrown-during-bigdecimal-divide – dexametason Apr 05 '12 at 17:10

4 Answers4

19

From the BigDecimal#divide(BigDecimal) documentation:

...if the exact quotient cannot be represented (because it has a non-terminating decimal expansion) an ArithmeticException is thrown.

In your specific case "2/3" has a non-terminating decimal expansion (0.6666...) so you'll have to use a form of divide() which takes a scale and/or RoundingMode to resolve the infinite representation. For example:

BigDecimal a = new BigDecimal(2);
BigDecimal b = new BigDecimal(3);
a.divide(b, 4, RoundingMode.CEILING); // => 0.6667
a.divide(b, 4, RoundingMode.FLOOR);   // => 0.6666
maerics
  • 151,642
  • 46
  • 269
  • 291
2

You get the exception because there is no exact representation of the result of the division. In order to work around this problem, you need to use the overload with the scale and rounding mode, like this:

System.out.println(a.divide(b, 20, RoundingMode.HALF_UP));

Here is your modified code on ideone.

6
5
1
0.66666666666666666667
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

If you read the javadoc it says it will throw an java.lang.ArithmeticException if the exact quotient does not have a terminating decimal expansion. 2/3 = .666666666... and does not terminate

Danny
  • 7,368
  • 8
  • 46
  • 70
1

Returns a BigDecimal whose value is (this / divisor), and whose preferred scale is (this.scale() - divisor.scale()); if the exact quotient cannot be represented (because it has a non-terminating decimal expansion) an ArithmeticException is thrown.

2 / 3 = 0.666666666666666666666........ and so on, and it cannot be represented. As JavaDoc says, it's a non-terminating decimal expansion

Matei Suica
  • 859
  • 1
  • 7
  • 17