JDK-8257086 : Clarify differences between {Float, Double}.equals and ==
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 16
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-11-25
  • Updated: 2022-09-28
  • Resolved: 2021-02-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17
17 b08Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
The equals methods on Float and Double are *not* just wrappers around the corresponding == operator because the IEEE 754 == operator does *not* define an equivalence relation. The properties of an equivalence relation are broken by NaN (since NaN is not equal to itself) and by -0.0/+0.0. While -0.0 and +0.0 compare as equal, they are distinct values that can change the value of a result of an operation; for example, +1.0/+0.0 is positive infinity while +1.0/-0.0 is negative infinity.

This situation could be more clearly motivated than the oblique "This definition allows hash tables to operate properly." statement equals methods.
Comments
Changeset: 474dba2d Author: Joe Darcy <darcy@openjdk.org> Date: 2021-02-02 02:33:56 +0000 URL: https://git.openjdk.java.net/jdk/commit/474dba2d
02-02-2021

Some additional notes that might be useful in improving the specification. As Joe noted, an equivalence relation includes reflexivity: a value must be equal to itself. The Object.equals contract requires reflexivity, which is violated by NaN and ==. For the +0.0 and -0.0 case, the issue is that Object.hashCode's contract requires that equal objects have the same hashCode. In IEEE 754 +0.0 == -0.0 but the boxed values have different hash codes. One could attempt to fix this by making their hash codes equal, as Joe noted there some operations on them that give different results, so it's more sensible that +0.0 and -0.0 not be considered equal by the equals() method.
25-11-2020