[JavaScript] 큰 숫자 변환

2023. 1. 19. 03:46JavaScript

JavaScript를 사용하여 알고리즘 문제를 풀거나 코딩을 하다가 매우 큰 수를 만나면 어느 순간 반올림 되어 원하는 계산값이 아닌 다른 값이 결과로 도출되는 경우가 많다.
이유는 메모리 저장 방식으로 인하여다.

절대값이 2^53보다 크거나 같은 숫자 리터럴은 너무 커서 정수로 정확하게 표시할 수 없습니다.


이를 해결하기 위해서는 2가지 방법이 있다.
BigInt를 사용하는 방법과 String을 사용하는 방법이다.

1) BigInt사용

ES11 문법(ECMAScript 2020)에서 나온 데이터 타입으로 Number 원시 값이 안정적으로 나타낼 수 있는 최대치인 2^53 - 1보다 큰 정수를 표현할 수 있는 내장 객체이다. (Number는 2^53 - 1까지 안정적으로 나타낼 수 있고 나머지는 환경에 따라 다른 듯 하다.)
사용법은 굉장히 간단하다.

const theBiggestInt = 9007199254740991n;

const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n

const hugeString = BigInt("9007199254740991");
// ↪ 9007199254740991n

const hugeHex = BigInt("0x1fffffffffffff");
// ↪ 9007199254740991n

const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111");
// ↪ 9007199254740991n

BigInt함수에 숫자를 넣으면 된다. Number와 비슷하지만 혼용해서 뒤에 n이 붙으며 Number와 함께 쓸수 없다.
그래서 내장 Math객체의 매서드를 사용할 수 없다.
BigInt를 사용해야한다면 함수를 바꿔야할 수도 있다...

2) String 사용

String을 사용한다면 2^53이상의 수도 저장할 수 있다. String의 길이 또한 2^53 - 1까지 사용할 수 있다. 결론적으로 String을 이용하여 나타낸다면 10^(2^53-1)단위의 숫자를 나타낼 수 있는 셈이다.
아래에는 두 수를 빼는 함수인 subtract이라는 함수를 만들었다. num1과 num2는 String으로 된 숫자를 집어 넣어야한다. 이 때, String과 Array를 사용하여 2^51이상의 수도 계산 할 수 있도록 만들었다. 함수의 return 값으로는 String으로된 숫자이다.

function subtract(num1,num2){
    let [arr1,arr2] = BigInt(num1) >= BigInt(num2) ? [num1.split('').map(Number).reverse(),num2.split('').map(Number).reverse()] : [num2.split('').map(Number).reverse(),num1.split('').map(Number).reverse()];
    for(let i = 0; i < arr1.length; i++){
        if(i < arr2.length)
            arr1[i] -= arr2[i];
        if(arr1[i] < 0){
            arr1[i+1]--;
            arr1[i]+=10;
        }
        if(i === arr1.length - 1 && arr1[i] === 0){
            let j = i;
            while(arr1[j]===0 && j > 0){
                j--;
                arr1.pop();
            }
        }
    }
    return BigInt(num1) >= BigInt(num2) ? arr1.reverse().join(''):"-"+(arr1.reverse().join(''));
}

Reference

- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/BigInt
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/length