카테고리 없음

자바스크립트에서는 왜 0.1 + 0.2 ≠ 0.3일까?

solming 2024. 9. 18. 21:47
728x90

 

시작

자바스크립트에서 0.1 + 0.2를 해보면 0.3이 아닌 0.30000000000000004가 나오는 것을 볼 수 있습니다.

왜 그런걸까요?

결론부터 말하자면 자바스크립트는 64비트 부동소수점을 사용하기 때문입니다.

 

부동소수점이란?

그럼 부동소수점이라는 건 뭘까요?

쉽게 표현하면 모든 숫자를 1.xxxxxx 형식으로 나타낸다는 것입니다.

  • 자바나 파이썬의 Float 타입, 자바스크립트의 number타입이 해당됩니다.

 

자바스크립트는 숫자 타입을 나타날 때 IEEE 754의 부동소수점 표현 형식 중 배정밀도 64비트 부동소수점 형식을 따릅니다.

- 처음 1 Bit : 부호 표시용 (양수 = 0, 음수 = 1)

- 11 Bits : 지수 부분. (소수점이 몇 칸 움직일 지)

- 52 Bits : 가수 부분 (소수점이 움직인 결과에서 소수점 뒤로 오는 부분들을 채워넣음)

 

부동소수점을 사용하는 이유는 한정된 메모리를 최대한 효율적으로 활용하여 연산해야 하기 때문입니다. 

 

 

0.1 + 0.2를 계산해보자

컴퓨터는 모두 2진수로 계산을 하므로 소수점을 먼저 2진수로 변환해봅시다.

우리가 일반적으로 아는 2진수 변환 방법과 약간의 차이가 있습니다.

정수는 우리가 알던대로 2를 나눔으로써 2진수 변환을 할 수 있지만, 반대로 소수는 2를 곱하면서 계산해주어야 합니다.

 

0.1을 2진수 변환하는 과정입니다.

 

0.1을 2진수로 바꾸면 딱 나누어 떨어지지 않기 때문에 0.0001100110011001100…. 이 반복됩니다.
마찬가지로 0.2도 딱 나누어 떨어지지않고 0.0011001100110011001100… 이 반복됩니다.

 

0.1과 0.2를 2진수로 바꾸는 과정에서 딱 나누어 떨어지지않고 무한소수로 변환되어 한정된 메모리 저장소에 저장하기위해 뒤를 짜르고 근사치로 저장하게 됩니다. ( 컴퓨터의 비트 수에는 제한이 있기 때문에 !)

그 결과로 0.3의 2진수와 비교해봤을 때 아주 작은 수의 차이가 생기게 됩니다.

 

따라서 0.1 과 0.2 의 연산 결과가 10진수로는 0.3 이지만, 2진수로 표현할 때는 비트의 한계가 있어 근사값인 0.300000004로 표시하게 되는 것입니다.

 

그렇다면 정확하게 계산하는 방법은?

소수점 이하가 정확해야할 땐, bignumber.js, big.js와 같은 오픈소스를 사용해야 합니다.

https://mikemcl.github.io/big.js/

 

big.js API

big.js A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic. Hosted on GitHub. The library is incorporated into this page, so it should be available in the console now. API For brevity, var, semicolons and toString calls have been

mikemcl.github.io

https://www.npmjs.com/package/bignumber.js/v/4.0.4

 

bignumber.js

A library for arbitrary-precision decimal and non-decimal arithmetic. Latest version: 9.1.2, last published: a year ago. Start using bignumber.js in your project by running `npm i bignumber.js`. There are 8004 other projects in the npm registry using bignu

www.npmjs.com

 

 

참조

자바스크립트에서 0.1+0.2는 왜 0.3이 아닐까
https://betterprogramming.pub/why-is-0-1-0-2-not-equal-to-0-3-in-most-programming-languages-99432310d476

이진수 계산법
https://kyungyeon.dev/posts/111/

728x90