为什么double.NaN不等于自身?


82

谁可以给我解释一下这个?在C#中double.NaN不等于double.NaN

bool huh = double.NaN == double.NaN; // huh = false
bool huh2 = double.NaN >= 0; // huh2 = false
bool huh3 = double.NaN <= 0; // huh3 = false

我可以将哪个常量与double.NaN进行比较,然后得出真值?


12
只是为了解释一下,NaN等于空,甚至不等于空。这是根据定义。en.wikipedia.org/wiki/NaN
法莱纳

2
我认为不幸的是上下文丢失了。如果我们有两个双精度数,并且都为它们分配了NaN值,以表示实际值1/0。它们应该相等,但是由于上下文丢失,它们被视为不相等
Michael Meadows

13
数学上正确。为什么一个人会认为一个nan等于另一个?sqrt(-1)!= 1/0
Gordon Gustafson 2009年

2
就像NULL在SQL中一样
shashwat

2
@MichaelMeadows 1/0是Inf,而不是NaN。
Jim Balter 2014年

Answers:


133

如果您很好奇,这是Double.IsNaN这样的:

public static bool IsNaN(double d)
{
    return (d != d);
}

时髦,是吗?


11
那就好奇怪了。但是话又说回来,NaN的声明也是如此:public const double NaN = (double) 1.0 / (double) 0.0;
FredrikMörk09年

5
@ Fredik,@ Erich:除以零将得出inf(或+ inf,-inf基于操作数),0/0(以及其他)结果为NaN。有与特种作战/结果一个不错的表steve.hollasch.net/cgindex/coding/ieeefloat.html
托斯滕马立克

5
为了增加混乱,的Object.Equals(double.NaN,double.NaN)返回true
罗曼

2
@JimBalter是正确的,我的评论是错误的:参考源实际上是在说到public const double NaN = (double)0.0 / (double)0.0; 参考源的链接。感谢您指出了这一点。另一个需要注意的是:错误和说谎是两件完全不同的事情
FredrikMörk2014年

1
不确定在发布时是否正确,但是今天对IsNaN的定义有所不同
Joe Amenta



10

该行为是故意的。NaN之所以表示不是数字的事物,许多事物的全部。

将某物与NaN进行比较的正确方法是使用IsNaN函数。




5

使用方法“ Double.IsNaN(value)”检查这种情况。


3

实际上,您已经找到了一种检查IEEE-754浮点数是否为NaN的方法:它是唯一与之比较的浮点值(或值的范围,因为有多个NaN)False,即:

bool isNaN(double v) {
    return v != v;
}

实际上,Double.IsNaN方法实际上可以做同样的事情。您仍然应该使用它,因为这种行为对于任何不了解FP标准的人来说都是非常令人惊讶的。


2

我们对NaN唯一了解的是“不是数字”。这并不意味着它具有与其状态相关联的值。例如:

∞+(-∞)= NaN

0/0 = NaN

(∞+(-∞))<>(0/0)

这是一些C#演示

var infinity = 100d / 0;
var negInfinity = -100d / 0;

var notANumber = infinity + negInfinity;
Console.WriteLine("Negative Infinity plus Infinity is NaN: {0}", double.IsNaN(notANumber));

var notANumber2 = 0d / 0d;
Console.WriteLine("Zero divided by Zero is NaN: {0}", double.IsNaN(notANumber2));

Console.WriteLine("These two are not equal: {0}", notANumber == notANumber2);

2

的原因Double.NaN != Double.NaN很简单:

您期望0/0与之相同Math.Sqrt(-3)吗?和一样Math.Sqrt(-7)吗?

我认为C#中存在一个错误,在该错误中Equals()NaN不会被覆盖。

Assert.IsTrue(Double.NaN != Double.NaN);
Assert.IsTrue(Double.NaN.Equals(Double.NaN));

同时

Assert.IsTrue(Double.PositiveInfinity == Double.NegativeInfinity);
Assert.IsTrue(Double.PositiveInfinity.Equals(Double.PositiveInfinity));
// same for Double.NegativeInfinity and Single

Double和使用静态函数Single,例如

Double.IsNaN(value) && Double.IsInfinity(value);

或更具体:

Double.IsPositiveInfinity(value);
Double.IsNegativeInfinity(value);

2

相等运算符认为两个NaN值彼此不相等。通常,尽管可以使用比较方法(例如EqualsCompareTo),但Double运算符不能用于将Double.NaN与其他Double值进行比较。见下面的例子

msdn引用

class Program
{
    static void Main(string[] args)
    {
        Double i = Double.NaN;
        while (!i.Equals(i)) //this would be result in false
        //while(i != i) // this would result in true.
        {
            Console.WriteLine("Hello");
        }
    }
}

是.net小提琴一样。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.