[floating-point] IEEE754 NaN 값에 대해 false를 반환하는 모든 비교의 이론적 근거는 무엇입니까?

NaN 값 비교가 다른 모든 값과 다르게 동작하는 이유는 무엇입니까? 즉, 연산자 ==, <=,> =, <,>와의 모든 비교에서 하나 또는 두 값이 모두 NaN이면 다른 모든 값의 동작과 반대로 false를 반환합니다.

나는 이것이 어떤 식 으로든 수치 계산을 단순화한다고 생각하지만 Kahan 의 IEEE 754 상태 에 관한 강의 노트 조차도 다른 설계 결정에 대해 자세히 설명 하지 않는 명백한 이유를 찾을 수 없었습니다 .

이탈 한 동작은 간단한 데이터 처리를 수행 할 때 문제를 일으 킵니다. 예를 들어 C 프로그램에서 일부 실제 필드를 사용하여 레코드 목록을 정렬 할 때 NaN을 최대 요소로 처리하기 위해 추가 코드를 작성해야합니다. 그렇지 않으면 정렬 알고리즘이 혼란 스러울 수 있습니다.

편집 :
지금까지의 대답은 NaN을 비교하는 것이 의미가 없다고 주장합니다.

동의하지만 그렇다고해서 정답이 거짓임을 의미하는 것은 아니며 부울이 아님 (NaB) 일 것입니다.

따라서 비교를 위해 true 또는 false를 반환하는 선택은 임의의 견해이며 일반적인 데이터 처리의 경우 일반적인 법칙 (= = 반사율, <, ==,>의 트리 코미 네이션)을 준수하면 데이터 구조가 가장 유리합니다. 이 법에 의존하는 것은 혼란스러워집니다.

그래서 나는 철학적 추론뿐만 아니라 이러한 법을 어기면 어떤 구체적인 이점을 요구하고 있습니다.

편집 2 :
NaN을 최대로 만드는 것이 나쁜 생각이되는 이유를 이해한다고 생각합니다. 상한값 계산을 망칠 것입니다.

NaN! = NaN은 다음과 같은 루프에서 수렴을 감지하지 않기 위해 바람직 할 수 있습니다.

while (x != oldX) {
    oldX = x;
    x = better_approximation(x);
}

그러나 절대 차이를 작은 한계와 비교하여 더 잘 작성해야합니다. 따라서 IMHO는 NaN에서 반사성을 깨뜨리기위한 비교적 약한 주장입니다.



답변

저는 IEEE-754위원회의 일원이었습니다. 일을 좀 더 명확하게하려고 노력할 것입니다.

먼저 부동 소수점 숫자는 실수가 아니며 부동 소수점 산술은 실제 산술의 공리를 만족시키지 않습니다. Trichotomy는 수레뿐만 아니라 가장 중요하지 않은 실제 산술의 유일한 속성은 아닙니다. 예를 들면 다음과 같습니다.

  • 덧셈은 연관성이 없습니다.
  • 분배 법은 유지하지 않습니다.
  • 역수가없는 부동 소수점 숫자가 있습니다.

계속할 수있었습니다. 우리가 알고 사랑하는 실제 산술의 모든 속성 을 만족시키는 고정 크기 산술 유형을 지정할 수 없습니다 . 754위원회는 그들 중 일부를 구부리거나 파기로 결정해야합니다. 이것은 매우 간단한 원칙에 의해 안내됩니다.

  1. 우리가 할 수있을 때, 우리는 실제 산술 행동과 일치합니다.
  2. 우리가 할 수 없을 때, 우리는 위반을 예측 가능하고 진단하기 쉬운 것으로 만들려고 노력합니다.

“정답이 거짓이라는 의미는 아닙니다”라는 귀하의 의견과 관련하여 이것은 잘못된 것입니다. 술어 가보다 작은 (y < x)지 묻습니다 . 경우 NaN이입니다, 다음은 하지 부동 소수점 값보다 적은 답은 반드시 거짓 있도록.yxyx

나는 trichotomy가 부동 소수점 값을 유지하지 않는다고 언급했습니다. 그러나 유사한 속성이 있습니다. 754-2008 표준의 조항 5.11, 단락 2 :

4 가지 상호 배타적 인 관계가 가능합니다. 마지막 경우는 하나 이상의 피연산자가 NaN 일 때 발생합니다. 모든 NaN은 비 순차적 자체를 포함하여 모든 것을 비 교해야한다.

NaN을 처리하기 위해 추가 코드를 작성하는 한 NaN이 제대로 빠져 나가는 방식으로 코드를 구성하는 것이 가능하지만 항상 쉬운 것은 아니지만 항상 그런 것은 아닙니다. 그렇지 않은 경우 일부 추가 코드가 필요할 수 있지만 대수 종결이 부동 소수점 산술에 가져온 편의성을 지불하는 것은 작은 가격입니다.


부록 : 많은 의견 제시 자들은 NaN! = NaN을 채택하는 것이 친숙한 공리를 보존하지 않는 근거로 평등과 삼분 절의 반사성을 유지하는 것이 더 유용 할 것이라고 주장했다. 나는이 견해에 대해 동정심을 가지고 있다고 고백했다. 그래서 나는이 답변을 다시 방문하고 좀 더 많은 맥락을 제공 할 것이라고 생각했다.

Kahan과의 대화에서 NaN! = NaN은 두 가지 실용적인 고려 사항에서 비롯된 것입니다.

  • x == y동등해야한다 x - y == 0이것은 X의 위반, 그러나, 참고 -이 표준이 개발되었을 때 가장 중요했다 비해 더 많은 공간 효율의 하드웨어 구현한다 가능하면 (실제 연산의 정리되고 넘어 = y = 무한대이므로, 그 자체로는 큰 이유가 아닙니다 (x - y == 0) or (x and y are both NaN).

  • 더 중요한 isnan( )것은 NaN이 8087 산술로 공식화 될 당시에는 술어 가 없었다는 것입니다. isnan( )수년이 걸릴 수 있는 프로그래밍 언어에 의존하지 않는 NaN 값을 감지하는 편리하고 효율적인 수단을 프로그래머에게 제공 해야했습니다. 이 주제에 대한 Kahan의 글을 인용하겠습니다.

NaN을 제거 할 수있는 방법이 없었다면 CRAY에서 무기한만큼 쓸모가 없을 것입니다. 하나가 발생하자마자 무기한 결론을 내릴 때까지 무한정 계속되는 것이 아니라 계산을 중단하는 것이 가장 좋습니다. 그렇기 때문에 NaN에 대한 일부 작업은 NaN 이외의 결과를 제공해야합니다. 어떤 작업? … 예외는 C 술어 “x == x”및 “x! = x”이며, 이는 모든 무한 또는 유한 수 x에 대해 각각 1과 0이지만 x가 숫자가 아님 (NaN)이면 역전됩니다. 이것들은 NaN에 대한 단어와 술어 IsNaN (x)가없는 언어의 NaN과 숫자 사이의 단순한 예외없는 구별을 제공합니다.

이것은 “부울이 아님”과 같은 것을 반환하지 않는 논리이기도합니다. 어쩌면이 실용주의가 잘못 배치되어 표준이 필요 isnan( )했을 것입니다. 그러나 NaN은 몇 년 동안 효율적이고 편리하게 사용하기가 거의 불가능 해졌지만 세계는 프로그래밍 언어 채택을 기다렸습니다. 나는 합리적인 트레이드 오프가 될 것이라고 확신하지 않습니다.

둔감하게 : NaN == NaN의 결과는 지금 바뀌지 않을 것입니다. 인터넷에서 불평하는 것보다 함께 사는 법을 배우는 것이 좋습니다. 컨테이너에 적합한 주문 관계 존재 해야한다고 주장하려면 선호하는 프로그래밍 언어 totalOrder가 IEEE-754 (2008)에 표준화 된 술어를 구현하도록 권장합니다 . 그것이 현재 상황에 동기를 부여한 Kahan의 우려의 타당성을 아직 밝히지 않았다는 사실.


답변

NaN은 정의되지 않은 상태 / 번호로 생각할 수 있습니다. 0/0의 개념은 undefined 또는 sqrt (-3) (부동 소수점이있는 실수 시스템에서)라는 개념과 유사합니다.

NaN은이 정의되지 않은 상태에 대한 일종의 자리 표시 자로 사용됩니다. 수학적으로 말하면 undefined는 undefined와 다릅니다. 정의되지 않은 값이 다른 정의되지 않은 값보다 크거나 작다고 말할 수는 없습니다. 따라서 모든 비교는 false를 반환합니다.

sqrt (-3)와 sqrt (-2)를 비교하는 경우에도이 동작이 유리합니다. 둘 다 NaN을 반환하지만 동일한 값을 반환하더라도 동등하지 않습니다. 그러므로 NaN을 다룰 때 평등을 갖는 것은 항상 잘못된 행동입니다.


답변

또 다른 비유를 던져라. 상자 두 개를 건네고 사과 중 어느 것도 사과가 들어 있지 않다고 말하면 상자에 같은 것이 들어 있다고 말할 수 있습니까?

NaN에는 무엇인가에 대한 정보가 없습니다. 따라서 이러한 요소는 절대 동일하다고 말할 수 없습니다.


답변

NaN 에 대한 Wikipedia 기사에서 다음과 같은 관행으로 인해 NaN이 발생할 수 있습니다.

  • NaN을 하나 이상의 피연산자로 사용하는 모든 수학 연산>
  • 0/0, ∞ / ∞, ∞ / -∞, -∞ / ∞ 및 -∞ / -∞ 나누기
  • 곱셈 0 × ∞ 및 0 × -∞
  • 더하기 ∞ + (-∞), (-∞) + ∞ 및 동등한 빼기.
  • 음수의 제곱근을 취하거나, 음수의 로그를 취하거나, 90 도의 홀수 배수 (또는 π / 2 라디안)의 탄젠트를 취하거나, 역 사인을 취하는 등 함수를 도메인 외부의 인수에 적용 또는 -1보다 작거나 +1보다 큰 수의 코사인.

NaN을 생성 한 이러한 작업을 알 수있는 방법이 없으므로 의미가있는 작업을 비교할 방법이 없습니다.


답변

디자인의 이론적 근거를 모르지만 다음은 IEEE 754-1985 표준에서 발췌 한 것입니다.

“피연산자의 형식이 다른 경우에도 지원되는 모든 형식의 부동 소수점 숫자를 비교할 수 있습니다. 비교는 정확하고 오버플로 또는 언더 플로가 아닙니다. 상호 배타적 인 관계는 가능합니다. 마지막 사건은 적어도 하나의 피연산자가 NaN 인 경우에 발생합니다. 모든 NaN은 순서가없는 것을 자기 자신을 포함한 모든 것과 비교해야합니다. “


답변

NaN을 허용하는 대부분의 프로그래밍 환경은 3 값 논리도 허용하지 않기 때문에 독특하게 보입니다. 3 값 논리를 믹스에 넣으면 일관성이 유지됩니다.

  • (2.7 == 2.7) = 그렇습니다
  • (2.7 == 2.6) = 거짓
  • (2.7 == NaN) = 알 수 없음
  • (NaN == NaN) = 알 수 없음

.NET조차도 bool? operator==(double v1, double v2) 연산자를 여전히 어리석은 (NaN == NaN) = false결과에 갇혀 있습니다.


답변

NaN (Not A Number)은 정확히 다음을 의미한다고 추측합니다. 이것은 숫자가 아니므로 비교하는 것이 실제로 의미가 없습니다.

null피연산자가 있는 SQL의 산술과 ​​비슷 null합니다. 결과는 모두입니다 .

부동 소수점 숫자의 비교는 숫자 값을 비교합니다. 따라서 숫자가 아닌 값에는 사용할 수 없습니다. 따라서 NaN은 숫자로 비교할 수 없습니다.