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
{
}
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
{
}
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.
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.
if(float.isNaN(fValue))
{
}