BigDecimal.equals(Object) compares both the numerical value and the scale of the BigDecimal objects.

Why is this an issue?

In Java, BigDecimal.equals(Object) returns true only if two BigDecimal objects have the same numerical value and the same scale (number of digits to the right of the decimal point). Consequently, new BigDecimal("2.0").equals(new BigDecimal("2.00")) evaluates to false even though both instances represent the same numerical value.

In financial, commerce, and scientific applications, comparisons usually intend to verify numerical equivalence regardless of representation differences. Using equals() or Objects.equals() can introduce subtle bugs when values are formatted, serialized, or computed with different scale factors. To compare BigDecimal values for numerical equality, use compareTo(other) == 0 instead.

Code examples

Noncompliant code example

BigDecimal priceA = new BigDecimal("10.0");
BigDecimal priceB = new BigDecimal("10.00");

if (priceA.equals(priceB)) { // Noncompliant: "BigDecimal.equals()" compares scale as well as value; use "compareTo() == 0" for numerical comparison
  applyDiscount();
}

Compliant solution

BigDecimal priceA = new BigDecimal("10.0");
BigDecimal priceB = new BigDecimal("10.00");

if (priceA.compareTo(priceB) == 0) {
  applyDiscount();
}

Exceptions

This rule ignores BigDecimal.equals() calls inside equals(Object) method declarations. Classes implementing equals(Object) and hashCode() often require scale-sensitive comparison to satisfy the hashCode contract.

If scale-sensitive equality is intentionally desired in other contexts, suppress the issue with an inline // NOSONAR comment and provide a short rationale explaining why scale sensitivity is necessary (e.g., // NOSONAR: scale-sensitive comparison is intentional).

Resources

Documentation