Reputation: 6166
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
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
Reputation: 7505
if (fValue.CompareTo(float.NaN) == 0)
Note: I know, the thread is dead.
Upvotes: 1
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