Anthony Brien
Anthony Brien

Reputation: 6166

How can I compare a float to NaN if comparisons to NaN always return false?

I have a float value set to NaN (seen in the Watch Window), but I can't figure out how to detect that in code:

if (fValue == float.NaN) // returns false even though fValue is NaN
{
}

Upvotes: 56

Views: 48122

Answers (5)

Dmitry Fedorkov
Dmitry Fedorkov

Reputation: 4419

In performance-critical code float.IsNaN could be too slow because it involves FPU. In that case you can use binary mask check (according to IEEE 754 specification) as follow:

public static unsafe bool IsNaN (float f)
{
    int binary = *(int*)(&f);
    return ((binary & 0x7F800000) == 0x7F800000) && ((binary & 0x007FFFFF) != 0);
}

It is 5 times faster than float.IsNaN. I just wonder why Microsoft did not implement IsNaN in such way. If you'd prefer not using unsafe code you still can use union-like structure:

[StructLayout (LayoutKind.Explicit)]
struct FloatUnion
{
    [FieldOffset (0)]
    public float value;

    [FieldOffset (0)]
    public int binary;
}

public static bool IsNaN (float f)
{
    FloatUnion union = new FloatUnion ();
    union.value = f;

    return ((union.binary & 0x7F800000) == 0x7F800000) && ((union.binary & 0x007FFFFF) != 0);
}

It's still 3 times faster than IsNaN.

Upvotes: 17

Tipx
Tipx

Reputation: 7505

if (fValue.CompareTo(float.NaN) == 0)

Note: I know, the thread is dead.

Upvotes: 1

John Feminella
John Feminella

Reputation: 311476

You want float.IsNaN(...). Comparisons to NaN always return false, no matter what the value of the float is. It's one of the quirks of floating points.

That means you can do this:

if (f1 != f1) { // This conditional will be true if f1 is NaN.

In fact, that's exactly how IsNaN() works.

Upvotes: 114

Jeff Mc
Jeff Mc

Reputation: 3793

if(float.isNaN(fValue))
{
}

Upvotes: 8

Jakob Christensen
Jakob Christensen

Reputation: 14956

Try this:

if (float.IsNaN(fValue))
{
}

Upvotes: 39

Related Questions