## Details

## Description

Two complex numbers with real/imaginary parts 0.0d but different signs compare as equal numbers. This is according to their mathematical value; the comparison is done via

return (real == c.real) && (imaginary == c.imaginary);

Unfortunately, two Double values do NOT compare as equal in that case, so real.equals(c.real) would return false if the signs differ.

This becomes a problem because for the hashCode, MathUtils.hash is used on the real and imaginary parts, which in turn uses Double.hash.

This violates the contract on equals/hashCode, so Complex numbers cannot be used in a hashtable or similar data structure:

Complex c1 = new Complex(0.0, 0.0);

Complex c2 = new Complex(0.0, -0.0);

// Checks the contract: equals-hashcode on c1 and c2

assertTrue("Contract failed: equals-hashcode on c1 and c2", c1.equals(c2) ? c1.hashCode() == c2.hashCode() : true);

Dfp instances are affected in the same way (-0.0 == 0.0 but their hash code differs).