Search code examples
androidroundingbigdecimal

BigDecimal round to 0 or 5


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));
}

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