0.1 + 0.2가 0.3이 아니라고?
"0.1 + 0.2가 0.3이 아니라고?" 프론트엔드 개발을 하다 보면 한 번쯤은 마주하게 되는 순간입니다. JavaScript의 부동소수점 연산 이슈의 원인과 실무에서 활용할 수 있는 해결책들에 대해 정리해두어 같은 이슈를 만났을 때 당황하지 않고 해결하고자 합니다.
문제의 발견
console.log(0.1 + 0.2 === 0.3); // false
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 + 0.3); // 0.6000000000000001
console.log(0.1 * 3); // 0.30000000000000004
console.log(0.3 - 0.1); // 0.19999999999999998JavaScript가 수학을 못한다고 생각할 수 있지만, 결론부터 이야기하면 컴퓨터 연산의 근본적인 한계 때문입니다.
JavaScript 64비트 숫자의 한계(부동소수점과 고정소수점)
1. 이진법 표현의 한계
컴퓨터는 모든 것을 이진법으로 처리합니다. 십진법에서 간단한 0.1도 이진법으로는 무한소수가 됩니다. 0.1 (십진법) = 0.0001100110011001100... (이진법) JavaScript는 IEEE 754 표준에 따라 64비트로 숫자를 저장하는데, 무한소수를 유한한 비트로 표현하다 보니 반올림 오차가 발생합니다.
2. 부동소수점 구조
64비트 부동소수점은 다음과 같이 구성됩니다:
부호 비트: 1비트 (양수/음수)
지수 비트: 11비트 (범위 결정)
가수 비트: 52비트 (정밀도 결정)
모든 십진수를 정확히 표현할 수는 없습니다.(Number.MAX_SAFE_INTEGER는 16자리, 15자리는 안전)
실무에서 마주하는 상황들
1. 가격 계산
2. 좌표 계산
3. 금융 계산
해결방법?
소수점 자리 제한
정수 변환
라이브러리 사용(big.js, decimal.js 등)
배열 기반 십진수 표현
자바스크립트만 그럴까?
부동소수점 이슈는 JavaScript만의 버그가 아니라 근본적인 특성입니다. Java와 같은 언어들도 같은 상황에서의 문제가 발생하고 있는데요. 중요한 것은 이 한계와 쓰임을 알고 적절한 해결책을 선택하는 것 같습니다.
참고
Last updated