因此,如果反编译.net源代码,则可以找到此代码
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SecuritySafeCritical]
[__DynamicallyInvokable]
public static unsafe bool IsNaN(double d)
{
return (ulong) (*(long*) &d & long.MaxValue) > 9218868437227405312UL;
}
所以根据IEEE754 NaN != NaN
所以问题很简单:为什么看起来不像
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SecuritySafeCritical]
[__DynamicallyInvokable]
public static unsafe bool IsNaN(double d)
{
return d != d;
}
我的朋友告诉我,==
可能是return !IsNan(this) && this.InnerEquals(other);
但是NaN的afaik实现是在处理器本身的硬件层上进行硬编码的。而且我们不应该NaN
单独处理案件。
还有一个问题。为什么这么傻?
bool b1 = (double.NaN == double.NaN); // false
bool b2 = double.NaN.Equals(double.NaN); //true
我知道一个实现
[__DynamicallyInvokable]
public override bool Equals(object obj)
{
if (!(obj is double))
return false;
double d = (double) obj;
if (d == this)
return true;
if (double.IsNaN(d))
return double.IsNaN(this);
else
return false;
}
但是不知道为什么
在IEEE754中,对NaN值进行编码,使其符号位为0
或,1
并且所有1
位的指数部分。小数部分中的值无关紧要,只要它们不是所有0
位即可(如果是,则是无穷大之一,而不是NaN)。
因此,请考虑32位单精度浮点数:
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
x 11111111 ???????????????????????
我已使用m
(尾数表示)上面的分数位,以免将其与十六进制数字混淆f
。
如果不是所有这些?
位都为零,则为NaN编码之一。如果将其强制转换为32位长,则检查二进制文件很简单:
x 11111111 00000000000000000000000
并且,如果它大于正变体或小于负变体,则为NaN编码之一。
忽略了该&
操作正在执行的符号,因为带符号的long.MaxValue
将是2^63 - 1
(假设是64位),因此该操作只会将最高有效位强制为0
。
魔术值是由一个0
符号位,所有1
位的指数构成的(对于双精度,其中有11个以及0
分数中的所有位。因此为二进制:
seee eeee eeee mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
0111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
给0x7ff0000000000000
或9218868437227405312
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句