본문 바로가기
programming/javascript

자바스크립트 숫자범위와 정밀도 정수형 최대 15자리 부동소수점 17자리

by 개코 - 개발과 코딩 2021. 11. 27.

자바스크립트의 숫자 범위는 특별하다. 64비트로 일괄처리되고 숫자형인 number 타입 하나만 있다. 그럼에도 개발자의 뒷통수를 치는 경우들이 가끔 보이기도 한다. 그렇다고 이런 경우들 때문에 개발 못하는 경우는 없다. 거의 발생할 일이없기도 하거니와 이런 것들 모른다고 개발 못하는 것도 아니기 떄문이다.

자바스크립트 숫자 범위와 정밀도
정수형 최대 15자리 부동소수점 17자리

자바스크립트의 숫자 데이터에 조금 더 살펴보자.

자바스크립트는 다른 언어들과는 다르게 숫자형을 number 타입으로만 지정하고 있다.

여러가지 이유가 있겠지만 다양성을 위한 통일된 규칙이 필요하여 이렇게 정해진 것으로 알고 이싿.

자바스크립트의 숫자형은 64비트로 고정되어 동작한다.

이런 내부적인 것은 그냥 그렇구나 하고 넘어가도록 하자.

프로그램을 만들 때 그렇게 중요한 것은 아니지만 뒷통수를 때리는 것도 이 부분이다.

정수형 숫자 범위

프로그램에서 정수형은 소숫점이 없는 숫자를 말한다.

자바스크립는 정수형 숫자의 정밀도 즉 정확도는 15자리까지이다.

넉넉하고 충분한 자리수이지만 이 정수형 데이터의 내부적인 연산에 의해 반올림되는 경우가 있다.

아래의 코드를 보면 대강 이해가 된다.

<!DOCTYPE html>
<html>
    <body>

        <h2>자바스크립트 숫자형</h2>
        <div id="cont">
            <p id="vNum1"></p>
            <p id="vNum2"></p>
            <p id="vNum5"></p>
        </div>

        <script>
            
            console.log("----------");
            
            let vNum1 = 999999999999999;
            let vNum2 = 9999999999999999;
            let vNum5 = 8888888888888888;
            
            console.log(typeof(vNum1), vNum1);
            document.getElementById("vNum1").innerHTML = vNum1;

            console.log(typeof(vNum2), vNum2);
            document.getElementById("vNum2").innerHTML = vNum2;

            console.log(typeof(vNum5), vNum5);
            document.getElementById("vNum5").innerHTML = vNum5;

            console.log("----------");

        </script>

    </body>
</html>

결과화면을 보자.

숫자형태가 15자리까지는 정확하게 나오고 있지만, 넘어가는 순간 반올림되고 있다.

내부적으로 숫자형태를 처리하는 과정에서 이런 현상이 발견되는 것이겠지만 특별히 큰 수를 웹브라우저 환경에서 계산하는 일은 거의 없기 때문에 무시하고 넘어가기도 한다.

만약, 웹브라우저에서 큰 수에 대한 산수가 필요한 경우라면 주의하자.

부동소숫점 숫자 범위

자바스크립트의 부동소숫점은 점이다.

소숫점을 말한다.

이것 또한 개발자의 통수치기 좋은 면모를 보여준다.

그렇기에 이미 문제를 겪은 개발자들은 사칙연산을 조금 복잡하게 다루고 있기도 하다.

단순히 더하기를 하면 그만이지만, 더하고 빼고 곱하고 등등 10을 곱하고 나누기도 한다.

왜 이런 해괴망칙하고 상스러운 작업을 하는 것일까.

가끔 스택오버플로우에는 이런 코드들을 발견하고 한숨을 쉬는 개발자가 있는 반면 발견의 기쁨에 주체 못해 흑화되어 웹브라우저 메모리 터트리는 개발자들도 가끔 있다.

어쨌든 정밀도 때문이다. 그냥 그렇다고 생각하고 넘어가자.

이런거 고민하고 개발 못한다. 시간만 허비한다.

코드를 보자.

<!DOCTYPE html>
<html>
    <body>

        <h2>자바스크립트 숫자형</h2>
        <div id="cont">
            <p id="vNum3"></p>
            <p id="vNum4"></p>
            <p id="vNum5"></p>
            <p id="vNum6"></p>
        </div>

        <script>
            
            console.log("----------");
            
            let vNum3 = 0.1 + 0.2;

            console.log(typeof(vNum3), vNum3);
            document.getElementById("vNum3").innerHTML = vNum3;

            let vNum4 = (0.2 * 10 + 0.1 * 10) / 10;

            console.log(typeof(vNum4), vNum4);
            document.getElementById("vNum4").innerHTML = vNum4;
            
            console.log("----------");            
            
            let vNum5 = 0.01 + 0.02;

            console.log(typeof(vNum5), vNum5);
            document.getElementById("vNum5").innerHTML = vNum5;

            let vNum6 = (0.02 * 100 + 0.01 * 100) / 100;

            console.log(typeof(vNum6), vNum6);
            document.getElementById("vNum6").innerHTML = vNum6;

            console.log("----------");

        </script>

    </body>
</html>

위의 코드가 익숙한 사람들도 있을 것이다.

0.2 와 0.1 을 더할 경우 특이점이 발생한다.

결과화면을 보자.

소수점이 넘쳐 흐르고 있는 현상을 볼 수 있다.

이 현상 때문에 정확한 계산을 위한 방법을 위해 10과 같은 수를 더하고 나누고 하는 작업이 추가될 수도 있다.

당연하겠지만, 이런 숫자계산 작업은 내부에서 계산하고 가져오는 방식을 택하는 것이 일반적이기도 하다.

하지만, 화면에서 계산이 필요한 계산기나 ERP 같은 프로그램들은 주의가 필요하다.

물론, 테스트 단계에서 에러를 잡겠지만, 숫자 계산이 민감한 경우들은 주의하자.

반응형

댓글