Почему double.NaN не равен себе? - PullRequest
80 голосов
/ 18 июля 2009

Может кто-нибудь объяснить это мне? В 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 и получить истину?

Ответы [ 11 ]

130 голосов
/ 18 июля 2009

Если вам интересно, вот как выглядит Double.IsNaN:

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

Фанки, да?

44 голосов
/ 18 июля 2009

Использование Double.IsNaN .

15 голосов
/ 18 июля 2009
bool isNaN = Double.IsNaN(yourNumber)
10 голосов
/ 18 июля 2009

Поведение нарочно. Причина в том, что NaN представляет собой нечто такое, что не является числом , и, таким образом, для многих это своего рода ловушка.

Правильный способ сравнить что-то с NaN - использовать функцию IsNaN .

7 голосов
/ 18 июля 2009

Используйте Double.IsNan () , чтобы проверить равенство здесь. Причина в том, что NaN не число.

6 голосов
/ 18 июля 2009

Для этого есть специальная функция:

double.IsNan(huh);
5 голосов
/ 18 июля 2009

Используйте метод "Double.IsNaN (значение)" для проверки этого условия.

3 голосов
/ 18 июля 2009

На самом деле, вы уже нашли способ проверить, является ли число с плавающей запятой IEEE-754 NaN : это единственное значение с плавающей запятой (или диапазон значений, поскольку существует несколько NaN), которое оценивает до False по сравнению с самим собой, то есть:

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

Под капотом метод Double.IsNaN может фактически сделать то же самое. Вы должны все еще использовать это, потому что поведение весьма удивительно для любого, кто не знает о стандарте FP.

2 голосов
/ 18 ноября 2015

Оператор равенства считает, что два значения NaN не равны друг другу. В общем, операторы Double нельзя использовать для сравнения Double.NaN с другими значениями Double, хотя методы сравнения (такие как равно и CompareTo ) могут использоваться. см. ниже примеры

Ссылка от 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 fiddle для того же.

2 голосов
/ 11 марта 2014

Причина 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...