본문 바로가기
Frontend2026년 7월 4일4분 읽기

0.1 + 0.2 는 왜 0.3이 아닌가 — 부동소수점과 돈 계산

YS
김영삼
조회 684
0.1 + 0.2 는 왜 0.3이 아닌가 — 부동소수점과 돈 계산

핵심 요약

0.1 + 0.2 === 0.3false인 건 언어 버그가 아니라 IEEE 754 부동소수점의 본질이다. 0.1과 0.2는 2진법으로 정확히 표현할 수 없어 아주 작은 오차가 생긴다. 이건 JS만이 아니라 파이썬·자바 등 거의 모든 언어에서 같다. 돈처럼 정확해야 하는 값엔 float를 쓰면 안 된다.

1. 왜 오차가 생기나

10진법 0.1은 2진법으로 0.00011001100110011...처럼 무한 반복된다. 컴퓨터는 64비트 안에 잘라 담으므로 근사값이 저장되고, 계산 시 그 오차가 드러난다.

0.1 + 0.2          // 0.30000000000000004
0.1 + 0.2 === 0.3  // false
0.3 - 0.1          // 0.19999999999999998

2. 비교는 어떻게

// ❌ 직접 비교 금지
if (a === 0.3) ...

// ✅ 허용 오차(epsilon)로 비교
const eq = (a, b) => Math.abs(a - b) < Number.EPSILON
eq(0.1 + 0.2, 0.3)  // true

3. 돈 계산은 정수로

가장 확실한 방법은 최소 단위(원·센트)를 정수로 다루는 것이다.

// 12,345.67원을 1234567(전) 정수로 저장
const price = 1234567     // 원 단위 정수
const total = price * qty // 정수 연산은 정확
// 표시할 때만 나눠서 포맷

4. 표시·반올림

목적방법
자리수 표시(0.1+0.2).toFixed(2) → "0.30"
통화 포맷Intl.NumberFormat('ko-KR',{style:'currency',currency:'KRW'})
정밀 계산decimal.js·big.js 라이브러리

5. 함정

  • toFixed는 문자열을 반환하고 반올림도 은근히 부정확할 수 있다 — 금융 계산엔 decimal 라이브러리
  • DB에 돈을 float/double로 저장하면 같은 문제 — DECIMAL/NUMERIC을 쓴다
  • 큰 정수는 Number.MAX_SAFE_INTEGER를 넘으면 부정확 — 그땐 BigInt

자주 묻는 질문

이게 JavaScript만의 문제인가요?

아니요. IEEE 754 부동소수점을 쓰는 거의 모든 언어(파이썬·자바·C 등)에서 동일하게 발생합니다. JS가 특히 눈에 띄는 건 웹에서 계산을 자주 보여주기 때문일 뿐, 원리는 공통입니다.

돈은 무조건 정수로 저장해야 하나요?

가장 안전한 방법입니다. 원 단위 정수(또는 센트 정수)로 저장·계산하고 표시할 때만 포맷하면 오차가 없습니다. 소수 단위나 복잡한 이자 계산이 필요하면 decimal.js 같은 고정소수점 라이브러리를 쓰세요.

toFixed(2)로 반올림하면 충분하지 않나요?

표시용으론 대체로 괜찮지만 toFixed는 문자열을 반환하고 경계값에서 반올림이 예상과 다를 수 있습니다. 화면 표시엔 Intl.NumberFormat, 실제 금액 계산엔 정수·decimal을 쓰는 게 안전합니다.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록