liminfo

IEEE 754 부동소수점

IEEE 754 부동소수점 표현, 특수값, 반올림 규칙 레퍼런스

29개 결과

IEEE 754 부동소수점 소개

IEEE 754 레퍼런스는 IEEE 754-2008 부동소수점 연산 표준을 검색할 수 있는 빠른 참조 도구입니다. 단정밀도, 배정밀도, 특수값, 반올림, 비교, 변환의 여섯 가지 카테고리로 정리되어 있어 소프트웨어 엔지니어, 컴퓨터 공학 학생, 수치 계산 연구자, 임베디드 개발자가 부동소수점 연산을 이해하고 디버깅하며 올바르게 구현하는 데 필요한 비트 수준의 세부 정보와 코드 예제를 즉시 찾을 수 있습니다.

프로그래머들은 float(부호 1 + 지수 8 + 가수 23비트, 바이어스 127)와 double(부호 1 + 지수 11 + 가수 52비트, 바이어스 1023)의 정확한 비트 레이아웃, 1.0(0x3F800000) 같은 표준 값의 16진수 표현, 0.1이 정확히 표현될 수 없는 이유(가장 가까운 float 근사값은 0x3DCCCCCD), JavaScript의 MAX_SAFE_INTEGER 한계(2^53 - 1 = 9007199254740991)를 이 레퍼런스로 확인합니다. 머신 엡실론, 점진적 언더플로를 위한 비정규화수, 조용한 NaN과 신호 NaN의 차이도 다룹니다.

비교와 변환 카테고리는 실제 프로그래밍 함정을 다룹니다. 부동소수점 숫자에서 == 비교가 실패하는 이유와 엡실론 또는 ULP 기반 비교 방법, 부동소수점 오차 누적을 O(n*eps)에서 O(eps)로 줄이기 위한 Kahan 보상 합산 구현, 10진수를 IEEE 754 비트 패턴으로 단계별 변환하는 방법, memcpy 또는 struct.pack을 사용한 타입 퍼닝으로 float 비트를 정수로 재해석하는 방법을 설명합니다.

주요 기능

  • 단정밀도(float, 32비트): 부호 + 지수(바이어스 127) + 가수 레이아웃, 표현 범위, 1.0·-0.5·0.1 예시
  • 배정밀도(double, 64비트): 부호 + 지수(바이어스 1023) + 가수 레이아웃, 범위, 머신 엡실론(2^-52), MAX_SAFE_INTEGER
  • 특수값: +0과 -0(==에서는 같지만 1/x에서 다름), +/-Infinity, NaN(조용한 NaN vs 신호 NaN), 비정규화수
  • 5가지 IEEE 754 반올림 모드: 반올림-짝수(은행가 반올림), +무한대 방향(ceil), -무한대 방향(floor), 0 방향(trunc), 중간값-멀리
  • 부동소수점 비교: 엡실론 기반 동등성, 상대 오차 비교, NaN 순서를 위한 totalOrder, ULP 간격 계산
  • 부동소수점 오차 누적을 O(n*eps)에서 O(eps)로 줄이는 Kahan 보상 합산 알고리즘
  • 10진수 → IEEE 754 변환: 단계별 부호, 정수부, 소수부, 정규화, 바이어스 지수 계산
  • 타입 퍼닝: C에서 memcpy 기반 비트 재해석, Python에서 struct.pack/unpack, 16진수 float 리터럴(0x1.8p1)

자주 묻는 질문

부동소수점 연산에서 0.1 + 0.2가 0.3이 아닌 이유는?

0.1과 0.2는 2진 부동소수점으로 정확히 표현할 수 없습니다. 0.1에 가장 가까운 float는 0x3DCCCCCD(약 0.100000001490116)이고, 0.2도 유사한 오차가 있습니다. 더하면 누적된 반올림 오차로 인해 결과가 0.3에 가장 가까운 float와 달라집니다. 이는 2진 부동소수점의 근본적인 특성으로 버그가 아닙니다. 동등성 비교에는 a === b 대신 Math.abs(a - b) < epsilon을 사용하세요.

IEEE 754에서 +0과 -0의 차이는 무엇인가요?

+0과 -0은 서로 다른 비트 패턴입니다. +0은 모든 비트가 0이고, -0은 부호 비트만 1입니다. 하지만 비교에서 +0 === -0은 true입니다. 차이는 나눗셈에서만 관찰됩니다: 1 / +0 = +Infinity, 1 / -0 = -Infinity. Math.atan2 같은 함수도 두 0에 대해 다르게 정의됩니다. 대부분의 코드에서는 구분할 필요가 없지만 수치 해석 라이브러리에서 부호 있는 0의 동작에 의존하는 경우가 있습니다.

NaN이란 무엇이고 왜 NaN != NaN인가요?

NaN(Not a Number)은 0/0, sqrt(-1), Infinity - Infinity 같은 정의되지 않은 부동소수점 연산의 결과입니다. IEEE 754에서 NaN은 자기 자신을 포함한 모든 값에 대해 순서가 없도록 정의되어 있어 NaN < 1, NaN > 1, NaN == NaN이 모두 false입니다. 이것은 의도적인 설계로, C의 isnan() 또는 JavaScript의 Number.isNaN()을 사용한 명시적 검사를 강제합니다. 조용한 NaN(qNaN)은 계산을 통해 조용히 전파되고, 신호 NaN(sNaN)은 부동소수점 예외를 트리거합니다.

머신 엡실론이란 무엇이고 왜 중요한가요?

머신 엡실론은 부동소수점 시스템에서 1.0 + e != 1.0이 되는 가장 작은 e입니다. float에서는 2^-23(약 1.19e-7), double에서는 2^-52(약 2.22e-16)입니다. 이는 형식의 상대적 정밀도를 정의합니다. 엡실론보다 작은 상대 오차로 계산된 값은 실제 결과와 구별할 수 없습니다. 엡실론 비교의 허용 오차로 사용합니다: abs(a - b) <= epsilon * max(abs(a), abs(b))이면 "부동소수점 정밀도 내에서 같음"으로 간주합니다.

IEEE 754의 5가지 반올림 모드는 무엇인가요?

반올림-짝수(기본값, 은행가 반올림)는 가장 가까운 표현 가능한 값으로 반올림하고, 정확한 중간값에서는 최하위 비트가 짝수인 값으로 반올림하여 통계적 편향을 최소화합니다. +무한대 방향(올림)은 항상 올립니다. -무한대 방향(내림)은 항상 내립니다. 0 방향(절삭)은 소수부를 0 방향으로 버립니다. 중간값-멀리는 중간값을 0에서 먼 쪽으로 반올림하여 학교에서 배우는 일반적인 반올림 규칙과 일치합니다(IEEE 754-2008에서 추가).

ULP란 무엇이고 부동소수점 비교에 어떻게 활용하나요?

ULP(마지막 자리 단위)는 부동소수점 수와 다음 표현 가능한 수 사이의 간격입니다. float에서 1.0의 ULP = 2^-23 ≈ 1.19e-7입니다. 큰 값에서는 ULP도 비례하여 커집니다: float에서 ULP(1e6) ≈ 0.0625로, 1000000.0 다음의 float는 1000000.0625입니다. ULP 기반 비교는 두 float의 정수 비트 표현을 비교하여 N ULP 이내인지 확인합니다. 크기가 크게 다른 값에서 엡실론 기반 비교보다 더 견고합니다.

Kahan 보상 합산은 부동소수점 오차를 어떻게 줄이나요?

N개의 수를 단순 합산하면 N * machine_epsilon * sum에 비례하는 오차가 누적됩니다(O(n*eps)). Kahan 합산은 각 덧셈에서 손실된 하위 비트를 추적하는 보상 변수 c를 유지합니다. 각 덧셈 전에 c를 빼서 다음 항을 수정합니다. 보상은 이전 단계의 반올림 오차를 포착하여 다음 항에 다시 추가합니다. 결과는 N에 관계없이 O(eps) 오차를 가집니다. 대형 부동소수점 배열을 합산할 때 필수적입니다.

10진수를 IEEE 754 float 비트 표현으로 변환하는 방법은?

-6.75를 예로 들면: (1) 부호 비트 결정(음수이므로 1). (2) 크기를 2진수로 변환: 6 = 110(2), 0.75 = 0.11(2), 따라서 6.75 = 110.11(2). (3) 1.M 형태로 정규화: 1.1011 x 2^2. (4) 바이어스 지수 계산: 2 + 127 = 129 = 10000001(2). (5) 가수 비트는 10110...0(23비트). (6) 조합: 1 10000001 10110000000000000000000 = 0xC0D80000.