NaN
NaN컴퓨팅에서 Not a Number의 약자인 NaN(/n æn/)은 0을 0으로 나눈 결과와 같이 정의되지 않거나 표현할 수 없는 숫자 데이터 유형의 특정 값입니다.NaNs의 체계적인 사용은 1985년 IEEE 754 부동소수점 표준에 의해 무한대와 같은 다른 비무한량의 표현과 함께 도입되었습니다.
수학에서 0을 0으로 나눈 값은 일반적으로 정의되지[a] 않으므로 컴퓨팅 시스템에서는 NaN으로 표시됩니다.
음수의 제곱근은 실수가 아니므로 호환 컴퓨팅 시스템에서도 NaN으로 표시됩니다.NaN은 계산에서 결측값을 나타내기 위해 사용될 수도 있습니다.[1][2]
조용한 NaNs 및 신호 NaNs라고 하는 두 가지 별개의 종류의 NaN이 제공됩니다.Quiet NaN은 잘못된 연산 또는 값으로 인한 오류를 전파하는 데 사용됩니다.신호 NaN은 기본 부동 소수점 산술에 대한 수치 및 기호 계산 또는 다른 확장을 혼합하는 것과 같은 고급 기능을 지원할 수 있습니다.
부동점
부동 소수점 형식들 |
---|
IEEE 754 |
다른. |
부동 소수점 계산에서 NaN은 무한대와 동일하지 않지만, 두 가지 모두 일반적으로 실수의 부동 소수점 표현과 부동 소수점 연산에서 특수한 경우로 처리됩니다.잘못된 연산은 산술 오버플로(크기에서 무한대 또는 가장 큰 유한 수를 반환함) 또는 산술 언더플로(크기에서 가장 작은 정상 수, 정상 이하 수 또는 0을 반환함)와 같지도 않습니다.
IEEE 754 NaN은 (인피니티 값과 같이) 1개로 채워진 지수 필드와 (인피니티 값과 구별되도록) 사인과 필드의 0이 아닌 일부 숫자로 인코딩됩니다; 이것은 사인과 필드에 설정된 비트에 따라 여러 개의 별개의 NaN 값을 정의할 수 있게 합니다.뿐만 아니라 선두 부호 비트의 값에 대해서도 마찬가지입니다(그러나 애플리케이션은 그러한 별개의 NaN 값에 대해 별개의 의미론을 제공할 필요는 없습니다).
예를 들어, IEEE 754 단일 정밀도(32비트) NaN은 다음과 같이 인코딩됩니다.
s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
여기서 s는 부호(응용 프로그램에서 가장 자주 무시됨)이고 x 시퀀스는 0이 아닌 숫자(값 0이 무한을 인코딩함)를 나타냅니다.실제로는 x에서 가장 중요한 비트를 사용하여 NaN의 종류를 결정합니다. "조용한 NaN" 또는 "신호하는 NaN"(Encoding의 자세한 내용 참조).나머지 비트는 페이로드를 인코딩합니다(대부분 응용프로그램에서 무시됨).
순서 비교 이외의 부동 소수점 연산은 일반적으로 조용한 NaN(qNaN)을 전파합니다.시그널링 NaN(sNaN)에 대한 대부분의 부동 소수점 연산은 무효 연산 예외를 신호합니다. 기본 예외 동작은 qNaN 피연산자와 동일하며 부동 소수점 결과를 생성하는 경우 qNaN을 생성합니다.
산술 연산을 통한 조용한 NaN 전파는 중간 단계 동안 광범위한 테스트 없이 일련의 연산이 끝날 때 오류를 탐지할 수 있습니다.예를 들어 NaN으로 시작해서 연속으로 1을 5번 더하면 각 덧셈에서 NaN이 나오지만, 최종 결과가 NaN이라는 것만 알면 되기 때문에 각각의 계산을 확인할 필요가 없습니다.그러나 언어와 함수에 따라 NaNs는 다른 모든 부동 소수점 값에 대해 일정한 결과를 제공하는 일련의 계산에서 조용히 제거될 수 있습니다.예를 들어, x가 NaN인 경우에도 계산 x는0 결과 1을 생성할 수 있으므로 최종 결과만 확인하면 x0 이전의 계산에서 NaN이 생성되었다는 사실이 모호해집니다.일반적으로 NaN이 도입된[3] 모든 경우를 감지하려면 설정된 유효하지 않은 플래그에 대한 나중 테스트가 필요합니다(자세한 내용은 아래 함수 정의 참조).
구 IEEE 754-2008 표준의 섹션 6.2에서, 두 가지 이상한 기능이 있습니다.maxNum
그리고.minNum
숫자를 선호하는 두 피연산자의 최대값과 최소값을 각각 반환하는 함수 - 피연산자 중 하나만 NaN이면 다른 피연산자의 값이 반환됩니다.IEEE 754-2019 개정판은 (피연산자에 신호 NaN이 나타나는 경우) 연관성이 없기 때문에 이러한 기능을 대체했습니다.[4][5]
NaN과 비교
비교는 가능한 NaN 피연산자를 고려하기 위해 IEEE 754 표준에 의해 지정됩니다.[6](IEEE 754 부동 소수점 형식에서와 같이) 두 개의 실수 또는 확장된 실수를 비교할 때, 첫 번째 숫자는 두 번째 숫자보다 작거나 같거나 클 수 있습니다.이것은 세 가지 가능한 관계를 제공합니다.그러나 비교의 적어도 하나의 피연산자가 NaN인 경우에는 이 삼분법이 적용되지 않으며, 네 번째 관계가 필요합니다. 순서가 없습니다.특히 두 NaN 값은 동일하지 않고 순서가 없는 값으로 비교됩니다.
지정한 대로 <, ≤, =, ≥, > 수학 기호(또는 프로그래밍 언어의 등가 표기)와 관련된 술어는 순서가 없는 관계에서 거짓을 반환합니다.예를 들어, NOT(x < y)는 논리적으로 x ≥y와 동치가 아닙니다. 즉, 순서가 없는 경우, x 또는 y가 NaN일 때, 전자는 true를 반환하고 후자는 false를 반환합니다.그러나 ≠은(는) =의 음수로 정의되므로 순서가 없는 경우 true로 반환됩니다.
비교 | NaN ≥ x | NaN ≤ x | NaN > x | NaN < x | NaN = x | NaN ≠ x |
---|---|---|---|---|---|---|
결과 | 거짓의 | 거짓의 | 거짓의 | 거짓의 | 거짓의 | 진실의 |
이러한 규칙에 따라 x를 자신과 비교하여 x ≠ x 또는 x = x를 사용하여 x가 NaN인지 아니면 non-NaN인지를 검정할 수 있습니다.
비교 술어는 조용한 NaN 피연산자에서 시그널링 또는 비시그널링 중 하나입니다. 시그널링 버전은 그러한 비교에 대해 무효 동작 예외를 시그널링합니다(즉, 기본적으로 비시그널링 버전의 동작에 추가하여 해당 상태 플래그를 설정합니다).등식 및 등식 술어는 비신호입니다.위의 수학 기호와 관련된 다른 표준 비교 술어는 NaN 피연산자를 수신하는 경우 모두 시그널링입니다.표준에서는 이러한 다른 술어의 비신호 버전도 제공합니다.술어를isNaN(x)
는 값이 NaN인지 여부를 결정하며 x가 신호 NaN이더라도 예외 신호를 보내지 않습니다.
IEEE 부동 소수점 표준에서는 NaN ≠ NaN을 보유해야 합니다.이와 달리 2022년 민간 양론 표준인 NaR(Not a Real)은 NaR = NaR이 성립하는 개념과 유사합니다.
NaN 생성 작업
NaN을 반환할 수 있는 작업에는 세 가지 종류가 있습니다.[8]
- NaN 피연산자가 하나 이상 있는 대부분의 연산.
- 불확정된 양식:
- (±0) / (±0) 및 (±∞) / (±∞)의 구분.
- 곱하기 (±0) × (± ∞) 및 (± ∞) × (±0).
- x가 무한대이거나 y가 0일 때 나머지 x % y.
- 덧셈(+∞) + (-∞) + (-∞) + (+∞) + (-∞) - (+∞) - (-∞) - (-∞) - (-)
- 이 표준에는 파워에 대한 대체 기능이 있습니다.
- 기준을
pow
함수와 정수 지수pown
함수는 0, 1 및 ∞를 1로 정의합니다. - 그
powr
function은 세 가지 불확정 형태를 모두 유효하지 않은 연산으로 정의하므로 NaN을 반환합니다.
- 기준을
- 복잡한 결과를 가진 실제 운영:
NaN은 변수에 명시적으로 할당될 수도 있으며, 일반적으로 결측값에 대한 표현으로 사용됩니다.IEEE 표준 이전에는 프로그래머들이 정의되지 않거나 누락된 값을 나타내기 위해 종종 특별한 값(예: -99999999)을 사용했지만 일관성 있게 또는 정확하게 처리된다는 보장은 없었습니다.[1]
NaN은 위의 모든 경우에 반드시 생성되는 것은 아닙니다.작업이 예외 조건을 생성할 수 있고 트랩이 마스킹되지 않으면 대신 트랩이 발생합니다.[9]피연산자가 조용한 NaN이고 신호를 보내는 NaN 피연산자도 없다면 예외 조건이 없고 결과는 조용한 NaN입니다.명시적 할당은 NaNs 신호를 보내는 경우에도 예외를 발생시키지 않습니다.
정숙한 NaN
일반적으로 조용한 NaN, 즉 qNaN은 대부분의 작업을 통해 전파되므로 추가적인 예외를 제기하지 않습니다.그러나 잘못된 연산 예외는 형식 변환 또는 특정 비교 연산과 같이 부동 소수점 값을 반환하지 않는 일부 연산에 의해 시그널링됩니다.
신호 NaN
시그널링 NaN(sNaN)은 NaN의 특수한 형태로, 대부분의 작업에서 사용될 때 유효하지 않은 작업 예외를 발생시킨 다음, 적절한 경우 전파될 수 있는 qNaN으로 "조용히"되어야 합니다.이들은 IEEE 754에 소개되었습니다.다음과 같은 몇 가지 아이디어가 있습니다.
- 초기화되지 않은 메모리를 시그널링 NaNs로 채우면 데이터가 초기화되기 전에 사용된 경우 잘못된 작업 예외가 생성됩니다.
- sNaN을 다음과 같이 더 복잡한 개체의 자리 표시자로 사용합니다.
트랩 핸들러가 발견되면 sNaN을 디코딩하고 인덱스를 계산된 결과로 반환할 수 있습니다.실제로 이 접근 방식은 많은 복잡한 문제에 직면해 있습니다.일부 단순 연산(절대값 등)에 대한 NaN의 부호 비트 처리는 산술 연산의 경우와 다릅니다.트랩은 표준에서 필요하지 않습니다.이런 종류의 문제에 대해 휴대성이 더 좋은 다른 접근법이 있습니다.[citation needed]
페이로드 작업
IEEE 754-2019는 getPayload, setPayload, setPayloadSignaling 등의 작업을 구현할 것을 권장하며,[10] 애플리케이션 사용을 간소화하기 위해 페이로드에 대한 액세스를 표준화합니다.[11]IEEE 754-2019 배경 문서에 따르면, 이 권장 사항은 "역호환성을 위해 예약된 새로운 구현에 필요한 것"으로 해석되어야 합니다.[12]
인코딩
IEEE 754 표준을 따르는 부동 소수점 저장 형식에서 NaN은 NaN 고유의 미리 정의된 특정 비트 패턴으로 식별됩니다.기호 비트는 중요하지 않습니다.이진 형식 NaN은 (무한 값과 같이) 1로 채워진 지수 필드와 (무한 값과 구별되도록) 0이 아닌 일부 숫자로 표시됩니다.1985년의 원래 IEEE 754 표준(IEEE 754-1985)은 이진 부동 소수점 형식만을 설명하고 시그널링/정지 상태를 태그하는 방법을 지정하지 않았습니다.실제로는, NaN이 신호를 보내고 있는지 조용한지를 결정하는 가장 중요한 부분과 필드가 있습니다.서로 다른 두 가지 구현(반대되는 의미)으로 인해 다음과 같은 의미입니다.
- 대부분의 프로세서(Intel 및 AMD의 x86 제품군, Motorola 68000 제품군, AIM PowerPC 제품군, ARM 제품군, SunSPARC 제품군 및 선택적으로 새로운 MIPS 프로세서)는 NaN이 조용한 경우 시그널링/조용한 비트를 0이 아닌 것으로 설정하고 NaN이 시그널링하는 경우 0으로 설정합니다.따라서 이러한 프로세서에서 비트는
is_quiet
깃발; - PA-RISC 및 이전 MIPS 프로세서에 의해 생성된 NaN에서, NaN이 조용한 경우 시그널링/조용한 비트는 0이고, NaN이 시그널링하는 경우에는 0이 아닙니다.따라서 이러한 프로세서에서 비트는
is_signaling
깃발을 올리다
전자의 선택은 시그널링/조용한 비트를 1로 설정하는 것만으로 시그널링 NaN을 조용하게 할 수 있기 때문에 선호되어 왔습니다.시그널링/조용한 비트를 0으로 설정하면 무한대를 얻을 수 있기 때문에 후자의 경우에는 반대로 할 수 없습니다.[13]
IEEE 754 표준의 2008년 및 2019년 개정판은 시그널링/정지 상태의 인코딩에 대한 공식 요구사항 및 권장사항을 제공합니다.
- 이진 교환 형식의 경우, significant 및 field의 가장 중요한 비트는 조용한 NaN과 signaling NaN을 구분하기 위해 전용으로 사용됩니다.[14]게다가, 그것은 그것이 되어야만 합니다.
is_quiet
flag.[15] 즉, NaN이 조용한 경우 이 비트는 0이 아니며 NaN이 시그널링하는 경우 0이 아닙니다. - 이진 인코딩이든 십진 인코딩이든 십진 변환 형식의 경우 부호 비트 다음의 조합 필드의 상위 5비트를 1로 설정하여 NaN을 식별합니다.필드의 여섯번째 비트는
is_signaling
flag. 즉, NaN이 조용한 경우 이 비트는 0이고 NaN이 시그널링하는 경우 0이 아닙니다.[16]
IEEE 754-2008 적합성의 경우, 최근 MIPS 프로세서에서 시그널링/조용한 비트의 의미는 이제 FCSR 레지스터의 NAN2008 필드를 통해 구성할 수 있습니다.이 지원은 MIPS Release 3에서는 선택 사항이며 Release 5에서는 필수 사항입니다.[17]
시그날 및 필드의 나머지 비트의 상태/값은 표준에 의해 정의되지 않습니다.이 값을 NaN의 'payload'라고 합니다.동작에 단일 NaN 입력이 있고 출력에 전파되는 경우, 결과 NaN의 페이로드는 입력 NaN의 페이로드가 되어야 합니다(시그널링/조용한 상태가 a에 의해 인코딩될 때 이진 형식에서는 항상 가능하지 않습니다).is_signaling
위에서 설명한 바와 같이 플래그(flag.NaN 입력이 여러 개일 경우, NaN의 페이로드 결과는 입력 NaN 중 하나에서 나와야 하며, 표준은 어떤 것을 지정하지 않습니다.
함수정의
조용한 NaN을 입력으로 받는 숫자 함수의 결과에 대한 적절한 정의에 대해 의견의 차이가 있습니다.한 가지 견해는 오류 표시를 전파하기 위해 NaN이 모든 경우에 함수의 출력으로 전파되어야 한다는 것입니다.ISO C99 및 IEEE 754-2008 표준에 의해 일반적으로 채택된 또 다른 관점은 함수에 여러 인수가 있고 출력이 모든 비 NaN 입력(무한을 포함)에 의해 고유하게 결정되는 경우 그 값이 결과여야 한다는 것입니다.따라서 예를 들어 다음과 같이 반환되는 값을hypot(±∞, qNaN)
그리고.hypot(qNaN, ±∞)
+∞ 입니다.
이 문제는 지수 함수 = x에 대해 특히 심각합니다.식 0, ∞, 1은 한계로 발생할 때 불확정적인 형태로 간주되며(예를 들어 ∞ × 0과 마찬가지로), 0부터 0까지의 거듭제곱을 1로 정의해야 하는지에 대한 문제는 의견이 분분합니다.
파라미터가 정의되지 않았을 때 출력이 정의되지 않은 것으로 간주될 경우pow(1, qNaN)
qNaN을 생성해야 합니다.그러나 수학 라이브러리는 일반적으로 임의의 실수에 대해 1을 반환하고 y가 무한대인 경우에도 1을 반환합니다.마찬가지로 x가 0이거나 무한대인 경우에도 1을 생성합니다.불확정된 형태에 대해 값 1을 반환하는 근거는 그 값이 매개변수의 한계값 주위에서 사라지는 공의 작은 부분을 제외한 모든 부분에 대한 값이[clarification needed] 한계값에 있는 경우 단일 지점의 함수 값을 특정 값으로 간주할 수 있다는 것입니다.[citation needed]IEEE 754 표준의 2008년 버전은 다음과 같이 말합니다.pow(1, qNaN)
그리고.pow(qNaN, 0)
조용한 NaN 대신에 다른 어떤 것을 사용하든 1을 반환하기 때문에 둘 다 1을 반환해야 합니다.또한 ISO C99와 나중에 IEEE 754-2008은 qNaN 대신 = 1을 지정하기로 선택했습니다. 이러한 선택의 이유는 C의 이론적 근거에 제시되어 있습니다: "일반적으로 C99는 수치 값이 유용한 NaN 결과를 피합니다.의 결과.pow(−2, ∞)
모든 큰 양의 부동소수점 값은 짝수 정수이므로 +∞입니다."
멱함수가 어떻게 작용해야 하는지에 대한 보다 엄격한 해석을 원하는 사람들을 만족시키기 위해 2008년 표준은 두 개의 추가적인 멱함수를 정의합니다. , 지수는 정수여야 하며 , 그리고 는 매개 변수가 NaN이거나 지수가 불확정한 형태를 줄 때마다 NaN을 반환합니다.
정수 NaN
대부분의 고정 크기 정수 형식은 유효하지 않은 데이터를 명시적으로 나타낼 수 없습니다.그러한 경우, NaN을 정수 타입으로 변환할 때, IEEE 754 표준은 무효-동작 예외를 시그널링할 것을 요구합니다.예를 들어 자바에서는 이러한 작업이 인스턴스를 던집니다.java.lang.ArithmeticException
.[19]C에서는[19] 정의되지 않은 동작으로 이어지지만, 부속서 F가 지원되는 경우 동작이 "잘못된" 부동 소수점 예외(IEEE 표준에서 요구하는 대로)와 지정되지 않은 값을 산출합니다.
펄스Math::BigInt
패키지는 유효한 정수를 나타내지 않는 문자열의 결과에 "NaN"을 사용합니다.[20]
> perl -mMath::BigInt-e "프린트 수학::BigInt->new('foo')" NaN
디스플레이
서로 다른 운영 체제와 프로그래밍 언어는 NaN의 문자열 표현이 다를 수 있습니다.
nan (C, C++, Python) NaN (ECMAscript, Rust, C#, Julia)Julia는 정밀도, NaN32 및 NaN16에 따라 대체 NaN을 보여줄 수 있습니다. NaN은 Float64 유형입니다.NaN% NAN (C, C++, Rust) NaNQ (IBM XL 및 AIX: Fortran, C++ proposal n2290) NaNS (ditto) qNasNaN 1.#SNAN(엑셀) 1.#QNAN (엑셀) -1.#IND(엑셀) +nan.0(도식)
실제로 부호화된 NaN에는 부호, 조용한/신호 비트 및 선택적인 '진단 정보'(때로는 페이로드라고도 함)가 있기 때문에 NaN의 문자열 표현에서도 이러한 정보를 찾을 수 있습니다.다음과 같은 예가 있습니다.
- C 및 C++ 언어의 경우 부호 비트는 항상 표준 라이브러리 함수로 표시됩니다(예: C++ 언어).
-nan
) 참석시.페이로드의 표준 디스플레이 또는 시그널링 상태는 없지만, 특정 페이로드의 조용한 NaN 값은 문자열을 제공함으로써 구성될 수 있습니다.nan(char-sequence)
숫자 parsing 함수(예:strtod
) 또는 문자 시퀀스 문자열을 제공하여nan()
(또는nans()
sNaN)의 경우 모두 구현 정의 방식으로 해석됩니다.- GCC 및 LLVM은 다음과 같은 기본 구현을 제공합니다.
nan()
그리고.nans()
. 그들은 문자 시퀀스를 다음에 대한 정수로 해석합니다.strtoull
(또는 크기가 다른 등가물) 정수 염기의 검출과 함께. - GNU C 라이브러리의 플로트 파서는 "특정되지 않은 방식"으로 문자 시퀀스 문자열을 사용합니다.[21]실제로 이 구문 분석은 최대 64비트의 페이로드에 대해 GCC/LLVM과 동등합니다.
- 새 lib가 구현되지 않음
nan()
구문 분석, 그러나strtod()
는 접두사가 없는 16진수 형식을 허용합니다. - musl은 페이로드 구문 분석을 구현하지 않습니다.
- GCC 및 LLVM은 다음과 같은 기본 구현을 제공합니다.
모든 언어가 여러 NaN의 존재를 인정하는 것은 아닙니다.예를 들어 ECMAscript는 전체에서 하나의 NaN 값만 사용합니다.
참고문헌
메모들
인용문
- ^ a b Bowman, Kenneth (2006). An Introduction to Programming with IDL: Interactive Data Language. Academic Press. p. 26. ISBN 978-0-12-088559-6.
- ^ Press, William H.; Teukolsky, Saul A.; Vetterling, William T.; Flannery, Brian P. (2007). Numerical Recipes: The Art of Scientific Computing. Cambridge University Press. p. 34. ISBN 978-0-521-88068-8.
- ^ William Kahan (1 October 1997). "Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic" (PDF).
- ^ David H.C. Chen (21 February 2017). "The Removal/Demotion of
MinNum
andMaxNum
Operations from IEEE 754™-2018" (PDF). Retrieved 6 May 2019. - ^ "754R Minutes". 19 May 2017. Retrieved 25 June 2017.
- ^ IEEE 754 2019, §5.11
- ^ 양산표준(2022)
- ^ David Goldberg (1991). "What Every Computer Scientist Should Know About Floating-Point".
- ^ "Intel 64 and IA-32 Architectures Software Developer's Manual Volume 1: Basic Architecture". April 2008. pp. 118–125, 266–267, 334–335.
- ^ IEEE 754 2019, §9.7
- ^ "Background discussion for the new Payload functions".
- ^ "IEEE Standard for Floating-Point Arithmetic revision due in 2019" (PDF).
- ^ "Re: (long) sNaNs not what they could be..." grouper.ieee.org. 15 October 2010. Retrieved 5 November 2020.
- ^ IEEE 754 2019, §3.4
- ^ IEEE 754 2019, §6.2.1
- ^ IEEE 754 2019, §3.5.2
- ^ "MIPS® Architecture For Programmers – Volume I-A: Introduction to the MIPS64® Architecture" (PDF). MIPS Technologies, Inc. 20 November 2013. p. 79. Retrieved 27 September 2017.
- ^ "Rationale for International Standard—Programming Languages—C, Revision 5.10" (PDF). April 2003. p. 180.
- ^ "ArithmeticException (Java Platform SE 8)". docs.oracle.com.
- ^ "
Math::BigInt
". perldoc.perl.org. Retrieved 12 June 2015. - ^ "Parsing of Floats (The GNU C Library)". www.gnu.org. Retrieved 9 September 2021.
If chars… are provided, they are used in some unspecified fashion to select a particular representation of NaN (there can be several).
기준
- IEEE Computer Society (29 August 2008). IEEE Standard for Floating-Point Arithmetic. IEEE. pp. 1–70. doi:10.1109/IEEESTD.2008.4610935. ISBN 978-0-7381-5753-5. IEEE Std 754-2008.
- IEEE Computer Society (22 July 2019). IEEE Standard for Floating-Point Arithmetic. IEEE. pp. 1–84. doi:10.1109/IEEESTD.2019.8766229. ISBN 978-1-5044-5924-2. IEEE Std 754-2019.
외부 링크
- 숫자가 아닙니다, foldoc.org
- 부동 소수점 연산 표준 IEEE 754-2008 (구독 필요)
- 부동 소수점 연산 표준 IEEE 754-2019 (구독 필요)