javabigdecimal

Rounding Bigdecimal values with 2 Decimal Places


I want a function to convert Bigdecimal 10.12 for 10.12345 and 10.13 for 10.12556. But no function is satisfying both conversion in same time.Please help to achieve this.

Below is what I tried.
With value 10.12345:

BigDecimal a = new BigDecimal("10.12345");

a.setScale(2, BigDecimal.ROUND_UP)
a.setScale(2, BigDecimal.ROUND_CEILING)
a.setScale(2, BigDecimal.ROUND_DOWN)
a.setScale(2, BigDecimal.ROUND_FLOOR)
a.setScale(2, BigDecimal.ROUND_HALF_DOWN)
a.setScale(2, BigDecimal.ROUND_HALF_EVEN)
a.setScale(2, BigDecimal.ROUND_HALF_UP)

Output :

10.12345::10.13
10.12345::10.13
10.12345::10.12
10.12345::10.12
10.12345::10.12
10.12345::10.12
10.12345::10.12

With value 10.12556:

BigDecimal b = new BigDecimal("10.12556");

b.setScale(2, BigDecimal.ROUND_UP)
b.setScale(2, BigDecimal.ROUND_CEILING)
b.setScale(2, BigDecimal.ROUND_DOWN)
b.setScale(2, BigDecimal.ROUND_FLOOR)
b.setScale(2, BigDecimal.ROUND_HALF_DOWN)
b.setScale(2, BigDecimal.ROUND_HALF_EVEN)
b.setScale(2, BigDecimal.ROUND_HALF_UP)

Output :

10.12556::10.13
10.12556::10.13
10.12556::10.12
10.12556::10.12
10.12556::10.12
10.12556::10.12
10.12556::10.12

Solution

  • I think that the RoundingMode you are looking for is HALF_EVEN. From the javadoc:

    Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor. Behaves as for ROUND_HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for ROUND_HALF_DOWN if it's even. Note that this is the rounding mode that minimizes cumulative error when applied repeatedly over a sequence of calculations.

    Here is a quick test case:

    BigDecimal a = new BigDecimal("10.12345");
    BigDecimal b = new BigDecimal("10.12556");
    
    a = a.setScale(2, RoundingMode.HALF_EVEN);
    b = b.setScale(2, RoundingMode.HALF_EVEN);
    
    System.out.println(a);
    System.out.println(b);
    

    Correctly prints:

    10.12
    10.13
    

    UPDATE:

    setScale(int, int) has not been recommended since Java 1.5, when enums were first introduced, and was finally deprecated in Java 9. You should now use setScale(int, RoundingMode) e.g:

    setScale(2, RoundingMode.HALF_EVEN)