为什么
double.IsNegative(double.NaN)
意外地返回 true
,而 double.NaN < 0
返回预期的 false
?double.IsNegative(double.NaN)
意外地返回 true
,而 double.NaN < 0
返回预期的 false
?根据参考资源,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" : "???");
1.0
、256.0
、0.25
都具有全零尾数和非零指数,它们并不特殊。 - Ben VoigtIEEE754 定义了浮点数。最高位用于表示符号,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
n < 0
返回false
的数字是-0.0
。 - chux - Reinstate Monica