RoundingMode.UNNECESSARY throws exception

4.1k views Asked by At

I wrote this to test BigDecimal in action but found that RoundingMode.UNNECESSARY threw an exception. Can anyone explain why?

public class TestRounding2 {

    public static void main(String args[]) {

        Locale swedish = new Locale("sv", "SE");
        BigDecimal pp; //declare variable pp=pounds pence

        NumberFormat swedishFormat = NumberFormat.getCurrencyInstance(swedish);

        Scanner scan = new Scanner(System.in);
        System.out.println("ENTER POUNDS AND PENCE TO AT LEAST FIVE DECIMAL PLACES :");

        pp = scan.nextBigDecimal();

        BigDecimal pp1 = pp.setScale(2, RoundingMode.HALF_EVEN);
        System.out.println("HALF_EVEN: £ " + pp1.toString());
        System.out.println(swedishFormat.format(pp1));

        BigDecimal pp2 = pp.setScale(2, RoundingMode.FLOOR);
        System.out.println("FLOOR: £ " + pp2.toString());
        System.out.println(swedishFormat.format(pp2));

        BigDecimal pp3 = pp.setScale(2, RoundingMode.CEILING);
        System.out.println("CEILING £: " + pp3.toString());
        System.out.println(swedishFormat.format(pp3));

        BigDecimal pp4 = pp.setScale(2, RoundingMode.HALF_DOWN);
        System.out.println("HALF DOWN £: " + pp4.toString());
        System.out.println(swedishFormat.format(pp4));

        BigDecimal pp5 = pp.setScale(2, RoundingMode.HALF_UP);
        System.out.println("HALF UP: £ " + pp5.toString());
        System.out.println(swedishFormat.format(pp5));

        BigDecimal pp6 = pp.setScale(2, RoundingMode.UP);
        System.out.println("UP: £ " + pp6.toString());
        System.out.println(swedishFormat.format(pp6));

        BigDecimal pp7 = pp.setScale(2, RoundingMode.DOWN);
        System.out.println("DOWN: £ " + pp7.toString());
        System.out.println(swedishFormat.format(pp7));

        BigDecimal pp8 = pp.setScale(2, RoundingMode.UP);
        System.out.println("UP:  " + pp8.toString());
        System.out.println(swedishFormat.format(pp8));

    }
}
1

There are 1 answers

3
Sergey Grinev On BEST ANSWER

It's by design. See javadoc:

Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary. If this rounding mode is specified on an operation that yields an inexact result, an {@code ArithmeticException} is thrown.

This mode is made to specifically throw an exception if there is something to round.

Examples. Next code doesn't throw Exception.

    BigDecimal pp = new BigDecimal(7);
    pp.setScale(2, RoundingMode.UNNECESSARY);
    System.out.println(pp);

changing 7 to fractional number leads to an exception because it's now NECESSARY to round it:

    BigDecimal pp = new BigDecimal(7.1);
    pp.setScale(2, RoundingMode.UNNECESSARY);
    // java.lang.ArithmeticException: Rounding necessary
    System.out.println(pp);