Question

I'm tinkering with BigDecimal and currency formatting in Android, and was wondering if it was possible to do the following using BigDecimal:

What I desire:

  64.99 --> 65.00 (Rounded Up)
  64.99 --> 60.00 (Rounded Down)
  65.01 --> 70.00 (Rounded Up)
  65.01 --> 65.00 (Rounded Down)

At present, with my code below, I'm only able to round to zeros. For example:

What I get:

  64.99 --> 70.00 (Rounded Up)
  64.99 --> 60.00 (Rounded Down)
  65.01 --> 70.00 (Rounded Up)
  65.01 --> 60.00 (Rounded Down)

Is there a way using BigDecimal to achieve what I desire?

My code:

private static void printRoundedValues() {
    NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
    BigDecimal valueUp = new BigDecimal(64.50, new MathContext(1,RoundingMode.UP));
    BigDecimal valueDown = new BigDecimal(64.50, new MathContext(1,RoundingMode.DOWN)); 

    System.out.println("Value Up: " +  currencyFormat.format(valueUp));
    System.out.println("Value Down: " +  currencyFormat.format(valueDown));
}
Was it helpful?

Solution

You can multiply by 2, then round to the nearest 10, then divide by 2. The precision is 2 for these BigDecimals; it may need to be different for BigDecimals of different scale.

BigDecimal[] bds = {new BigDecimal("64.99"), new BigDecimal("65.01")};
BigDecimal two = new BigDecimal("2");
MathContext mcUp = new MathContext(2, RoundingMode.UP);
MathContext mcDown = new MathContext(2, RoundingMode.DOWN);
NumberFormat currency = NumberFormat.getCurrencyInstance();
for (BigDecimal bd : bds)
{
    System.out.println("Test: " + bd);
    BigDecimal roundUp5 = bd.multiply(two).round(mcUp).divide(two);
    System.out.println("Round up: " + currency.format(roundUp5));
    BigDecimal roundDown5 = bd.multiply(two).round(mcDown).divide(two);
    System.out.println("Round down: " + currency.format(roundDown5));
}

Output:

Test: 64.99
Round up: $65.00
Round down: $60.00
Test: 65.01
Round up: $70.00
Round down: $65.00

OTHER TIPS

    NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
    BigDecimal valueUp = new BigDecimal(64.50, new MathContext(2, RoundingMode.UP));
    BigDecimal valueDown = new BigDecimal(64.50, new MathContext(2, RoundingMode.DOWN));

    System.out.println("Value Up: " +  currencyFormat.format(valueUp));
    System.out.println("Value Down: " +  currencyFormat.format(valueDown));

Here is how MathContext precision works:

  • creates a value (64.5)
  • set the precision to given value (2) which results in 64.5
  • round this value using given RoundingMode (UP), which gives you the value of 65

You probably need to set scale rather than precision:

    BigDecimal valueUp = new BigDecimal(64.50).setScale(0, RoundingMode.UP);
    BigDecimal valueDown = new BigDecimal(64.50).setScale(0, RoundingMode.DOWN);

The function you are looking for is setScale and is part of BigDecimal.

Here is a good answer to the same question: Java BigDecimal: Round to the nearest whole value

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top