commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Cyrille Artho <>
Subject [math] Issue with equals/hashCode on Complex/Dfp instances
Date Mon, 14 Apr 2014 23:03:51 GMT
Dear all,
Java's default contract (in Object) states that two objects with equal data 
should return the same hashCode. In other words, if a.equals(b), their 
return value of hashCode() must be the same.

Unfortunately, with Double values, new Double(0.0d).equals(new 
Double(-0.0d)) is false. This is because their internal representation 
differs. Java's built-in Double thus returns a different hashCode for 0.0d 
and -0.0d.

However, Apache's math library uses a mathematical comparison for 
Complex/Dfp (perhaps also others), where 0.0d == -0.0d. This breaks the 
contract, and thus causes problems when Complex or Dfp instances are used 
in containers such as HashMap, HashSet, etc. See the bug report for more 
details and test cases:

It is not quite clear how this should be fixed. Gilles posted a patch that 
uses Java's equals to perform the comparison. This fixes the behavior 
w.r.t. the contract but may surprise people who expect a mathematical 

Another possible fix (without a tentative patch at this time) would be to 
change hashCode:

     public int hashCode() {
         if (imaginary == 0.0d && real == 0.0d) {
             return ZERO.hashCode();

and similar for Dfp.

This fixes the issue for zero values. However, there may be issues with 
normalized vs. unnormalized floating point values with the same 
(mathematical) value but different internal representations, where this 
kind of fix cannot be used. I'm not familiar enough with various floating 
point implementations to know if Java always normalizes the values before 
using them in a statement like hashCode().

Therefore, the suggestion above is mathematically nice for +/- 0.0d, but 
otherwise much less safe than Gilles' patch.

Any comments? Probably best post them on JIRA:
Cyrille Artho -
Better once than never, for never too late.
		-- Shakespeare, "The Taming of the Shrew"

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message