Issue
import java.util.*;
public class MyClass {
public static void main(String args[]) {
Map<Float, Integer> m = new HashMap<>();
m.put(Float.intBitsToFloat(0x7f800001), 1);
m.put(Float.intBitsToFloat(0x7f800002), 2);
System.out.println(m.size());
}
}
Why does the above code return 1
as the size of m
? 0x7f800001
and 0x7f800002
are both NaN float values, but since NaN != NaN
by definition, this should not cause a collision.
The behavior is similar to the documented handling of null
keys in the Java Hashmap, but I can't find anything that indicates that NaN
is handled as null
by HashMap.
Solution
Float.equals(Object)
is documented as:
Compares this object against the specified object. The result is true if and only if the argument is not null and is a
Float
object that represents a float with the same value as the float represented by this object. For this purpose, two float values are considered to be the same if and only if the methodfloatToIntBits(float)
returns the identicalint
value when applied to each.
Now that sounds like different NaN values should be treated as non-equal, but floatToIntBits
documentation includes (emphasis mine):
If the argument is NaN, the result is 0x7fc00000.
In all cases, the result is an integer that, when given to the
intBitsToFloat(int)
method, will produce a floating-point value the same as the argument tofloatToIntBits
(except all NaN values are collapsed to a single "canonical" NaN value).
So basically, Float.equals
(and Float.hashCode
, which also uses floatToIntBits(float)
) treats all NaN values as equal.
Answered By - Jon Skeet Answer Checked By - Katrina (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.