88

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?

Jason Berkan
  • 8,734
  • 7
  • 29
  • 39
Carlo
  • 25,602
  • 32
  • 128
  • 176

11 Answers11

142

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

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

Funky, huh?

Erich Mirabal
  • 9,860
  • 3
  • 34
  • 39
  • 11
    That is weird allright. But then again, so is the declaration of NaN: `public const double NaN = (double) 1.0 / (double) 0.0;` – Fredrik Mörk Jul 17 '09 at 20:18
  • @Fedrik: as funky as this looks, you really should play with imitating that definition. You will get different results if you use double.NaN and double myNaN = (double)1.0 / (double)0.0; as the test (especifically, the former will test as false for IsInfinity and the latter as true!) – Erich Mirabal Jul 17 '09 at 20:28
  • 5
    @Fredik, @Erich: Division by Zero will give inf (or, +inf, -inf based on the operands), 0 / 0 (among others) results in a NaN. There's a nice table with special operations/results at http://steve.hollasch.net/cgindex/coding/ieeefloat.html – Torsten Marek Jul 17 '09 at 20:32
  • @Erick Mirabal: BTW, where did you find out what IsNaN looks like? There's some times I need to see the implementation of certain .net methods. – Carlo Jul 18 '09 at 00:51
  • @Carlo You can use .NET Reflector or use the Microsoft source server when debugging. – Adrian Godong Jul 18 '09 at 21:19
  • @Torsten: yes, I know division by zero gives you Infinity. But what I find funky is that double.NaN is defined as a number divided by zero, yet it fails the IsInfinity test! @Carlo, as Adrian notes, .NET Reflector is what I used. I use it *all* the time to check implementation ideas and details. – Erich Mirabal Jul 18 '09 at 23:11
  • 5
    To add to the confusion, object.Equals(double.NaN, double.NaN) returns true – Román Jan 23 '12 at 10:34
  • @FredrikMörk "so is the declaration of NaN:" -- why lie? This answer gave the actual definition of IsNaN, whereas you just made something up. – Jim Balter Jun 05 '14 at 01:12
  • "double.NaN is defined as a number divided by zero" -- no it isn't. 0/0 has no mathematical meaning and is thus "not a number"; there are many other ways to get "non a number". – Jim Balter Jun 05 '14 at 01:16
  • 3
    @JimBalter You are correct that my comment was wrong: the reference source is actually saying `public const double NaN = (double)0.0 / (double)0.0;` [link to the reference source](http://referencesource.microsoft.com/#mscorlib/system/double.cs#dcd7a869fad1e6bb). Thanks for pointing that out. On another note: being wrong and lying are two completely different things – Fredrik Mörk Jun 05 '14 at 06:04
  • @FredrikMörk As I said, you just made it up; you never saw any such declaration. Therefore it was a lie, not merely wrong. – Jim Balter Jun 05 '14 at 10:08
  • 2
    Not sure if this was correct when you posted it, but IsNaN is [defined differently](https://github.com/dotnet/coreclr/blob/ef1e2ab328087c61a6878c1e84f4fc5d710aebce/src/mscorlib/src/System/Double.cs#L92) today. – Joe Amenta Nov 07 '15 at 11:46
47

Use Double.IsNaN.

Adrian Godong
  • 8,802
  • 8
  • 40
  • 62
17
bool isNaN = Double.IsNaN(yourNumber)
Francis B.
  • 7,018
  • 2
  • 32
  • 54
13

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.

Mike Dinescu
  • 54,171
  • 16
  • 118
  • 151
8

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

Colin Mackay
  • 18,736
  • 7
  • 61
  • 88
7

There's a specialized function for this:

double.IsNan(huh);
arul
  • 13,998
  • 1
  • 57
  • 77
5

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

David
  • 34,223
  • 3
  • 62
  • 80
3

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.

Torsten Marek
  • 83,780
  • 21
  • 91
  • 98
3

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);
Michael Meadows
  • 27,796
  • 4
  • 47
  • 63
2

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);
Artur A
  • 7,115
  • 57
  • 60
2

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.

Jenish Rabadiya
  • 6,708
  • 6
  • 33
  • 62