- A Concurrent Affair - https://www.concurrentaffair.org -

Double.equals for NaN and -0.0

I just fixed two bugs in DrJava [1] that had to do with boxed floating-point comparisons of NaN [2] and -0.0 [3].

Both bugs had the same cause, a difference between the behavior of primitive == and the equals [4] method in Double and Float.

According to IEEE 754, any NaN isn’t equal to anything, not even itself. Therefore, Double.NaN==Double.NaN should evaluate to false. On the other hand, positive and negative zero are the same (even though they have different encodings), so 0.0==-0.0 should evaluate to true. This is the case for the primitive types double and float, but not for the boxed types Double and Float.

This may be surprising, but the boxed types had additional contracts to fulfill regarding the behavior of equals and hashCode in hash tables. It was decided that it was more important to successfully look up floating-point values in hash tables, so new Double(Double.NaN).equals(new Double(Double.NaN)) returns true, and new Double(0.0).equals(new Double(-0.0)) returns false. Try it.

In Dynamic Java, the interpreter in DrJava, we internally used boxed types when comparing primitives, just because that way, we could write the equals method more easily. Now I created special cases for floating-point numbers that unboxes the values and eschews the equals [4] method.

[5] [6]Share [7]