liveBook · Manning

BigDecimal

As explained in 100 Java Mistakes and How to Avoid Them

BigDecimal is the Java arbitrary-precision decimal numeric class in java.math.

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

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains arbitrary precision, unscaled values, scale, equality behavior, remedies, and an IntelliJ inspection limitation.
Examples
Demonstrates long-to-double precision loss and BigDecimal values constructed from "0" and "0.0".
What it assumes
Assumes Java object comparison and floating-point knowledge while explaining BigDecimal representation from its unscaled value and scale.
What you can do after
Diagnose scale-sensitive equality and choose compareTo() or stripTrailingZeros() for the intended comparison.
How it connects
Connects decimal precision with floating-point widening, equals(), compareTo(), scale, stripTrailingZeros(), and static analysis.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.