Reputation: 986
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
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
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