포스트

[C++] NaN (Not a Number)

[C++] NaN (Not a Number)

C++ NaN (Not a Number) 정리

NaN은 부동소수점 연산에서 “수로 간주될 수 없는 결과”를 표현하기 위해 사용하는 특수한 값입니다. 이는 IEEE 754 부동소수점 표준에서 정의되며, 프로그램이 계산 불가능한 상황에서 강제 종료되지 않고 실행을 계속할 수 있도록 해줍니다.


1. NaN이란?

  • NaN은 Not a Number의 약자로, 정의되지 않거나 계산이 불가능한 결과를 나타냅니다.
  • 예외 상황을 실수 값의 형태로 표현하여 프로그램 흐름을 유지할 수 있게 합니다.

NaN이 발생하는 대표적 연산

| 연산 | 결과 | |——|——| | 0.0 / 0.0 | NaN | | sqrt(-1.0) | NaN | | log(-1.0) | NaN | | ∞ - ∞ | NaN |

주요 특징

  • NaN은 자기 자신과도 같지 않다(x == x)는 false
  • 어떤 값과의 비교도 false → <, ==, !=, > 모두 false
  • std::isnan(x)를 사용해 NaN 여부 판단 가능

2. NaN과 Infinity의 관계

공통점

  • 둘 다 IEEE 754 부동소수점 표준에서 정의된 특수 실수 값
  • 계산 불가능하거나 표현 불가한 상태를 나타냄

차이점

| 항목 | NaN | +∞ / –∞ | |——|—–|———-| | 의미 | 수가 아님 (정의되지 않음) | 매우 크거나 작은 수 | | 비교 | 비교 불가 | 비교 가능 (크기 비교 가능) | | 발생 조건 | 0/0, sqrt(-1), ∞ - ∞ 등 | 1/0, overflow 등 | | 검사 방법 | std::isnan(x) | std::isinf(x) |

비교 결과 예시

1
2
std::numeric_limits<double>::quiet_NaN() == std::numeric_limits<double>::quiet_NaN(); // false
std::numeric_limits<double>::infinity() == std::numeric_limits<double>::infinity();   // true

3. NaN의 종류: quiet NaN vs signaling NaN

IEEE 754에서는 NaN을 두 가지로 분류합니다:

quiet NaN (qNaN)

  • 연산 시 조용히 NaN을 전파
  • 대부분의 시스템에서 기본적으로 사용하는 NaN
  • 예: sqrt(-1), 0.0/0.0 → NaN이 되지만 예외 발생 없이 계산 계속

signaling NaN (sNaN)

  • 연산 시 에러나 예외 발생을 유도
  • 주로 디버깅, 초기화되지 않은 값 확인에 사용
  • 일부 시스템/컴파일러에서만 제한적으로 사용 가능
항목quiet NaNsignaling NaN
정의계산 실패 값 전파계산 실패 시점에 알림
동작조용히 NaN 반환예외나 트랩 발생 가능
용도일반 연산, 에러 누적디버깅, 초기화 오류 탐지
지원광범위제한적 (플랫폼 의존)

비트 차이 (double 기준)

  • exponent = 2047 (모두 1)
  • fraction의 가장 높은 비트 (MSB)가 1 → qNaN
  • MSB가 0이고 나머지에 1 있음 → sNaN

4. 사용 목적 요약

상황사용되는 특수 값설명
계산 불능NaNsqrt(-1), 0/0, ∞ - ∞ 등
값이 너무 큼+∞ / –∞1.0 / 0.0, DBL_MAX * 2 등
초기화 오류 감지sNaN디버깅용 신호 (일부 시스템 한정)

5. 요약

항목NaN
의미수가 아님 (Not a Number)
비교불가능 (false)
종류quiet, signaling
검사std::isnan(x)
목적정의되지 않은 계산 결과 표현

NaN은 부동소수점 시스템에서 필수적인 예외 처리 메커니즘입니다. 정밀 계산이나 신뢰성 있는 시스템을 개발할 때 반드시 고려해야 할 요소입니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.