Stuff that's in my head

Can open... Worms? everywhere! The blog of Colin Angus Mackay
posts - 375, comments - 482, trackbacks - 67

Tip of the Day #16: NaN (Not a Number)

The Issue

If you want to detect if a double (System.Double) or float (System.Single) is “not a number” or NaN you cannot use something like this:

if (myDouble == double.NaN) { /* do something */ }

It will always be false.

Sounds crazy? Try this:

double myDouble = double.NaN;
Console.WriteLine("myDouble == double.NaN : {0}", myDouble == double.NaN);

The result is:

myDouble == double.NaN : False

You can see that myDouble was explicitly set the value of double.NaN, yet in the next line it is returning false.

The Solution

If you want to test for a floating point value being Not a Number you to use IsNan() which is a static method on System.Double and System.Single. Here is the first example re-written to use the static method. It will now work correctly:

if (double.IsNan(myDouble) { /* do something */ }

If we re-write our other example:

double myDouble = double.NaN;
Console.WriteLine("double.IsNaN(myDouble) : {0}", double.IsNaN(myDouble));

We get the expected result too:

double.IsNaN(myDouble) : True

The Reason

According to Wikipedia: In computing, NaN, which stands for Not a Number, is a value or symbol that is usually produced as the result of an operation on invalid input operands, especially in floating-point calculations. For example, most floating-point units are unable to explicitly calculate the square root of negative numbers, and will instead indicate that the operation was invalid and return a NaN result. NaNs may also be used to represent missing values in computations.

It goes on to say: A NaN does not compare equal to any floating-point number or NaN, even if the latter has an identical representation. One can therefore test whether a variable has a NaN value by comparing it to itself, thus if x = x gives false then x is a NaN code.

This is why (double.NaN == double.NaN) always results in false. And it is also how the .NET framework detects the NaN value in the IsNan() method.

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

Print | posted on Saturday, September 12, 2009 12:21 PM

Feedback

Gravatar

# re: Tip of the Day #16: NaN (Not a Number)

As a side note, it seems as if the implementation of Double.IsNaN has changed to .NET Framework 3.5. It now returns ((d >= 0.0) && (d < 0.0)); I sort of like the wierdness of the code around this.
9/12/2009 5:57 PM | Fredrik Mörk
Gravatar

# re: Tip of the Day #16: NaN (Not a Number)

Are you sure? mscorlib for .NET 3.5 is still the same as .NET 2.0. There are only some bug fixes in it. The code for the IsNaN() method in my post was extracted using .NET Reflector and I'm running .NET 3.5. I also checked the .NET 4.0 assemblies, which is the first new version of mscorlib since .NET 2.0, and the code is the same.
9/12/2009 6:22 PM | Colin Angus Mackay
Gravatar

# re: Tip of the Day #16: NaN (Not a Number)

This is a very simple, structured and lucid explanation Colin - high fives to you.
I have posted a link to this article on my blog. Hope its fine with you.
http://theincorrigibleprotege.blogspot.com/2009/09/when-xx-is-false.html
9/21/2009 1:37 AM | Giriraj Daga

Post Comment

Title  
Name  
Email
Url
Comment   

Powered by: