[JavaScript] Number의 부동소수점 문제 발생원인과 해결방법

let x = 0.1 + 0.2;
console.log(x);

위의 자바스크립트 코드를 실행시키면 어떤 결과가 나올까요? 상식적으로는 0.3이 나와야 정상이겠습니다만 실제로는 위와 같이 0.30000000000000004라는 결과값이 나옵니다. 바로 자바스크립트의 Number Type이 64비트의 부동 소수점으로 데이터를 저장하기 때문에 부동소수점 문제가 발생한 것입니다. 이번 포스팅에서는 자바스크립트에서 부동 소수점 문제가 발생하는 원인이 무엇이고, 이 문제를 어떻게 해결할 수 있을지에 대해 알아보도록 하겠습니다.

 

※ 참고로 자바스크립트만 이 부동소수점에 대한 이슈는 자바스크립트에서만 발생하는 특이한 이슈가 아닌 부동소수점을 차용하고 있는 모든 프로그래밍 언어에서 이러한 문제가 발생합니다. 

 

 


 

부동 소수점 문제의 원인

컴퓨터는 0과 1로만 자바스크립트에서 사용하는 부동 소수점은 이진수로 표현되기 때문에 특정 십진수를 정확하게 표현할 수 없습니다. 예를 들어, 십진수 0.1의 경우에는 이진수로 정확히 표현되지 않아서 무한소수로 표현이 됩니다. 하지만 Number는 64비트이기 때문에 이 무한소수를 저장할 수가 없습니다. 즉 64비트가 넘어가는 값은 반올림되기 때문에 정확한 값의 표현이 되지 않는 것입니다.

 

 

 문제 해결 방법 

정수 연산 사용

let x = (0.1 * 10 + 0.2 * 10) / 10;
console.log(x);

부동 소수점 문제를 피하기 위해 정수 연산을 사용할 수 있습니다. 예를 들어, 계산 전에 값을 정수로 변환하고 나중에 필요한 경우 다시 소수점으로 변환할 수 있습니다.

 

 

소수점 자리 제한

let x = 0.1 + 0.2;
x = parseFloat(x.toFixed(1)); // 결과를 1자리 소수로 제한
console.log(x);

소수점 자리를 제한하여 필요한 정밀도를 유지할 수 있습니다. toFixed 메서드를 사용하여 특정 소수점 자리까지 값을 제한할 수 있습니다.

 

 

외부 라이브러리 사용

  • Decimal.js
  • BigNumber.js
  • Big.js
<!-- Decimal.js CDN을 통해 불러오기 (최신 버전) -->
<script src="https://cdn.jsdelivr.net/npm/decimal.js"></script>
<script>
    // Decimal.js 사용
    let x = new Decimal(0.1).plus(0.2);
    console.log(x.toString());
</script>

가장 추천하는 방법은 부동 소수점 문제를 다루는 라이브러리를 사용하는 방법입니다. 자바스크립트에서는 이 부동소수점을 방지할 수 있는 Decimal.js, BigNumber.js, Big.js와 같은 여러 가지 라이브러리를 제공하고 있습니다. 이 라이브러리는 정확한 소수점 연산을 지원하기 때문에 부동 소수점 문제를 해결할 수 있습니다. 외부 라이브러리를 사용하는 방법은 위의 예제처럼 CDN을 사용하는 방법도 있고, 직접 다운로드하여 사용하는 방법 그리고 node.js를 사용하고 있으시다면 npm으로 다운로드하는 방법 등 다양한 방법이 있으니 필요에 따라 선택하시면 됩니다.

 

 

 

 

댓글

Designed by JB FACTORY