Search code examples
javabigdecimal

BigDecimal Incorrect Round


I have this result of division:

4893.305785123966785163027491292661448576748

I want to round to 4893.30, but it always returns 4893.31. but when the second decimal will be 6 or more i want to round up.

new BigDecimal("4893.305785123966785163027491292661448576748").setScale(2,BigDecimal.ROUND_HALF_DOWN)); to 4893.31 //BAD

new BigDecimal("4893.305").setScale(2,BigDecimal.ROUND_HALF_DOWN)); to 4893.30 //OK

new BigDecimal("4893.3055").setScale(2,BigDecimal.ROUND_HALF_DOWN)); to 4893.31 //BAD

How does the round work? I want to take in consideration only the value of the second decimal. Any ideas?


Solution

  • "How does the round work? I want to take in consideration only the value of the second decimal."

    It sounds like you want to truncate instead of round.

    Instead of using ROUND_HALF_DOWN:

    Rounding mode to round towards "nearest neighbor"...

    ...instead, try using ROUND_DOWN:

    Rounding mode to round towards zero. Never increments the digit prior to a discarded fraction (i.e., truncates)...

    e.g.

        BigDecimal bd = new BigDecimal("4893.305785123966785163027491292661448576748");
        bd = bd.setScale(2, BigDecimal.ROUND_DOWN);
        System.out.println(bd); // 4893.30
    

    Update to answer question edit

    If you want to only take certain decimal places into consideration, that's a truncate followed by a rounding:

        BigDecimal bd = new BigDecimal("4893.305785123966785163027491292661448576748");
        bd = bd.setScale(3, BigDecimal.ROUND_DOWN);       // truncate to 4893.305
        bd = bd.setScale(2, BigDecimal.ROUND_HALF_DOWN);  // round to 2 decimal places
        System.out.println(bd);                           // 4893.30
    
        bd = new BigDecimal("4893.306785123966785163027491292661448576748");
        bd = bd.setScale(3, BigDecimal.ROUND_DOWN);       // truncate to 4893.306
        bd = bd.setScale(2, BigDecimal.ROUND_HALF_DOWN);  // round to 2 decimal places
        System.out.println(bd);                           // 4893.31