Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing Double.NaN with itself

Tags:

c#

.net

double

nan

I am stuck trying to find out why these two operations return different values:

  1. Double.NaN == Double.NaN returns false
  2. Double.NaN.Equals(Double.NaN) returns true

I have the answer to the first part but not the second and not to "why are these two comparisons returning different values"

like image 890
GETah Avatar asked Jan 22 '13 12:01

GETah


People also ask

Can you compare NaN?

Unlike all other possible values in JavaScript, it is not possible to use the equality operators (== and ===) to compare a value against NaN to determine whether the value is NaN or not, because both NaN == NaN and NaN === NaN evaluate to false . The isNaN() function provides a convenient equality check against NaN .

What is Double NaN?

public static final double NaN. A constant holding a Not-a-Number (NaN) value of type double . It is equivalent to the value returned by Double.

What does Double NaN return?

All numeric operations with NaN as an operand produce NaN as a result. Reason behind this is that NaN is unordered, so a numeric comparison operation involving one or two NaNs returns false.


2 Answers

The reason for the difference is simple, if not obvious.

If you use the equality operator ==, then you're using the IEEE test for equality.

If you're using the Equals(object) method, then you have to maintain the contract of object.Equals(object). When you implement this method (and the corresponding GetHashCode method), you have to maintain that contract, which is different from the IEEE behaviour.

If the Equals contract was not upheld, then the behaviour of hash tables would break.

var map = new Dictionary<double,string>(); map[double.NaN] = "NaN"; var s = map[double.NaN]; 

If !double.NaN.Equals(double.NaN), you'd never get your value out of the dictionary!

If the previous sentence does not make sense, then understand that the mechanics of hashing (used in Dictionary<T,U>, HashSet<T>, etc) use both the object.Equals(object) and object.GetHashCode() methods extensively, and rely upon guarantees of their behaviour.

like image 199
Drew Noakes Avatar answered Sep 17 '22 13:09

Drew Noakes


At the very bottom of the remarks section of Double.Equals, you will find:

If two Double.NaN values are tested for equality by calling the Equals method, the method returns true. However, if two NaN values are tested for equality by using the equality operator, the operator returns false. When you want to determine whether the value of a Double is not a number (NaN), an alternative is to call the IsNaN method.

like image 39
Oded Avatar answered Sep 21 '22 13:09

Oded