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
Falaina 2009

2
残念なことに、コンテキストが失われていると思います。2つのdoubleがあり、実際の値1/0を表すために、両方にNaNの値が割り当てられている場合。それらは等しいはずですが、コンテキストが失われるため、等しくないものとして扱われます
Michael Meadows

13
数学的に正しい。なぜあるナンが別のナンと等しいと思うのでしょうか?sqrt(-1)!= 1/0
Gordon Gustafson

2
NULLSQLと同じです
shashwat 2013

2
@MichaelMeadows 1/0はInfであり、NaNではありません。
ジムバルター2014年

回答:


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örk

5
@ Fredik、@ Erich:ゼロ除算はinf(または、オペランドに基づいて+ inf、-inf)を返し、0/0(とりわけ)はNaNになります。steve.hollasch.net/cgindex/coding/ieeefloat.html
Torsten Marek

5
混乱に追加するには、はObject.equals(double.NaN、double.NaN)がtrueを返す
ロマン

2
@JimBalterあなたは私のコメントが間違っていたというのは正しいです:参照ソースは実際public const double NaN = (double)0.0 / (double)0.0; には参照ソースへのリンクを言っています。それを指摘してくれてありがとう。別のノートで:間違っていると横たわっていることは2つの完全に異なるものです
フレドリックモルクは、

1
投稿したときにこれが正しいかどうかはわかりませんが、IsNaNの定義は今日では異なります。
ジョーアメンタ2015年



10

動作は意図的なものです。NaNである理由は、数値はないものを表しているため、多くの場合、それは一種のキャッチオールです。

何かをNaNであると比較する適切な方法は、IsNaN関数を使用することです。



6

これには特別な機能があります:

double.IsNan(huh);

5

メソッド「Double.IsNaN(value)」を使用して、この状態を確認します。


3

実際、IEEE-754浮動小数点数がNaNであるかどうかを確認する方法はすでに見つかりました。これは、Falseそれ自体と比較した場合に評価される唯一の浮動小数点値(または複数のNaNがあるため、値の範囲)です。

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)?と同じ

私の意見でEquals()は、NaNでオーバーライドされないバグがC#にあります。

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

等式演算子は、2つのNaN値が互いに等しくないと見なします。一般に、Double演算子を使用してDouble.NaNを他のDouble値と比較することはできませんが、比較方法(EqualsCompareToなど)は使用できます。以下の例を参照してください

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フィドルです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.