Ale*_*kiy 4 .net c# floating-point double ieee-754
因此,如果反编译.net源代码,您可以找到此代码
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SecuritySafeCritical]
[__DynamicallyInvokable]
public static unsafe bool IsNaN(double d)
{
return (ulong) (*(long*) &d & long.MaxValue) > 9218868437227405312UL;
}
Run Code Online (Sandbox Code Playgroud)
所以根据IEEE754 NaN != NaN
所以问题很简单:为什么它看起来不像
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SecuritySafeCritical]
[__DynamicallyInvokable]
public static unsafe bool IsNaN(double d)
{
return d != d;
}
Run Code Online (Sandbox Code Playgroud)
我的朋友告诉我,实施==可能是return !IsNan(this) && this.InnerEquals(other);
但是NaN的实现在硬件层硬编码,在处理器本身.我们不应该NaN单独处理案件.
还有一个问题.为什么这么愚蠢?
bool b1 = (double.NaN == double.NaN); // false
bool b2 = double.NaN.Equals(double.NaN); //true
Run Code Online (Sandbox Code Playgroud)
我知道一个实现
[__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;
}
Run Code Online (Sandbox Code Playgroud)
但不知道为什么
在IEEE754中,NaN值被编码为具有符号位0或1所有1位的指数部分.分数部分中的值是无关紧要的,只要它们不是所有0位(如果它们是,它是无穷大而不是NaN之一).
因此考虑32位单精度浮点数:
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
x 11111111 ???????????????????????
Run Code Online (Sandbox Code Playgroud)
我已经将m(用于尾数)用于上面的分数位,以免将它与十六进制数字混淆f.
如果并非所有这些?位都为零,则它是NaN编码之一.如果将其转换为32位长,则检查二进制文件是一件简单的事情:
x 11111111 00000000000000000000000
Run Code Online (Sandbox Code Playgroud)
并且,如果它大于正变量或小于负变量,那么这是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
Run Code Online (Sandbox Code Playgroud)
给予0x7ff0000000000000或9218868437227405312.