为什么 double.IsNegative(double.NaN) 返回 true?

12
为什么 double.IsNegative(double.NaN) 意外地返回 true,而 double.NaN < 0 返回预期的 false

请注意,另一个负数,即使 n < 0 返回 false 的数字是 -0.0 - chux - Reinstate Monica
2个回答

12

根据参考资源double.IsNegative只检查最高有效位

    [Pure]
    [System.Security.SecuritySafeCritical]  // auto-generated
    internal unsafe static bool IsNegative(double d) {
        return (*(UInt64*)(&d) & 0x8000000000000000) == 0x8000000000000000;
    }

如果是 double.NaN,则最高有效位 被设置

    11111111 11111000 00000000 00000000 00000000 00000000 00000000 00000000   
    ||           ||                                                       |
    |<-   Exp   -><-                     Mantissa                        ->
    Sign

这就是为什么double.IsNegative返回true的原因。

当我们输入<>时,会使用FPU命令,它们知道所有指数都是特殊类型的浮点值,应该以特殊方式处理。

Single.NaN也是同样的情况。

请注意,我们可以构造另一个奇怪的值,即负零

    10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000   
    ||           ||                                                       |
    |<-   Exp   -><-                          Mantissa                   ->
    Sign
请看:

Please, look:

  double negativeZero = BitConverter.ToDouble(new byte[] { 
    0, 0, 0, 0, 0, 0, 0, 128
  });

  Console.WriteLine(negativeZero == 0 ? "Zero" : "???");

  Console.WriteLine(double.IsNegative(negativeZero) ? "Negative" : "???");

@harold:你说得很对,谢谢!反转的图像不太易读。 - Dmitry Bychenko
1
实际上,所有指数都是全1的才是特殊的吗?例如,所有2的整数次幂,如1.0256.00.25都具有全零尾数和非零指数,它们并不特殊。 - Ben Voigt
@Ben Voigt:谢谢!你说得对,根据IEEE-754标准,所有1的指数都是特殊值。 - Dmitry Bychenko

7

IEEE754 定义了浮点数。最高位用于表示符号,0 表示正数,1 表示负数。

经过一番研究,double.NaN 在二进制中似乎表示为 0xFFF8000000000000(而在代码中则是 0.0 / 0.0)。

double.IsNegative(double d) 只检查最高位,并不进行任何实际的数学运算。因此,NaN 被解释为负值。同时,如果将 double.NaN 用于二进制比较,则始终返回 false:

double.NaN < 0.0  //false
double.NaN > 0.0  //false
double.NaN <= 0.0 //false
double.NaN >= 0.0 //false
double.NaN == 0.0 //false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接