부동소수점 표현 (Floating-Point Representation)
쉽게 풀면
줄자로 길이를 잴 때 눈금이 촘촘한 구간과 성긴 구간이 있으면 어떤 값은 정확히 재지고 어떤 값은 반올림해야 하는 것처럼, 컴퓨터도 무한히 많은 실수를 유한한 비트(0과 1) 안에 다 담을 수 없습니다.
그래서 과학적 표기법(예: 1.23 × 10³)과 비슷한 방식으로 숫자를 "부호(+/-) × 가수(유효숫자) × 2^지수" 형태로 쪼개서 근사값을 저장합니다. 이 방식이 바로 IEEE 754라는 국제 표준으로 정해진 부동소수점 표현입니다.
"부동(浮動, floating)"이라는 이름은 소수점의 위치가 지수에 따라 이리저리 움직인다는 뜻에서 왔습니다. 문제는 0.1처럼 간단해 보이는 십진수도 이진수로는 정확히 표현되지 않아 아주 작은 오차가 생긴다는 점입니다.
왜 중요한가
부동소수점 표현 방식과 정밀도 선택은 계산 결과의 정확도, 메모리 사용량, 연산 속도 사이의 근본적인 절충 관계를 결정합니다.
특히 대규모 딥러닝 모델 학습이나 과학 계산 분야에서는 어떤 정밀도(FP32, FP16, BF16 등)를 사용하는지가 학습 속도와 하드웨어 자원 소모, 최종 성능에 직접 영향을 미치기 때문에 논문에서 자주 명시적으로 다루는 요소입니다.
이 개념을 이해하면 왜 같은 알고리즘도 구현 방식에 따라 결과가 미세하게 달라지는지, 왜 특정 분야에서는 별도의 정밀 연산 방식을 쓰는지를 파악할 수 있습니다.
핵심 정리
- 정규화된 수는
(−1)s × 1.f × 2e − bias로 저장합니다. s는 부호 1비트, e는 지수, f는 소수부(가수)입니다. - 비트 배분은 형식마다 다릅니다. IEEE 754의 binary16(반정밀도)은 1+5+10비트, binary32(단정밀도)는 1+8+23, binary64(배정밀도)는 1+11+52입니다. 딥러닝에서 쓰는 bfloat16은 1+8+7로 지수는 FP32와 같고 가수만 줄였습니다(IEEE 표준 형식은 아님).
- 상대 오차의 크기는 기계 엡실론(1과 그 다음 수 사이의 간격)으로 가늠합니다. binary64는 2−52 ≈ 2.2×10−16, binary32는 2−23 ≈ 1.2×10−7, binary16은 2−10 ≈ 9.8×10−4입니다.
- 표현 가능한 최댓값은 binary16이 65,504, binary32가 약 3.4×1038, bfloat16이 약 3.4×1038입니다.
- NaN(수가 아님), ±∞, 0 근처의 비정규수 같은 특수한 값이 있고, 연산 결과는 기본적으로 가장 가까운 표현 가능한 값으로 반올림됩니다.
예시로 보기
파이썬(binary64)에서 직접 계산한 값입니다.
- 0.1을 이진수로 저장한 실제 값은 0.1000000000000000055511151231257827…으로 정확히 0.1이 아닙니다.
0.1 + 0.2의 결과는 0.30000000000000004입니다.- 0.1을 반복문으로 10번 더하면 1.0이 아니라 0.9999999999999999가 됩니다.
- 253 = 9,007,199,254,740,992 이상에서는 모든 정수를 표현할 수 없어서, 253에 1을 더해도 값이 변하지 않습니다.
이 오차는 오류가 아니라 유한한 비트로 실수를 표현하는 방식에서 오는 성질입니다. 같음을 비교할 때는 == 대신 허용 오차를 둔 비교를 쓰고, 금액처럼 십진 정확성이 필요하면 십진 형식을 씁니다.
자주 하는 오해
| 오해 | 바로잡기 |
|---|---|
| 정밀도(비트 수)를 늘리면 오차가 없어진다. | 오차가 줄어들 뿐, 0.1 같은 값은 어떤 이진 형식에서도 정확히 표현되지 않습니다. |
| FP16과 BF16은 같은 16비트라서 비슷하다. | FP16은 가수 10비트로 정밀하지만 범위가 좁고(최댓값 65,504), BF16은 지수 8비트로 FP32와 같은 범위를 가지는 대신 가수가 7비트라 정밀도가 낮습니다. |
| 배정밀도는 소수점 이하 15자리까지 정확하다. | 정밀도는 소수점 이하 자리가 아니라 유효숫자(약 15~17자리)로 말합니다. 큰 수에서는 소수 자릿수가 훨씬 적습니다. |
| 오차는 한 번의 연산에서만 생긴다. | 연산마다 반올림 오차가 생기고, 큰 수와 작은 수의 덧셈이나 비슷한 두 수의 뺄셈에서는 오차가 크게 드러납니다. 반복 계산에서 누적될 수 있습니다. |
논문에서는 이렇게 쓰입니다
실제 논문에서
이 용어를 직접 쓴 국내 논문 문장을 아직 수집하지 못했습니다. 수집되는 대로 출처와 함께 싣겠습니다.
예시 문장
아래는 용어의 쓰임을 보여 주려고 만든 예시로, 실제 논문에서 가져온 문장이 아닙니다.
이 문장은 딥러닝 모델을 훈련하거나 배포할 때 숫자를 저장하는 비트 수(정밀도)를 낮춰서 계산 속도와 메모리 효율을 높였다는 뜻입니다. 정밀도가 낮아지면 그만큼 반올림 오차는 커질 수 있습니다.
과학 계산 분야에서 오차 누적을 방지하기 위해 더 높은 정밀도를 선택한 예이다.
정밀도를 연산 단계별로 다르게 적용해 속도와 안정성을 함께 얻는 최근 딥러닝 학습 기법을 설명한 예이다.
조금 더 깊게 보면
IEEE 754 표준의 부동소수점 수는 부호, 지수, 가수 각각에 몇 비트를 할당하는지에 따라 표현 가능한 값의 범위와 정밀도가 달라지며, 예를 들어 FP16은 FP32보다 저장 공간은 절반이지만 표현할 수 있는 유효숫자와 범위가 좁아 오차와 오버플로우에 더 취약합니다.
이런 한계를 보완하기 위해 지수 범위는 FP32와 비슷하게 유지하면서 가수 비트를 줄인 BF16(bfloat16) 같은 대안적 형식도 딥러닝 하드웨어에서 널리 쓰입니다.
논문을 읽을 때는 저자가 어떤 정밀도를 사용했는지, 그리고 정밀도를 낮췄을 때 성능 저하를 어떻게 완화했는지(혼합정밀도 학습, 손실 스케일링 등)를 함께 살펴보면 결과 해석에 도움이 됩니다.
주의할 점
부동소수점 오차 때문에 프로그램에서 0.1 + 0.2를 계산하면 정확히 0.3이 아니라 0.30000000000000004처럼 미세하게 다른 값이 나올 수 있습니다. 이는 버그가 아니라 이진수와 진법변환 과정에서 생기는 근본적인 한계이며, 반복 계산이 누적되면 오차가 점점 커질 수 있으므로 금융 계산 등 정밀도가 중요한 분야에서는 별도의 처리 방식을 씁니다.
헷갈리기 쉬운 용어
| 용어 | 한 줄 설명 |
|---|---|
| 부동소수점 표현 | 부호·지수·가수로 실수를 근사해 저장하는 방식 자체 |
| 부동소수점 오차 | 그 표현 때문에 필연적으로 생기는 계산 오차 |
| 혼합정밀도 학습 | 연산 단계별로 16비트와 32비트를 섞어 쓰는 딥러닝 학습 기법 |
참고 문헌
- IEEE. (2019). IEEE Standard for Floating-Point Arithmetic (IEEE Std 754-2019). Institute of Electrical and Electronics Engineers.
- Goldberg, D. (1991). What every computer scientist should know about floating-point arithmetic. ACM Computing Surveys, 23(1), 5–48.
- Higham, N. J. (2002). Accuracy and Stability of Numerical Algorithms (2nd ed.). SIAM.
- Micikevicius, P., Narang, S., Alben, J., Diamos, G., Elsen, E., Garcia, D., Ginsburg, B., Houston, M., Kuchaiev, O., Venkatesh, G., & Wu, H. (2018). Mixed precision training. International Conference on Learning Representations.
표의 기준값은 위 문헌에 근거한 관례이며, 분야·학술지마다 다른 기준을 쓸 수 있습니다.