为什么double.IsNegative(double.NaN)返回true?
c#
为什么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最signifucant位设置:
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
敬请期待:
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" : "???");
回答
在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
THE END
二维码