如果与NaN的比较总是返回false,我如何比较浮点数到NaN?

Ant*_*ien 39 c#

我有一个浮点值设置为NaN(在监视窗口中看到),但我无法弄清楚如何在代码中检测到:

if (fValue == float.NaN) // returns false even though fValue is NaN
{
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*lla 83

你想要的float.IsNaN(...).NaN无论float的值是什么,比较总是返回false.这是浮点的怪癖之一.

这意味着你可以这样做:

if (f1 != f1) { // This conditional will be true if f1 is NaN.
Run Code Online (Sandbox Code Playgroud)

事实上,这正是IsNaN()的工作原理.

  • 那令人不安:) (43认同)
  • @AntonioCS:不,这是[`IsNaN`](http://msdn.microsoft.com/en-us/library/system.single.isnan.aspx),资本"我".我想你在考虑Javascript的`isNaN`. (6认同)
  • 那么NaN!= NaN? (3认同)
  • f1 != f1 触发警告“与同一变量进行比较;” 所以我只是使用 float.IsNaN,但是我真的想使用 f1 != f1 只是为了迷惑人们。:-) (2认同)

Jak*_*sen 29

试试这个:

if (float.IsNaN(fValue))
{
}
Run Code Online (Sandbox Code Playgroud)


Dmi*_*kov 11

性能关键代码float.IsNaN可能太慢,因为它涉及FPU.在这种情况下,您可以使用二进制掩码检查(根据IEEE 754规范)如下:

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

它比快5倍float.IsNaN.我只是想知道为什么微软没有IsNaN以这种方式实施.如果您不想使用不安全的代码,您仍然可以使用类似union的结构:

[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);
}
Run Code Online (Sandbox Code Playgroud)

它仍然比它快3倍IsNaN.

  • 浮点数据结构在 IEEE 754 中进行了描述,并且与平台无关。此外,在 .NET 中通过二进制比较实现对无穷大的检查,例如`((*((int*) &f)) & 0x7fffffff) == 0x7f800000)`。 (3认同)
  • 浮点_data结构与平台无关,但字节顺序不是. (3认同)
  • 二进制比较是否真的依赖于字节序?二进制掩码中的字节顺序与int值中的字节顺序相同.无论如何,如果微软决定对无穷大使用这种检查,他们可以使用相同的方式进行NaN检查. (2认同)
  • 这就是 double.IsNaN 的工作原理:http://referencesource.microsoft.com/#mscorlib/system/double.cs,101 (2认同)