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

2
불행하다고 생각하는 것은 맥락이 사라 졌다는 것입니다. 두 개의 double이 있고 실제 값 1/0을 나타 내기 위해 둘 다 NaN 값이 할당 된 경우. 그들은 동일해야하지만, 상황이 손실되기 때문에, 그들은하지 동일하게 처리하고
마이클 메도우

13
수학적으로 정확합니다. 왜 하나의 난이 다른 난과 같을 것이라고 생각할까요? sqrt (-1)! = 1/0
Gordon Gustafson

2
그것은 단지처럼 NULLSQL에서
shashwat

2
@MichaelMeadows 1/0은 NaN이 아니라 Inf입니다.
Jim Balter 2014-06-05

답변:


133

궁금하다면 Double.IsNaN다음과 같습니다.

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

펑키?


11
이상하네요. 그러나 다시 NaN의 선언은 다음과 같습니다.public const double NaN = (double) 1.0 / (double) 0.0;
Fredrik Mörk

5
@Fredik, @Erich : 0으로 나누면 inf (또는 피연산자를 기반으로하는 + inf, -inf), 0/0 (다른 것들 중에서) 결과는 NaN입니다. steve.hollasch.net/cgindex/coding/ieeefloat.html에
Torsten Marek

5
혼란을 더하기 위해 object.Equals (double.NaN, double.NaN)은 true를 반환합니다.
Román

2
@JimBalter 내 의견이 틀렸다는 것이 맞습니다. 참조 소스가 실제로 public const double NaN = (double)0.0 / (double)0.0; 참조 소스에 대한 링크를 말하는 것 입니다. 지적 해 주셔서 감사합니다. 또 다른 메모에서 : 잘못되고 거짓말을하는 것은 두 개의 완전히 다른 것들
프레드릭 Mörk은

1
게시했을 때 이것이 올바른지 확실하지 않지만 IsNaN은 오늘날 다르게 정의 됩니다.
Joe Amenta



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

Equality 연산자는 두 개의 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.