How to truncate a BigDecimal without rounding

57,685

Solution 1

Use either RoundingMode.DOWN or RoundingMode.FLOOR.

BigDecimal newValue = myBigDecimal.setScale(2, RoundingMode.DOWN);

Solution 2

Use the setScale override that includes RoundingMode:

value.setScale(2, RoundingMode.DOWN);

Solution 3

I faced an issue truncating when I was using one BigDecimal to set another. The source could have any value with different decimal values.

BigDecimal source = BigDecimal.valueOf(11.23); // could 11 11.2 11.234 11.20 etc

In order to truncate and scale this correctly for two decimals, I had to use the string value of the source instead of the BigDecimal or double value.

new BigDecimal(source.toPlainString()).setScale(2, RoundingMode.FLOOR))

I used this for currency and this always results in values with 2 decimal places.

  • 11 -> 11.00
  • 11.2 -> 11.20
  • 11.234 -> 11.23
  • 11.238 -> 11.23
  • 11.20 -> 11.20
Share:
57,685
DJ180
Author by

DJ180

Updated on September 05, 2022

Comments

  • DJ180
    DJ180 over 1 year

    After a series of calculations in my code, I have a BigDecimal with value 0.01954

    I then need to multiply this BigDecimal by 100 and I wish the calculated value to be 1.95

    I do not wish to perform any rounding up or down, I just want any values beyond two decimal places to be truncated

    I tried setting scale to 2, but then I got an ArithmeticException saying rounding is necessary. How can I set scale without specifying rounding?

  • user666
    user666 over 4 years
    new BigDecimal(4343.33).setScale(2, RoundingMode.DOWN) returns 4343.32
  • GriffeyDog
    GriffeyDog over 4 years
    @user666 You are using the constructor that takes a floating point value, which can have rounding errors itself. Use the constructor that takes a String instead: new BigDecimal("4343.33").setScale(2, RoundingMode.DOWN)
  • user666
    user666 over 4 years
    that is correct, I tried it and it worked. But what if I have a bigDecimal object already existing? will it be treated like the string?
  • Zbyszek
    Zbyszek over 2 years
    11.238 -> 11.28 ?
  • GriffeyDog
    GriffeyDog over 2 years
    @San4musa Not true, you will get x.55. You can try it yourself: BigDecimal myBigDecimal = new BigDecimal("5.5555555"); BigDecimal newValue = myBigDecimal.setScale(2, RoundingMode.DOWN); System.out.println(newValue);
  • San4musa
    San4musa over 2 years
    @GriffeyDog you are right, I messed up with HALF_DOWN , my comment can not be edited to I'm deleting the comment "RoundingMode.DOWN will fail if the value is x.5555555 as the truncating value is > 0.5 so it will round to x.56 if you use BigDecimal newValue = myBigDecimal.setScale(2, RoundingMode.DOWN); " This statement is true for HALF_DOWN not for DOWN mode.