IEEE 754 부동소수점: 비트에서 숫자까지
IEEE 754 binary32와 binary64를 해독합니다. 부호, 바이어스 지수, 후행 유효숫자, 특수값, 반올림, 비결합 산술을 살펴봅니다.
요약: 정규 이진값에서 IEEE 754는 를 사용합니다. 즉 부호 비트, 바이어스 지수, 암묵적인 선행 1을 갖는 후행 유효숫자 필드입니다. 예약된 지수 패턴은 부호 있는 0, 서브노멀, 무한대, NaN을 인코딩합니다. 대부분의 정확한 실수 결과는 유한한 형식으로 반올림해야 하므로 부동소수점 덧셈과 곱셈은 일반적으로 결합법칙을 만족하지 않습니다.
범위와 스케일을 알고 있을 때는 고정소수점 이진 표현이 잘 작동합니다. 그러나 한 계산에서 자릿수가 여러 차수만큼 다른 값을 다뤄야 하면 불편해집니다. 예를 들어 소수부가 16비트인 부호 있는 32비트 고정소수점 값은 간격이 이고 범위는 약 에서 입니다.
부동소수점은 일부 비트를 지수에 할당하여, 크기에 따라 기수점이 움직이게 합니다. IEEE 754는 1985년에 처음 발행되었으며, 현재 개정판은 IEEE 754-2019입니다. 이 표준은 이진 및 십진 형식, 연산, 반올림, 예외, 교환 동작을 정의합니다. 구현은 하드웨어, 소프트웨어 또는 둘의 조합일 수 있으므로, 표준을 준수한다고 해서 모든 CPU가 모든 형식을 실리콘에 갖추고 있음을 뜻하지는 않습니다.
부동소수점이 필요한 이유
과학적 표기법은 종이 위에서 같은 문제를 해결합니다. 은 작은 유효숫자와 큰 지수를 분리합니다. IEEE 754는 각 부분에 몇 비트를 배정하고 어떻게 인코딩할지를 엄격한 규칙으로 정한 이진 과학적 표기법입니다.
이 형식은 두 가지 설계 압력으로 형태가 결정됩니다.
- 명시된 인코딩과 연산. 하나의 수학적 값에 하나의 비트 패턴만 대응하는 것은 아닙니다. 0에는 두 부호가 있고 NaN에는 많은 페이로드 인코딩이 있습니다. 표준은 연산과 비교가 이들을 어떻게 처리하는지 정의합니다.
- 구현 가능한 산술. 지수 비교와 유효숫자 정렬은, 반올림과 예외 동작이 명시된 유한한 하드웨어 또는 소프트웨어 알고리즘으로 구현되어야 합니다.
두 요구를 모두 충족하기 위해 선택한 절충, 즉 바이어스 지수, 암묵적인 선행 비트, 특수 용도의 지수 코드는 IEEE 754에 고유한 형태를 부여합니다.
단정밀도 레이아웃(32비트)
| 31 | 30 ............ 23 | 22 ........................... 0 |
| s | e (8 bits) | m (23 bits) |
| 1 | | |
- 부호 비트 : 1비트입니다. 0은 음이 아님을, 1은 음수를 뜻합니다.
- 지수 : 8비트이며, 바이어스 127을 가진 부호 없는 정수로 저장합니다.
- 후행 유효숫자 필드 : 23비트입니다. 정규수에서는 암묵적인 선행 1 뒤의 분수를 저장합니다.
정규화된 수(일반적인 경우)의 값은 다음과 같습니다.
유효숫자의 ""는 암묵적입니다. 정규화된 모든 이진수는 지수를 선택하면 선행 1을 갖도록 쓸 수 있기 때문에, 이 형식은 비트 하나를 절약합니다.
배정밀도 레이아웃(64비트)
구조는 같지만 필드가 더 넓습니다.
| 63 | 62 ........... 52 | 51 ............................. 0 |
| s | e (11 bits) | m (52 bits) |
- 부호 비트 : 1비트입니다.
- 지수 : 11비트, 바이어스는 1023입니다.
- 후행 유효숫자 필드 : 52비트입니다.
값(정규화됨):
범위는 약 이며, 유효 십진 자릿수는 약 15~17자리입니다.
지수에 바이어스를 두는 이유
지수를 2의 보수가 아니라 로 저장하면 미묘하지만 중요한 이점이 있습니다. 부동소수점 비교가 비트 패턴의 정수 비교(부호 비트 반전 포함)로 환원됩니다. 음이 아닌 두 부동소수점을 32비트 부호 없는 정수로 비교하면 더 큰 부동소수점이 더 큰 정수입니다. 2의 보수 지수는 양수와 음수 지수의 경계에서 이 단조 관계를 깨뜨립니다.
모두 0인 지수 필드는 0과 서브노멀에, 모두 1인 필드는 무한대와 NaN에 예약됩니다. binary32에서 1부터 254까지의 정규 지수 필드는 바이어스가 제거된 지수 부터 에 대응합니다.
특수한 경우
| 지수 비트 | 후행 유효숫자 비트 | 의미 |
|---|---|---|
| 모두 0 | 모두 0 | (부호 비트가 어느 쪽인지 결정) |
| 모두 0 | 0이 아님 | 서브노멀 |
| 중간의 모든 값 | 모든 값 | 정규화된 수 |
| 모두 1 | 모두 0 | |
| 모두 1 | 0이 아님 | NaN(숫자가 아님) |
0에는 두 인코딩(과 )이 있습니다. IEEE 비교에서는 같지만, 일부 연산에서는 서로 다른 부호의 결과를 냅니다(예: , ).
서브노멀(과거에는 비정규수라고도 함)은 0과 가장 작은 정규수 사이의 간격을 메웁니다. 암묵적인 선행 1은 0이 되고, binary32는 유효 지수 을 사용합니다. 이로써 점진적 언더플로가 제공됩니다. 서브노멀 범위에서는 절대 간격이 일정하게 유지되는 반면, 상대 정밀도는 0에 가까워질수록 낮아집니다.
무한대는 오버플로 또는 0으로 나누기에서 발생합니다. 산술 연산을 통해 직관적인 방식으로 전파됩니다. 즉 , 입니다.
NaN은 잘못된 연산을 나타냅니다. 예를 들어 , , 가 그렇습니다. NaN은 전염성이 있어 NaN이 포함된 모든 산술은 NaN을 산출합니다. 중요한 점은 IEEE 754 비교에서 이므로, 테스트 모음은 ==가 아니라 isnan()을 사용합니다.
예제: 0x40490FDB 디코딩
널리 알려진 32비트 상수입니다. 이진수로 쓰면 다음과 같습니다.
0x40490FDB = 0100 0000 0100 1001 0000 1111 1101 1011
필드로 나누면 다음과 같습니다.
- 부호:
0— 양수 - 지수:
1000 0000= — 실제 지수 - 후행 유효숫자:
100 1001 0000 1111 1101 1011
유효숫자는 , 즉 다음과 같습니다.
저장된 분수를 계산하면 다음과 같습니다.
따라서 유효숫자는 입니다. 여기에 을 곱하면 다음과 같습니다.
이는 단정밀도 정확도의 입니다. 상수 0x40490FDB는 의 표준 IEEE 754 단정밀도 인코딩이며, 전 세계의 수치 라이브러리, GPU 셰이더, 시험 문제에 등장합니다.
예제: 5.75 인코딩
를 단정밀도 IEEE 754로 변환합니다.
1단계: 이진수로 변환합니다. 입니다. 입니다. 합치면 입니다.
2단계: 정규화합니다. 이진점 왼쪽에 정확히 한 자리만 남도록 이진점을 왼쪽으로 옮깁니다.
따라서 실제 지수는 입니다.
3단계: 각 필드를 인코딩합니다.
- 부호: 양수이므로 입니다.
- 지수: 실제 + 바이어스 = =
1000 0001. - 후행 유효숫자: 선행 1을 버리고 다음 23비트를 저장합니다.
0111뒤에 0이 19개, 즉01110000 00000000 0000000입니다.
4단계: 조립합니다.
0 | 10000001 | 01110000000000000000000
16진수로는 0x40B80000입니다. 이 패턴에 디코딩 절차를 거꾸로 적용해 정확히 5.75를 복원하여 확인할 수 있습니다.
5.75에는 정확한 이진 표현이 있다는 점에 유의하세요. 소수부는 2의 음의 거듭제곱 합()입니다. 대부분의 십진 소수는 그렇지 않습니다. 단정밀도에서 은 0x3DCCCCCD이며, 다시 디코딩하면 가 되어 약 만큼 차이 납니다. 이 작은 오차가 초보자가 마주치는 모든 "" 놀라움의 근본 원인입니다.
반올림 방향
IEEE 754-2019는 다섯 가지 반올림 방향 속성을 정의합니다.
- 가장 가까운 값으로 반올림, 동점이면 짝수 쪽. 기본값입니다. 표현 가능한 값 중 더 가까운 값을 선택하고, 동점이면 최하위 유효숫자 비트가 0인 값을 선택합니다.
- 가장 가까운 값으로 반올림, 동점이면 0에서 멀어지는 쪽. 이 속성은 특히 십진 산술과 관련되며 모든 이진 부동소수점 환경에서 노출되지는 않습니다.
- 0을 향해 반올림(버림).
- 를 향해 반올림(올림).
- 를 향해 반올림(내림).
기본 모드는 통계적 편향을 최소화합니다. 단순한 “5 이상 올림”은 많은 값을 누적할 때 약간의 상향 편향을 만들지만, 반올림-동점-짝수 방식은 평균적으로 이를 상쇄합니다.
애플리케이션이 선택할 수 있는 방향은 언어, 런타임, 컴파일러, 하드웨어 환경에 따라 달라집니다. 재현성 역시 선택한 반올림 방향뿐 아니라 평가 순서, 중간 정밀도, 융합 연산, 라이브러리 함수, 서브노멀 처리에 좌우됩니다.
부동소수점 산술이 결합적이지 않은 이유
세 IEEE 754 단정밀도 값 을 생각해 봅시다.
: 먼저 이 정확히 성립합니다(상쇄가 깔끔합니다). 이어서 입니다. 최종 결과는 입니다.
: 먼저 를 계산합니다. 의 지수는 약 67이고 의 지수는 0입니다. 유효숫자를 정렬하면 는 binary32 정밀도보다 한참 밖으로 밀려납니다. 반올림 후에는 입니다. 그러면 입니다.
두 괄호 묶음이 서로 다른 답을 내므로 부동소수점 덧셈은 결합적이지 않습니다. 컴파일러가 식을 재결합해도 되는지는 언어 규칙, 구현, 최적화 플래그, 부동소수점 환경에 따라 달라집니다. 재현성에 민감한 코드는 하나의 컴파일러 플래그를 보편적인 보증으로 믿기보다 이러한 선택을 문서화하고 실제 도구 체인을 시험해야 합니다.
같은 성질은 뺄셈(상쇄 경우), 곱셈(매우 작은 곱은 0으로 언더플로할 수 있음), 나눗셈(매우 작은 수로 나누면 무한대로 오버플로할 수 있음)에도 적용됩니다.
하드웨어: FPU
하드웨어 부동소수점 가산기는 보통 다음과 같은 단계를 수행합니다. FPU가 없는 프로세서도 소프트웨어로 같은 의미론을 구현할 수 있습니다.
- 두 피연산자의 필드를 디코딩합니다.
- 지수를 비교하고, 더 작은 지수의 유효숫자를 차이만큼 오른쪽으로 이동합니다. 이때 반올림을 위해 가드 비트, 라운드 비트, 스티키 비트를 보존합니다.
- 정렬된 유효숫자를 더하거나 뺍니다(넓은 캐리 룩어헤드 방식 가산기를 사용).
- 선행 1이 나올 때까지 왼쪽으로 이동하여 결과를 정규화하고, 그에 맞춰 지수를 조정합니다.
- 현재 반올림 모드에 따라 반올림합니다.
- 결과를 IEEE 754 형식으로 인코딩합니다.
데이터패스에는 지수 비교, 유효숫자 정렬, 덧셈/뺄셈 논리, 선행 0 검출, 정규화, 반올림, 특수 사례 처리, 예외 보고가 필요합니다. RISC-V의 F 확장은 binary32 명령어를 정의하고 D는 binary64를 추가합니다. 둘 다 선택 사항이므로, 표준 형식과 필수 하드웨어의 차이를 보여 줍니다.
유효숫자 경로는 이진 산술 기법을 재사용하지만, FPU는 배선이 조금 더 붙은 정수 ALU 이상입니다. 반올림, 점진적 언더플로, NaN, 무한대, 부호 있는 0, 예외는 모두 아키텍처 동작의 일부입니다.
더 넓은 형식
IEEE 754는 단정밀도와 배정밀도 외에도 다음을 정의합니다.
- 반정밀도(binary16): 부호 1 + 지수 5 + 후행 유효숫자 비트 10입니다. 그래픽스와 정밀도를 낮춘 수치 작업에 사용됩니다.
- 4배 정밀도(128비트): 1 + 15 + 112입니다. 드물며 수치 해석과 일부 금융 계산에 사용됩니다.
- bfloat16(IEEE 754 기본 교환 형식 아님): 1 + 8 + 7입니다. binary32와 비슷한 지수 범위를 훨씬 낮은 정밀도로 유지하며, 기계 학습에 널리 쓰입니다.
각 변형은 대상 작업 부하에 맞춰 범위와 정밀도를 절충합니다.
흔한 함정
- 오차 모델 없이
==사용하기. 일부 불변 조건과 이산값에는 정확한 비교가 옳지만, 근삿값에는 영역별 절대/상대 허용오차 또는 최종 자릿수 단위 정책이 필요합니다. NaN != NaN을 잊기. NaN 검출에는isnan()을 사용합니다.- 결합법칙을 가정하기. 합의 순서를 바꾸면 답이 달라질 수 있습니다. 컴파일러 플래그가 안전하지 않은 재결합을 허용할 수 있으므로, 사용 전에 이해해야 합니다.
- 십진과 이진의 직관을 섞기. 은 정확한 유한 이진 표현이 없습니다. 십진 비즈니스 규칙에는 스케일 정수, 십진 부동소수점 또는 BCD를 고려하고, 그래도 필요한 각 경계에서 반올림을 정의해야 합니다.
- 서브노멀 성능을 가정하기. 일부 프로세서는 서브노멀을 전속도로 처리하지만, 다른 프로세서에서는 성능 저하가 있거나 0으로 플러시하는 모드를 지원합니다. 대상에서 측정하고 정확성이 필요할 때는 점진적 언더플로를 보존하세요.
더 넓은 CPU 아키텍처와 연결하기
레지스터 구성은 ISA에 따라 다릅니다. 어떤 아키텍처는 정수와 부동소수점 레지스터 파일을 분리하고, 다른 아키텍처는 상태의 일부를 겹치거나 통합합니다. 로드, 스토어, 변환, 이동, 호출 규약이 그 경계를 정의합니다.
더 넓은 산술에서 정수 측은 대상에 맞게 확장하고 최적화한 8비트 가산기와 관련된 구조에 의존합니다. 부동소수점 측은 정렬, 정규화, 반올림, 예외, 특수값 처리를 더합니다.
다음 단계
고정 폭 부호 있는 정수는 2의 보수 설명에서, 자릿수 중심의 십진 인코딩은 BCD: 이진화 십진수 기초에서 계속 살펴보세요.
비트 수준에서 실험하려면 유효숫자 산술에 ALU 스타일의 데이터패스를 사용한 다음, 정렬, 정규화, 가드/라운드/스티키 비트, 특수 사례를 별도 단계로 모델링해 보세요.
규범적 참조 자료는 현재 유효한 IEEE 754-2019 부동소수점 산술 표준입니다.
