我在代码中偶然发现了.NET对double.NaN的定义:
public const double NaN = (double)0.0 / (double)0.0;在PositiveInfinity和NegativeInfinity中也是这样做的。
double.IsNaN (去掉一些#编译指示和注释)定义为:
[Pure]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static bool IsNaN(double d)
{
if (d != d)
{
return true;
}
else
{
return false;
}
}这对我来说是非常违反直觉的。
为什么NaN被定义为被零除?0.0 / 0.0是如何在“幕后”表示的?为什么在double中可以被0整除,为什么NaN != NaN
发布于 2010-12-26 03:47:03
这里的答案相当简单。.Net框架已经实现了IEEE (System.Double complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic.)制定的浮点标准。这是因为浮点运算实际上必须在许多系统上工作,而不仅仅是x86/64体系结构,所以通过遵循约定,这将确保将有较少的兼容性问题(例如,将代码从DSP移植到x86处理器)。
至于d != d,这是一个性能优化。基本上,该指令依赖于硬件指令,该指令可以非常快速地确定两个双精度浮点数是否相等。在标准下,NAN != NAN因此是最快的测试方式。我想给你找个推荐人。
发布于 2010-12-26 04:14:48
为什么NaN被定义为被零除?为什么在双精度中可以被0整除,为什么NaN != NaN?
所有这些都是由IEEE 754 standard强制执行的,几乎所有现代CPU都是这样实现的。
0.0 / 0.0是如何在“幕后”表示的?
通过将所有位都设置为1的指数和至少有一位设置为1的尾数。请注意,这意味着有大量不同的位模式都表示NaN -但如上所述,即使位模式相同,也必须认为它们不相等(即==必须返回false)。
发布于 2010-12-26 03:54:41
从C#规范中:
14.9.2浮点比较运算符预定义的浮点比较运算符包括:
布尔运算符==(浮点x,浮点y);布尔运算符==(双x,双y);
布尔运算符!=(浮点x,浮点y);布尔运算符!=(双x,双y);
布尔运算符<(浮点x,浮点y);布尔运算符<(双x,双y);
布尔运算符>(浮点x,浮点y);布尔运算符>(双x,双y);
布尔运算符<=(浮点x,浮点y);布尔运算符<=(双x,双y);
布尔运算符>=(float x,float y);布尔运算符>=(double x,double y);这些运算符根据IEC 60559标准的规则比较操作数:如果任何一个操作数为NaN,则除!=之外的所有运算符的结果均为假,对于!=,结果为真。对于任何两个操作数,,x!=y始终与!(x == y)产生相同的结果。但是,当一个或两个操作数为NaN时,<、>、<=和>=运算符不会产生与相反运算符的逻辑取反相同的结果。例如:如果x和y中的任何一个为NaN,则x= y)为真。结束示例
关于如何在幕后表示NaN,IEEE规范上的wikipedia article有一些示例。
https://stackoverflow.com/questions/4531415
复制相似问题