BigDecimal represents decimal numbers with arbitrary precision. Use it when precision matters more than floating-point performance, and when rounding must be controlled explicitly. section 4.6 section 7.4
Numerically equal does not mean equals() equal
BigDecimal zero1 = new BigDecimal("0"); BigDecimal zero2 = new BigDecimal("0.0"); System.out.println(zero1.equals(zero2)); // false The values have different scales, so equals() compares different representations rather than only numerical value. Use compareTo() when scale is irrelevant. section 7.4
Avoid precision and comparison mistakes with these rules:
- Prefer BigDecimal when rounding can harm correctness; avoid relying on implicit floating-point widening. section 4.6
- Use compareTo() and test for zero when comparing numerical values regardless of scale. section 7.15
- Normalize with stripTrailingZeros() before equals() when representation-sensitive equality is still required. section 7.4
BigDecimal zero1 = new BigDecimal("0");
BigDecimal zero2 = new BigDecimal("0.0");
System.out.println(zero1.scale()); #1
System.out.println(zero2.scale()); #2
System.out.println(zero1.equals(zero2)); #3
Inspect how constructing zero from "0" versus "0.0" changes scale and makes equals() return false. section 7.4
BigDecimal zero1 = new BigDecimal("0").stripTrailingZeros();
BigDecimal zero2 = new BigDecimal("0.0").stripTrailingZeros();
System.out.println(zero1.scale()); #1
System.out.println(zero2.scale()); #2
System.out.println(zero1.equals(zero2)); #3
Inspect how stripTrailingZeros() normalizes both values before equality comparison. section 7.4
