mrd
mrd

Reputation: 4699

BigDecimal in Java: How to round to 10?

I want to round BigDecimal numbers to 10 up or down:

112 --> 110

117 --> 120

150 --> 150

115 --> 120

114.9 --> 110

67 --> 70

64 --> 60

etc.

I tried this:

number = number.round(new MathContext(1, RoundingMode.HALF_UP));

11 —> 10

150 —> 200 // wrong! should be 150!

48 —> 50

500 —> 500

250 —> 300 // wrong! should be 250!

240 —> 200 // wrong! should be 240!

245 —> 200 // wrong! should be 250!

51 -> 50

I have tried several other values for precision, but I never get correct rounding for all values.

What I am missing here?

Upvotes: 4

Views: 5037

Answers (3)

antoniodvr
antoniodvr

Reputation: 1259

You can use this:

private BigDecimal round(BigDecimal value) {
    value = value.multiply(new BigDecimal(0.01));
    value = value.setScale(1, BigDecimal.ROUND_HALF_UP);
    value = value.multiply(new BigDecimal(100));
    return value;
}

But the correct way to perform the scale is:

value = value.setScale(-1, RoundingMode.HALF_UP);

Here you will have the exponential representation of the number. You can use this method:

value.toPlainString();

to get back the plain string.

toPlainString() Returns a string representation of this BigDecimal without an exponent field.

Upvotes: 2

John Bollinger
John Bollinger

Reputation: 180351

You are missing that the MathContext object with which you are performing the rounding specifies the precision of the rounded result (== number of significant digits), not the scale (related to the place value of the least-significant digit). More generally, BigDecimal.round() is all about managing the precision of your numbers, which is not what you're after.

You can round a BigDecimal to the nearest multiple of any given power of 10 by setting its scale. To round to the nearest multiple of 10 itself, that would be:

number = number.setScale(-1, RoundingMode.HALF_UP));

Note that if the initial scale is less than -1, then this results in an increase in the precision of the number (by addition of significant trailing zeroes). If you don't want that, then test the scale (BigSecimal.scale()) to determine whether to round.

Upvotes: 5

Anubian Noob
Anubian Noob

Reputation: 13596

It's pretty easy to do with an ordinary int:

Math.round(number/10f)*10

Assuming number is 42, number/10f is 4.2, which rounds to 4.0, which when multiplied by 10 give 40.

Upvotes: 0

Related Questions