C# 학습/C# 언어의 기초

C# 세미나 자료: 특별한 부동소수점 값 (NaN, Infinity, -Infinity, -0)

DevGourmet 2025. 4. 7. 12:46

1. 개요

C#에서 float, double, decimal과 같은 부동소수점 타입은 정수 타입과 달리 **특수한 값(Special Values)**을 가질 수 있습니다. 대표적으로 NaN (Not a Number), Infinity, -Infinity, -0 등이 있으며, 수치 계산의 안정성과 정확성에 큰 영향을 줍니다.

본 세미나에서는 부동소수점의 특별한 값들이 언제 발생하며, 어떤 동작을 하는지, 그리고 실무에서 어떻게 다뤄야 하는지를 초급부터 고급까지 설명합니다.


2. 기본 이론

2.1 NaN (Not a Number)

  • 정의되지 않은 계산 결과
  • 0을 0으로 나누거나, Math.Sqrt(-1) 등의 연산 시 발생
double nan1 = 0.0 / 0.0;
double nan2 = Math.Sqrt(-1);

Console.WriteLine(double.IsNaN(nan1)); // true

2.2 Infinity / -Infinity

  • 아주 큰 수를 넘어서거나, 0으로 나누기 시 발생
double posInf = 1.0 / 0.0;   // Infinity
double negInf = -1.0 / 0.0;  // -Infinity

Console.WriteLine(double.IsInfinity(posInf));  // true
Console.WriteLine(double.IsPositiveInfinity(posInf)); // true

2.3 -0 (음의 0)

  • double이나 float은 +0과 -0을 구분할 수 있음
  • 1.0 / -0.0-Infinity가 됨
double negZero = -0.0;
Console.WriteLine(1.0 / negZero); // -Infinity

3. 단계별 설명

3.1 초급: NaN과 Infinity 감지

float f = 0f / 0f;
if (float.IsNaN(f))
{
    Console.WriteLine("NaN 발생!");
}

float inf = 10f / 0f;
if (float.IsInfinity(inf))
{
    Console.WriteLine("Infinity 발생!");
}

3.2 중급: 비교 연산에서의 주의점

double x = double.NaN;
Console.WriteLine(x == double.NaN); // false (항상 false!)

// 올바른 방법:
Console.WriteLine(double.IsNaN(x)); // true
  • NaN은 자기 자신과도 같지 않음 (IEEE 754 규칙)
  • 비교 대신 IsNaN() 사용 필수

3.3 고급: 계산 전파 및 안정성 확보

double a = Math.Sqrt(-1); // NaN

double b = a + 5;         // NaN
Console.WriteLine(b);     // NaN
  • NaN이 한번 발생하면 대부분의 연산에서 결과도 NaN으로 전파됨
  • 수치 알고리즘에서 NaN 또는 Infinity 발생 여부를 중간에 점검해야 함

4. 주의사항 및 팁

  • decimal은 NaN, Infinity 등을 지원하지 않음 → 예외 발생
  • double.IsNaN(x) 또는 float.IsInfinity(x)로 명확한 확인 필요
  • UI 표시 시 "NaN" 또는 "∞"가 출력되므로 사용자에게 오해를 줄 수 있음
  • JSON, DB 저장 시 이 값들은 별도 처리 필요

5. 결론

  • 특별한 부동소수점 값은 C#의 수치 계산에서 반드시 고려해야 하는 요소
  • NaN, Infinity는 계산 오류 또는 특수 상태를 의미하며, 적절한 조건 검사를 통해 제어해야 함
  • == 비교가 통하지 않는다는 점을 유의하고, IsNaN, IsInfinity 등 전용 메서드를 사용하세요

6. Q&A

Q1. NaN은 왜 자기 자신과 같지 않나요?
A1. IEEE 754 표준에 따라 NaN은 어떤 수와도 같지 않다고 정의되어 있습니다. 이는 계산 오류의 전파 및 감지를 위해 설계된 동작입니다.

Q2. decimal에는 NaN이 없나요?
A2. 맞습니다. decimal 타입은 고정 소수점 기반이므로 NaN, Infinity 개념이 없고, 오류 시 예외를 던집니다.

Q3. Infinity 값을 비교할 수 있나요?
A3. 네, double.PositiveInfinity== 비교가 가능합니다.

Q4. NaN이 포함된 수식을 계속 계산하면 어떻게 되나요?
A4. NaN이 포함되면 결과는 대부분 NaN이 되어 전파됩니다.