Piotr Sagalara
Piotr Sagalara

Reputation: 2485

BigDecimal wrong rounding

I have a problem with rounding a number using BigDecimal's scale and RoundingMode.

This is my piece of code:

BigDecimal taxAmount = new BigDecimal("0.8445");
taxAmount = taxAmountPrecision.setScale(2, RoundingMode.HALF_UP);

If I put 0.845 it is rounding well, but if there is 0.8445 the taxAmount is 0.84.

It should be 0.8445 -> 0.845 -> 0.85.

Upvotes: 4

Views: 1859

Answers (2)

Mateus Gondim
Mateus Gondim

Reputation: 5542

In order to achieve the desired behavior, you'd have to set the scale to 3 at first, then set to 2:

BigDecimal taxAmount = new BigDecimal("0.8445");
taxAmount = taxAmount.setScale(3, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);

Depending on the requirements(such as the number of decimal places you should expect), it makes more sense to do that decreasing precision logic in a loop.

Upvotes: 0

resueman
resueman

Reputation: 10623

That's the exact expected behavior of that rounding method.

Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.

The nearest neighbor of 0.8445 to 2 decimal places is 0.84. HALF_UP will round to 0.85 if the value is 0.845 or greater (halfway between the values), and will round to 0.844 if it's less than that. 0.8445 is less than 0.845, so it rounds down.

There are no intermediate rounding steps to propagate the 5 like you want. If you want that sort of rounding, you'll have to write a loop which rounds to steadily decreasing precisions.

Upvotes: 9

Related Questions