Search code examples
javabigintegerbigdecimalzero

Why BigDecimal.ZERO is unscaled?


The Javadoc for BigDecimal.ZERO says The value 0, with a scale of 0. As the name suggests one may expect that BigDecimal.ZERO should return value 0.0

I also know that it is the way BigDecimal.ZERO is coded:

private static final BigDecimal zeroThroughTen[] = {
        new BigDecimal(BigInteger.ZERO,         0,  0, 1),
        new BigDecimal(BigInteger.ONE,          1,  0, 1),
...
}

// Constants
/**
 * The value 0, with a scale of 0.
 *
 * @since  1.5
 */
public static final BigDecimal ZERO =
        zeroThroughTen[0];

I don't understand why it is decided in Java that BigDecimal.ZERO returns unscaled zero rather than return decimal zero (at least with scale 1 by default, i.e. 0.0).

What is the need that BigDecimal.ZERO and BigInteger.ZERO both returns value 0 with scale 0?


Solution

  • I don't know why you think BigDecimal.ZERO should be 0.0. Why not 0.00 or 0.000?

    The advantage of defining BigDecimal.ZERO with scale 0 is that it is up to the developer to set the scale that is needed. For example you can always construct a BigDecimal of value 0 with a different scale:

    BigDecimal zero = BigDecimal.ZERO.setScale(2);
    

    Scale 0 provides a good default value and adheres with the principle of least astonishment.

    Let's admit for a second that BigDecimal.ZERO was defined as 0.0. Consider the following code:

    BigDecimal b = new BigDecimal("20");
    BigDecimal b2 = new BigDecimal("20").add(BigDecimal.ZERO);
    System.out.println(b.equals(b2)); // false ??? since when 20 != 20 + 0 ??
    

    b and b2 would not be equal (as per BigDecimal.equals) because they would have different scale: b would have a scale of 0 and b2 would have a scale of 1 (because add returns a BigDecimal whose scale is the max of the two BigDecimals scale).