Java BigDecimal: Round to the nearest whole value

207,825

Solution 1

You can use setScale() to reduce the number of fractional digits to zero. Assuming value holds the value to be rounded:

BigDecimal scaled = value.setScale(0, RoundingMode.HALF_UP);
System.out.println(value + " -> " + scaled);

Using round() is a bit more involved as it requires you to specify the number of digits to be retained. In your examples this would be 3, but this is not valid for all values:

BigDecimal rounded = value.round(new MathContext(3, RoundingMode.HALF_UP));
System.out.println(value + " -> " + rounded);

(Note that BigDecimal objects are immutable; both setScale and round will return a new object.)

Solution 2

If i go by Grodriguez's answer

System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);

This is the output

100.23 -> 100
100.77 -> 101

Which isn't quite what i want, so i ended up doing this..

System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
value = value.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);

This is what i get

100.23 -> 100.00
100.77 -> 101.00

This solves my problem for now .. : ) Thank you all.

Solution 3

Here's an awfully complicated solution, but it works:

public static BigDecimal roundBigDecimal(final BigDecimal input){
    return input.round(
        new MathContext(
            input.toBigInteger().toString().length(),
            RoundingMode.HALF_UP
        )
    );
}

Test Code:

List<BigDecimal> bigDecimals =
    Arrays.asList(new BigDecimal("100.12"),
        new BigDecimal("100.44"),
        new BigDecimal("100.50"),
        new BigDecimal("100.75"));
for(final BigDecimal bd : bigDecimals){
    System.out.println(roundBigDecimal(bd).toPlainString());
}

Output:

100
100
101
101

Solution 4

Simply look at:

http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html#ROUND_HALF_UP

and:

setScale(int precision, int roundingMode)

Or if using Java 6, then

http://download.oracle.com/javase/6/docs/api/java/math/RoundingMode.html#HALF_UP

http://download.oracle.com/javase/6/docs/api/java/math/MathContext.html

and either:

setScale(int precision, RoundingMode mode);
round(MathContext mc);
Share:
207,825

Related videos on Youtube

n a
Author by

n a

Updated on March 07, 2020

Comments

  • n a
    n a about 4 years

    I need the following results

    100.12 -> 100.00
    100.44 -> 100.00
    100.50 -> 101.00
    100.75 -> 101.00
    

    .round() or .setScale() ? How do I go about this?

  • Boris Pavlović
    Boris Pavlović over 13 years
    It's not working: 100.12 : 100.12, 100.44 : 100.44, 100.50 : 100.5, 100.75 : 100.75
  • Daniel Fath
    Daniel Fath over 13 years
    No, setting scale returns a new decimal that isn't same as the first. For example:BigDecimal bd1 = new BigDecimal(100.12); BigDecimal bd2 = bd1.setScale(0, RoundingMode.HALF_UP); System.out.println(bd1.equals(bd2)); prints false
  • Grodriguez
    Grodriguez over 13 years
    This does nothing. From the documentation of round: "If the precision setting is 0 then no rounding takes place."
  • Grodriguez
    Grodriguez over 13 years
    @Daniel: That was already implied in the code snippet I posted in my answer. I've now made it explicit.
  • joel.neely
    joel.neely about 8 years
    I am curious about the statement that the first result "isn't quite what I want...". If you are actually concerned about output formatting, you can use DecimalFormat (as in new DecimalFormat("###.00") ) to manage the conversion of a BigDecimal back to string. It gives "101.00" as the result for both values that the snippets from @Grodriquez and you created.
  • kosmoplan
    kosmoplan about 7 years
    The second time you are rounding here is unnecessary as you know you have an integer already, so I would use BigDecimal.ROUND_UNNECESSARY instead, a bit more clear in my opinion.
  • trilogy
    trilogy over 5 years
    RoundingMode what is that? It's BigDecimal
  • Grodriguez
    Grodriguez over 5 years
  • Addison
    Addison almost 5 years
    Not to endorse this solution or anything, but the input.toBigInteger().toString().length() part would be much more efficient by using a logarithm, some thing like round_up(log(input)) + (1 if input is a power of ten, else 0)
  • MarkHu
    MarkHu over 2 years
    BigDecimal seems like a steaming heap.