Equals operator for zeros (BigDecimal / Double) in Java
Solution 1
BigDecimal 'equals' compares the value and the scale. If you only want to compare values (0 == 0.0) you should use compareTo:
BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0.0)) == 0 //true
BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0)) == 0 //true
See the javadoc.
As for the Double comparison, as explained by other answers, you are comparing a Double with an Integer in new Double(0.0).equals(0)
, which returns false
because the objects have different types. For reference, the code for the equals method in JDK 7 is:
public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
In your case, (obj instanceof Double)
is false.
Solution 2
The 0 in your first expression is interpreted as an
int
, which may be autoboxed into anInteger
, but not to aDouble
. So the type of the two is different, hence they are not equal. OTOH0.0
is adouble
, which is autoboxed into aDouble
, so the two operands are deemed equal.-
BigDecimals also contain a scale (i.e. number of digits to the right of the decimal separator dot).
BigDecimal.ZERO
has the value of "0", so its scale is 0. Hence it is not equal to "0.0", whose scale is 1.
If you want to compare values, useBigDecimal.compareTo
:BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0.0)) == 0 BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0)) == 0
Solution 3
new Double(0.0).equals(0) is actually boxed as something like this:
new Double(0.0).equals(Integer.valueOf(0))
Double.equals(...) will never return true unless given another Double instance.
Solution 4
new Double(0.0).equals(0); //false
as the argument you passed is integer. and the equels() in Double class checks whether the argument is od instance Double or not using instance of operator.
The Double's equals() method.
if (!(argument instanceof Double))
return false;
The argument you passed is integer, which is not instance of Double, so it returns false.
Manish Mulani
Updated on July 09, 2022Comments
-
Manish Mulani almost 2 years
A few interesting observations w.r.t equals operator on 0 and 0.0
new Double(0.0).equals(0)
returns false, whilenew Double(0.0).equals(0.0)
returns true.BigDecimal.ZERO.equals(BigDecimal.valueOf(0.0))
returns false, whileBigDecimal.ZERO.equals(BigDecimal.valueOf(0))
returns true.
Looks like the string comparison is being done in both the cases. Could anyone throw some light on this.
Thanks.
-
Mosty Mostacho over 10 yearsTransforming a BigDecimal to a double might result in loss of precision and a non-zero but close to zero BigDecimal turned into a Double might become 0. You should compare using the
compareTo
method in BigDecimal