IT story

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

hot-time 2020. 4. 12. 10:30
반응형

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은 숫자로 비교할 수 없습니다.


지나치게 단순화 된 답변은 NaN에 숫자 값이 없으므로 다른 것과 비교할 값이 없다는 것입니다.

NaN을 + INF처럼 작동 시키려면 NaN을 테스트하고 + INF로 교체하는 것을 고려할 수 있습니다.


NaN은 암시적인 새 인스턴스입니다 (특별한 종류의 런타임 오류). 그것은 NaN !== NaN같은 이유로 new Error !== new Error;

그리고 그러한 암시성은 오류 외부에서도 볼 수 있습니다. 예를 들어 정규 표현식의 맥락에서 /a/ !== /a/이는 구문 설탕 이라는 의미 입니다.new RegExp('a') !== new RegExp('a')


NaN과 실수를 비교하는 것은 순서가 맞지 않아야한다는 데 동의하지만 NaN과 자체를 비교하는 데는 이유가 있다고 생각합니다. 예를 들어 신호 NaN과 조용한 NaN의 차이점을 어떻게 알 수 있습니까? 신호를 부울 값 세트 (즉, 비트 벡터)로 생각하면 비트 벡터가 동일한 지 또는 다른지를 묻고 그에 따라 세트를 정렬 할 수 있습니다. 예를 들어, 최대 바이어스 지수를 디코딩 할 때 이진 형식의 최상위 비트와 최상위 비트를 정렬하기 위해 유효 비트가 시프트 된 경우 음수 값은 조용한 NaN이되고 양수 값은 신호 NaN이어야합니다. 물론 제로는 무한대로 예약되어 있으며 비교는 순서가 없습니다. MSB 정렬을 통해 서로 다른 이진 형식의 신호를 직접 비교할 수 있습니다. 따라서 동일한 신호 세트를 가진 두 개의 NaN은 동일하며 동일성을 의미합니다.


수학은 숫자가 "존재하는"필드이기 때문입니다. 컴퓨팅에서는 해당 숫자 초기화 하고 필요에 따라 상태를 유지 해야합니다. 그 옛날에는 메모리 초기화가 결코 신뢰할 수 없었던 방식으로 작동했습니다. 당신은 결코 "오, 그것은 0xCD로 초기화 될 것이고, 나의 알고는 깨지지 않을 것" 이라고 생각할 수 없었습니다 .

따라서 알고리즘에 빨려 들어 가지 않도록 충분히 끈적 거리지 않는 적절한 비 혼합 용매 가 필요합니다 . 숫자와 관련된 좋은 알고리즘은 대부분 관계와 함께 작동하며 if () 관계는 생략됩니다.

이것은 컴퓨터 메모리에서 무작위 지옥을 프로그래밍하는 대신 생성시 새로운 변수에 넣을 수있는 그리스 일뿐입니다. 그리고 알고리즘이 무엇이든 깨지지 않습니다.

다음으로 알고리즘이 NaN을 생성하고 있다는 것을 갑자기 알면 한 번에 하나씩 모든 브랜치를 조사하여 정리할 수 있습니다. "항상 거짓"규칙이 이것에 많은 도움이됩니다.


나를 위해 가장 쉬운 방법은 다음과 같습니다.

나는 무언가가 있고 그것이 사과가 아니라면 오렌지입니까?

NaN은 값이 없기 때문에 다른 것 (심지어 그 자체)과 비교할 수 없습니다. 또한 숫자를 제외한 모든 값이 될 수 있습니다.

나는 무언가가 있고 그것이 숫자와 같지 않으면 문자열입니까?


매우 짧은 답변 :

다음과 같은 이유로 : nan / nan = 1 잡고 있으면 안됩니다. 그렇지 않으면 inf/inf1이됩니다.

(따라서 nan동일 할 수 없다 nan.로서는을 >하거나 <하는 경우, nan아르키메데스 속성을 만족시키는 집합의 임의의 순서 관계를 존중 것, 우리는 다시했을 nan / nan = 1한도에서).

참고 URL : https://stackoverflow.com/questions/1565164/what-is-the-rationale-for-all-comparisons-returning-false-for-ieee754-nan-values

반응형