Double.NaN neden kendisine eşit değil?


82

Biri bunu bana açıklayabilir mi? C # 'da double.NaN double'a eşit değildir.

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

Double.NaN ile hangi sabiti karşılaştırabilirim ve doğru alabilirim?


12
Sadece huh'larınızı açıklamak için: NaN hiçbir şeye eşittir, kendisi bile. Bu tanım gereğidir. en.wikipedia.org/wiki/NaN
Falaina

2
Talihsiz olduğunu düşündüğüm şey, bağlamın kaybolması. İki çiftimiz olsaydı ve her ikisine de 1/0 gerçek değerini temsil etmek için bir NaN değeri atanırdı. Eşit olmalılar, ancak bağlam kaybolduğu için eşit değillermiş gibi davranılıyor
Michael Meadows

13
matematiksel olarak doğru. Neden biri bir nananın diğerine eşit olacağını düşünür? sqrt (-1)! = 1/0
Gordon Gustafson

2
Sadece gibidir NULLSQL
Shashwat

2
@MichaelMeadows 1/0 Inf, NaN değil.
Jim Balter

Yanıtlar:


134

Merak ediyorsanız, Double.IsNaNşuna benziyor:

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

Funky, ha?


11
Bu çok tuhaf. Ama public const double NaN = (double) 1.0 / (double) 0.0;
NaN'nin

5
@Fredik, @Erich: Sıfıra bölme inf (veya, işlenenlere göre + inf, -inf) verir, 0/0 (diğerleri arasında) bir NaN ile sonuçlanır. En özel harekat / sonuçlarla güzel masa olacak steve.hollasch.net/cgindex/coding/ieeefloat.html
Torsten Marek

5
Karışıklığı arttırmak için object.Equals (double.NaN, double.NaN) true değerini döndürür
Román

2
@JimBalter Yorumumun yanlış olduğu konusunda haklısınız: referans kaynağı aslında referans kaynağına public const double NaN = (double)0.0 / (double)0.0; bağlantı söylüyor . Bunu belirttiğiniz için teşekkürler. Başka bir not: yanlış ve yalan tamamen farklı iki şey
Fredrik Mörk

1
Bunu yayınladığınızda bunun doğru olup olmadığından emin değilim, ancak IsNaN bugün farklı tanımlandı .
Joe Amenta



10

Davranış kasıtlıdır. NaN olmanın nedeni, sayı olmayan bir şeyi temsil ediyor ve bu yüzden bu, birçok şey için bir nevi her şeyi kapsıyor.

Bir şeyi NaN olmakla karşılaştırmanın doğru yolu, IsNaN işlevini kullanmaktır .



6

Bunun için özel bir işlev var:

double.IsNan(huh);

5

Bu koşulu kontrol etmek için "Double.IsNaN (değer)" yöntemini kullanın.


3

Aslında, bir IEEE-754 kayan nokta sayısının NaN olup olmadığını kontrol etmenin bir yolunu buldunuz : Falsekendisi ile kıyaslandığında değerlendiren tek kayan nokta değeridir (veya birkaç NaN olduğu için değerler aralığı) , yani:

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

Başlık altında, Double.IsNaN yöntemi aslında aynı şeyi yapabilir. Yine de kullanmalısınız, çünkü bu davranış FP standardını bilmeyenler için oldukça şaşırtıcıdır.


2

NaN hakkında bildiğimiz tek şey "Sayı Değil" olduğudur. Bu, durumuyla ilişkilendirilebilecek bir değere sahip olduğu anlamına gelmez. Örneğin:

∞ + (-∞) = NaN

0/0 = NaN

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

İşte göstermek için bazı 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

Nedeni Double.NaN != Double.NaNbasit:

0/0Aynı olmasını Math.Sqrt(-3)mı bekliyorsunuz ? Ve aynı Math.Sqrt(-7)?

Bence Equals()NaN için geçersiz kılınmayan bir C # hatası var .

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

Aynı zamanda

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

Statik işlevleri Doubleve için kullanın Single, örneğin

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

Veya daha spesifik:

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

2

Eşitlik operatörü, iki NaN değerinin birbirine eşit olmadığını düşünür. Genel olarak, Double.NaN'yi diğer Double değerleriyle karşılaştırmak için Double operatörleri kullanılamaz, ancak karşılaştırma yöntemleri ( Equals ve CompareTo gibi ) yapabilir. aşağıdaki örneklere bakın

Msdn'den referans alınmıştır

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");
        }
    }
}

işte aynı .net keman.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.