Why is double.NaN not equal to itself?

C#.Net

C# Problem Overview


Can someone explain this to me? In C# double.NaN is not equal to double.NaN

bool huh = double.NaN == double.NaN; // huh = false
bool huh2 = double.NaN >= 0; // huh2 = false
bool huh3 = double.NaN <= 0; // huh3 = false

What constant can I compare to a double.NaN and get true?

C# Solutions


Solution 1 - C#

If you are curious, this is what Double.IsNaN looks like:

public static bool IsNaN(double d)
{
    return (d != d);
}

Funky, huh?

Solution 2 - C#

Solution 3 - C#

bool isNaN = Double.IsNaN(yourNumber)

Solution 4 - C#

The behavior is on purpose. The reason being NaN represents something that is not a number and so that is sort of a catch-all for many things.

The proper way to compare something to being NaN is to use the IsNaN function.

Solution 5 - C#

Use Double.IsNan() to test for equality here. The reason is that NaN is not a number.

Solution 6 - C#

There's a specialized function for this:

double.IsNan(huh);

Solution 7 - C#

Use the method "Double.IsNaN( value )" to check for this condition.

Solution 8 - C#

Actually, you already found the way to check if a IEEE-754 floating point number is NaN: it is the only floating point value (or range of values, because there are several NaNs) that evaluates to False if compared to itself, i.e. :

bool isNaN(double v) {
    return v != v;
}

Under the hood, the Double.IsNaN method might actually do the same thing. You should still use it, because the behavior is quite surprising to anybody who does not know about the FP standard.

Solution 9 - C#

The only thing that we know about NaN is that it's "Not a Number." That doesn't mean that it has a value that is associable with its state. For example:

∞ + (-∞) = NaN

0/0 = NaN

(∞ + (-∞)) <> (0/0)

Here's some C# to demonstrate

var infinity = 100d / 0;
var negInfinity = -100d / 0;

var notANumber = infinity + negInfinity;
Console.WriteLine("Negative Infinity plus Infinity is NaN: {0}", double.IsNaN(notANumber));

var notANumber2 = 0d / 0d;
Console.WriteLine("Zero divided by Zero is NaN: {0}", double.IsNaN(notANumber2));

Console.WriteLine("These two are not equal: {0}", notANumber == notANumber2);

Solution 10 - C#

The reason of Double.NaN != Double.NaN is simple:

Do you expect 0/0 to be the same as Math.Sqrt(-3)? And same as Math.Sqrt(-7)?

There is a bug in C# in my opinion where Equals() is not overridden for NaN.

Assert.IsTrue(Double.NaN != Double.NaN);
Assert.IsTrue(Double.NaN.Equals(Double.NaN));

At the same time

Assert.IsTrue(Double.PositiveInfinity == Double.NegativeInfinity);
Assert.IsTrue(Double.PositiveInfinity.Equals(Double.PositiveInfinity));
// same for Double.NegativeInfinity and Single

Use static functions for Double and Single, e.g.

Double.IsNaN(value) && Double.IsInfinity(value);

Or more specific:

Double.IsPositiveInfinity(value);
Double.IsNegativeInfinity(value);

Solution 11 - C#

>>The Equality operator considers two NaN values to be unequal to one another. In general, Double operators cannot be used to compare Double.NaN with other Double values, although comparison methods (such as Equals and CompareTo) can. see below examples

Referenced from msdn

class Program
{
    static void Main(string[] args)
    {
        Double i = Double.NaN;
	    while (!i.Equals(i)) //this would be result in false
	    //while(i != i) // this would result in true.
	    {
		    Console.WriteLine("Hello");
	    }
    }
}

here is .net fiddle for the same.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCarloView Question on Stackoverflow
Solution 1 - C#Erich MirabalView Answer on Stackoverflow
Solution 2 - C#Adrian GodongView Answer on Stackoverflow
Solution 3 - C#Francis B.View Answer on Stackoverflow
Solution 4 - C#Mike DinescuView Answer on Stackoverflow
Solution 5 - C#Colin MackayView Answer on Stackoverflow
Solution 6 - C#arulView Answer on Stackoverflow
Solution 7 - C#DavidView Answer on Stackoverflow
Solution 8 - C#Torsten MarekView Answer on Stackoverflow
Solution 9 - C#Michael MeadowsView Answer on Stackoverflow
Solution 10 - C#Artur AView Answer on Stackoverflow
Solution 11 - C#Jenish RabadiyaView Answer on Stackoverflow