본문 바로가기
Javascript

Javascript - Number 64비트 부동소수점

by DGK 2021. 9. 17.

 

인프런 자바스크립트 입문 수업을 듣고 중요한 내용을 정리했습니다.
개인 공부 후 자료를 남기기 위한 목적이므로 내용 상에 오류가 있을 수 있습니다.

 

Number 64비트 부동소수점

 

  • 64비트 부동소수점의 이해 

0.1과 0.2를 더하는 연산을 하는 경우 우리는 상식적으로 0.3의 결과 값을 기대한다.

하지만 결과는 아래와 같다.

let x = 0.1 + 0.2;
console.log(x);		//0.3값을 기대했지만, 0.30000000000000004값이 도출됨

이는 자바스크립트가 숫자(Number)를 64비트 부동소수점으로 저장하기 때문이다.

컴퓨터는 모든 데이터를 2진법으로 저장하기 때문에, 만약 어떤 수의(특히 소수의 경우) 분모의 해당 하는 수가 
2의 거듭제곱 형태이면 유한소수가 되고, 2의 거듭제곱 형태가 아니면 무한소수가 된다. 

0.1 = 1/10		//분모의 해당하는 수가 10
0.2 = 1/5		//분모의 해당하는 수가 5

//컴퓨터가 2진법으로 0.1과 0.2를 저장하는 경우 이들은 무한소수 형태가 된다.

console.log((0.1).toString(2));	
//0.0001100110011001100110011001100110011001100110011001101
//0.1을 2진수로 표현 (단, 64비트 부동소수점으로 저장됨)

console.log((0.2).toString(2));
//0.001100110011001100110011001100110011001100110011001101
//0.2를 2진수로 표현 (단, 64비트 부동소수점으로 저장됨)

따라서 자바스크립트가 무한소수를 저장하면 64비트의 공간을 초과하게 된다.(64비트 부동소수점)

이 때 자바스크립트는 64비트를 초과하는 부분을 반올림해서 저장하기 때문에, 우리가 원하는 정확한 숫자를
얻지 못하고 근사치를 얻게된다. 이 것이 연산과정에서 오차가 발생할 수 있는 이유이다.

두 무한소수 0.1과 0.2의 합인 0.3은 무한소수이며 당연히 근사치로 저장되기 때문에 오차가 발생한다.
(이것이 0.1 + 0.2 = 0.30000000000000004이 되는 이유)

 

 

  • 정리
1. 자바스크립트 뿐만 아니라 부동소수점으로 숫자(Number)를 저장하는 모든 프로그래밍 언어는
    동일한 문제를 지닌다.
2. 그러나 타언어(자바의 경우)는 숫자를 선언할 때 변수의 타입을 다르게 선언함으로써 내부의
    연산오류를 제어한다.

3. 자바스크립트는 모든 숫자를 동일한 선언자로 선언하기 때문에 이러한 연산 오류에 취약하다.
4. 그래서 자바스크립트는 이러한 연산 오류를 해결하기 위해 외부 오픈소스 라이브러리를 사용해야
    한다.(특히 연산이 많은 경우)
5. 자바스크립트는 정수 16자리를 넘어가는 순간 오류가 발생한다.(또 다른 사례)
let x2 = 999999999999999;
  console.log(x2);    //999999999999999(15자리)

let x3 = 9999999999999999;
  console.log(x3);    //10000000000000000(16자리)
  
console.log(Number.MAX_SAFE_INTEGER);	//9007199254740991
//자바스크립트의 Max Safe Integer 값인 9007199254740991를 초과했기 때문
  
//자바스크립트를 사용하면서 연산이 많은 경우에는 어떠한 상황에서 에러가 발생할지 모르니,
//외부 라이브러리를 사용하여 연산 오류에 대처하는 것을 추천한다.

6. 자바스크립트 연산 오류를 해결하기 위한 외부 라이브러리 

BigNumber.js
Big.js
Decimal.js

7. 사실상 실무에서는 소수점 이하 몇 자리 까지만 숫자를 나타낸다는 포맷이 존재하므로, 위와 같은 연산
    오류가
흔하게 발생하지는 않는다. 하지만 자바스크립트는 숫자를 64비트 부동소수점으로 저장하고 있으며,
    언제든지 위와 같은 사례의 오류가 발생할 수 있음을 인지하고 있어야 한다.

 

댓글