Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't BigDecimal.stripTrailingZeros() remove always all trailing zeros?

I do the following

    MathContext context = new MathContext(7, RoundingMode.HALF_UP);
    BigDecimal roundedValue = new BigDecimal(value, context);

    // Limit decimal places
    try {
        roundedValue = roundedValue.setScale(decimalPlaces, RoundingMode.HALF_UP);
    } catch (NegativeArraySizeException e) {
        throw new IllegalArgumentException("Invalid count of decimal places.");
    }
    roundedValue = roundedValue.stripTrailingZeros();

    String returnValue = roundedValue.toPlainString();

In case the input is now "-0.000987654321" (= value) I get back "-0.001" (= return Value) which is ok.

In case the input is now "-0.0000987654321" I get back "-0.0001" which is also ok.

But when the input is now "-0.00000987654321" I get back "0.0000" instead of "0" which is not ok. What is wrong here? Why aren't the trailing zeros removed in this case?

like image 437
Florian Avatar asked Jan 27 '14 15:01

Florian


2 Answers

BigDecimal d = new BigDecimal("0.0000");
System.out.println(d.stripTrailingZeros());

prints 0.0000 with Java 7 but 0 with Java 8. This is apparently a bug that has been fixed in Java 8.

like image 57
assylias Avatar answered Sep 18 '22 18:09

assylias


From the description of BigDecimal's stripTrailingZeros:

"Returns a BigDecimal which is numerically equal to this one but with any trailing zeros removed from the representation. For example, stripping the trailing zeros from the BigDecimal value 600.0, which has [BigInteger, scale] components equals to [6000, 1], yields 6E2 with [BigInteger, scale] components equals to [6, -2]"

In other words, it doesn't do what you want it to do. Instead, use the setScale(0) method. The following piece of testcode I wrote give the following output:

    BigDecimal d = new BigDecimal("0.0000");
    System.out.println(d.toString());
    d = d.setScale(0);
    System.out.println(d.toString());

0.0000
0

EDIT: When doing this for 0.0001, you get an error. You need to set the roundingmode as well. (Overload for setScale) You'll have to figure out something to work around that.

like image 25
Reinstate Monica Avatar answered Sep 19 '22 18:09

Reinstate Monica