컴퓨터가 소수점을 저장하는 방식: IEEE‑754부터 금융용 Decimal까지 완전 정복
SEO 키워드: 컴퓨터, 소수점 저장, IEEE‑754
# 📌 서론 – “왜 컴퓨터는 0.1을 정확히 표현하지 못할까?”
우리는 일상에서 0.1, 0.25, 3.14159 같은 소수점을 자유롭게 사용합니다. 하지만 프로그래밍을 할 때 “0.1 + 0.2가 0.3이 아니다”는 오류를 마주하면 당황하곤 하죠.
이 현상의 근본 원인은 컴퓨터가 소수를 이진수(0과 1) 형태로만 저장한다는 점에 있습니다.
본 글에서는
IEEE‑754 부동소수점이 어떻게 동작하는지,
왜 정확히 표현되지 않는가에 대한 원리,
금융·회계에 특화된 Decimal 타입이 어떻게 문제를 해결하는지
를 차근차근 풀어 설명합니다. 초보자도 이해할 수 있도록 그림과 예시를 풍부하게 넣었으니, 끝까지 읽고 직접 실습해 보세요!
# 1️⃣ IEEE‑754 부동소수점 – 컴퓨터의 기본 소수 저장 방식
# 1-1. 구조 살펴보기
IEEE‑754는 부동소수점(Floating‑Point) 표준으로, 현재 대부분의 프로그래밍 언어와 하드웨어가 따릅니다. 가장 흔한 double(64비트) 형식은 다음과 같이 구성됩니다.
| 비트 | 의미 | 비고 |
|------|------|------|
| 1 | 부호 비트 (Sign) | 0 = 양수, 1 = 음수 |
| 11 | 지수 (Exponent) | 바이어스(1023) 적용 |
| 52 | 가수 (Mantissa) | 숨겨진 1을 포함한 정밀도 15~17자리 |
예시:
0.15625를 IEEE‑754 double 로 변환하면
부호 = 0
지수 = 1023‑4 = 1019 (binary
01111111101)가수 =
010100000000…
# 1-2. 왜 0.1은 정확히 표현되지 않을까?
10진수 0.1 은 이진수로 무한히 반복되는 소수입니다.
0.1 (10진) = 0.000110011001100… (2진) // 무한 반복
IEEE‑754는 52비트 가수만 저장하므로, 무한히 이어지는 비트를 잘라 버립니다. 그 결과 실제 저장값은 0.10000000000000000555… 가 되며, 연산 시 오차가 누적됩니다.
# 1-3. 부동소수점 연산에서 흔히 보는 오류 사례
| 코드 (Python) | 기대값 | 실제값 |
|---------------|--------|--------|
| 0.1 + 0.2 | 0.3 | 0.30000000000000004 |
| 1.0/3.0 | 0.333…| 0.3333333333333333 |
오차는 작지만 금융·과학 계산에서는 치명적일 수 있습니다.
# 2️⃣ Decimal 타입 – 금융·회계에 최적화된 정확한 소수
# 2-1. Decimal이란?
Decimal(또는 BCD(Binary‑Coded Decimal))은 10진수 자리마다 4비트를 할당해 10진수를 그대로 저장합니다. 대표적인 구현은
C#
decimal(128비트, 28~29자리 정확도)Java
java.math.BigDecimalPython
decimal.Decimal
# 2-2. Decimal의 내부 구조
| 비트 | 의미 |
|------|------|
| 1 | 부호 |
| 96 | 10진수 정수 부분 (3×32비트) |
| 8 | 스케일(소수점 이하 자리수, 0~28) |
| 23 | 예약 비트(0) |
예를 들어 123.45 를 저장하면
정수 부분 =
12345스케일 =
2(소수점 이하 2자리)
이렇게 하면 오차 없이 정확히 표현할 수 있습니다.
# 2-3. 언제 Decimal을 사용해야 할까?
| 상황 | 권장 타입 |
|------|-----------|
| 은행·회계 시스템 (이자, 세금) | Decimal / BigDecimal |
| 과학·공학 시뮬레이션 (대규모 연산) | IEEE‑754 double |
| 그래픽·게임 물리 엔진 | IEEE‑754 float (단일 정밀도) |
특히 법적·재무 보고에서는 “소수점 오차가 0.01원이라도 안 된다”는 규정이 있기 때문에 Decimal이 필수입니다.
# 3️⃣ 실전 팁 – 부동소수점과 Decimal을 현명하게 선택하기
오차 허용 범위 정의
Math.abs(a - b) < 1e-9와 같이 허용 오차를 명시하면 부동소수점 오류를 감출 수 있습니다.
연산 순서 최적화
- 큰 수와 작은 수를 더할 때 작은 수가 소멸될 위험이 있으니, 작은 수부터 더하기가 안전합니다.
Decimal 변환 비용 고려
Decimal은 메모리와 연산 속도가 부동소수점보다 무겁습니다.
핵심 로직은 double로 빠르게 처리하고, 결과 출력·저장 단계에서 Decimal로 변환하는 전략을 쓰세요.
라이브러리 활용
Python:
from decimal import Decimal, getcontext→getcontext().prec = 28Java:
BigDecimal.valueOf(0.1).add(BigDecimal.valueOf(0.2))
# 4️⃣ 결론 – 올바른 소수 저장으로 신뢰성을 높이자
컴퓨터는 이진수 기반이기 때문에 10진 소수를 완벽히 표현하지 못합니다. 하지만 IEEE‑754는 일반적인 과학·공학 계산에 충분히 빠르고 효율적인 반면, Decimal은 금융·회계처럼 정확도가 생명인 분야에 최적화돼 있습니다.
핵심 포인트
부동소수점은 정밀도 손실이 발생한다 → 오차 허용 범위와 연산 순서에 주의.
Decimal은 정확한 10진 표현을 제공 → 비용을 감수하고 사용해야 하는 상황을 명확히 구분.
# 📣 행동 유도
1️⃣ 오늘 작성 중인 재무·회계 코드가 있다면, float/double 대신 Decimal(또는 BigDecimal)로 교체해 보세요.
2️⃣ 연산 테스트를 직접 해보세요.
python
from decimal import Decimal
print(Decimal('0.1') + Decimal('0.2')) # 0.3 정확히 출력
3️⃣ 블로그 댓글에 당신이 겪은 소수점 오류 사례를 공유하면, 함께 해결책을 찾아볼 수 있습니다!
이 글이 도움이 되었다면, SNS·카카오톡으로 공유하고, 다음 포스트에서는 “부동소수점 연산 최적화 팁”을 다룰 예정이니 구독과 알림 설정도 잊지 마세요!
Comments
Join the discussionNo comments yet. Be the first to comment.