regisxp
regisxp

Reputation: 986

Java BigDecimal Rounding Error

I have the following function that is used to round a double value in Java:

public static double round(double d, int decimalPlace) {

    BigDecimal bd = new BigDecimal(Double.toString(d));
    bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
    return bd.doubleValue();
}

As input, this function is receiving these values:

double d = 7.3149999999999995;
int decimalPlace = 2

But, when the function returns, the value returned is 7.31, instead of 7.32. I searched on the docs to see why the bd.SetScale is with that behavior, but with no success.

Does anybody could me explain why is this happening? Thanks a lot!!

Upvotes: 1

Views: 1112

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1500285

Does anybody could me explain why is this happening?

It's obeying the documented behaviour :) From the docs:

If the scale is reduced by the operation, the unscaled value must be divided (rather than multiplied), and the value may be changed; in this case, the specified rounding mode is applied to the division.

And for RoundingMode.HALF_UP:

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

Now 7.3149999999999995 isn't equidistant to both 7.31 and 7.32 - it's closer to 7.31, so that's the result.

The difference between HALF_UP and HALF_DOWN would only be seen if the original value were exactly 7.315, i.e. half way between the two.

As an aside, to make sure you get exactly the number you'd expect to start with, I'd suggest using a String. For example:

double d = 0.1;
BigDecimal bd = new BigDecimal(d);

isn't the same as:

BigDecimal bd = new BigDecimal("0.1");

Converting from double to BigDecimal is usually a sign that you've got something wrong, and you should be using one type consistently throughout.

Upvotes: 11

Paul Roberts
Paul Roberts

Reputation: 56

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

In your example, the nearest neighbor is: 7.31 because 4 in 7.314 is closer to 0 than 10. To prove this, change 7.314... to 7.315....

Look at the different rounding modes to provide the behavior you want.

Upvotes: 1

Related Questions