Skip to content
Advertisement

BigDecimal gives unexpected results for numbers larger than 7 or 0 decimal numbers

While trying to calculate a ratio of the volume of 2 objects, I noticed some weirdness in the calculation, here is a sample you can run for yourself:

JavaScript

And the result is:

JavaScript

There are 3 ways I could make it give me the expected result

1. If I change the decimal part from 0 to 1 (or any non-0 number):

JavaScript

2. If I divide the numbers beforehand (make them 7 digit numbers instead of 8):

JavaScript

3. If I specify a scale doing division (first.divide(second, 0, RoundingMode.HALF_UP):

JavaScript

I thought that BigDecimal is backed by an integer and the numbers I used are way below 2 billion. Can anyone explain what makes these 3 cases different from the original result?

Advertisement

Answer

As per the documentation, divide​(BigDecimal divisor, RoundingMode roundingMode) returns a BigDecimal whose value is (this / divisor), and whose scale is this.scale().

Why did you get the expected result for 21099000.1 / 13196000.1?

Check the result of the following code:

JavaScript

Output:

JavaScript

As you can see, JVM has chosen the scale as 1 for first and thus the result of divide (which is 1.5988936041) is also set as 1 which is equal to 1.6 with RoundingMode.HALF_UP.

Why did you not get the expected result for 21099000.0 / 13196000.0?

Check the result of the following code:

JavaScript

Output:

JavaScript

As you can see, JVM has chosen the scale as -3 for first and thus the result of divide (which is 1.5988936041) is also set as -3 which is equal to 0 (or 0E+3) with RoundingMode.HALF_UP.

How can I change this behavior?

As mentioned in the documentation, scale of the division is set as this.scale() which means if you set the scale of first to 1, you can get the expected result.

JavaScript

Output:

JavaScript

What is the most common way?

The last example worked well and there is no problem using it. However, the most common way is to use divide​(BigDecimal divisor, int scale, RoundingMode roundingMode).

JavaScript

Output:

JavaScript
Advertisement