Javascript 32bit 이상 Number&Integer 계산하기 (BigInt)

가벼운 마음으로

Hexspeak

상기 문제를 풀었는데, 

위의 문제는

  • n 이라는 integer value를 주고 1과 0 그리고 16진수 영어로만 표현 가능한 값인가?

를 알아내는 문제였다. 

예를 들자면

$ 1005 = \text{0x3ED} $

로 표현 할 수 있다. 여기에 3이라는 숫자가 들어갔기 때문에 오류이다.

$ 6336 = \text{0xCDE} $

이기 때문에 답으로 CDE를 돌려주면 된다.

위의 문제를 풀기위해서는 간단하게 toString을 사용하면 된다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString

let baseTenInt = 10;
console.log(baseTenInt.toString(16));

이런식이다. 

이 built method를 사용하면 굉장히 쉽게 풀수 있었지만,

무슨 마음인지 쉽게 풀고 싶지 않았다.

그래서 4bits 씩 오른쪽으로 shift 하는 방식으로 해당 문제를 풀게 되었다.

예를 들자면

이런식으로 16bit 영문 숫자로 대응 될 수 있는지 4bits를 확인하고 우측으로 4bit를 밀고 하는 식으로 접근을 했다.

그런데 풀이가 fail이 났다.

다음 값때문이다.

  • 747823223228

bit로는

  • 1010,1110,0001,1101,1011,1100,1101,0001,1011,1100
  • 40bits 였다.

이 값을 우측으로 shift를 하니 답이

  • IDBCDIBC

가 나왔다.

예상 답은

  • AEIDBCDIBC

이다.

도저히 이해가 안가서 1bit 씩 쉬프트를 해보니, shift operation을 함과 동시에 40bits가 31bits로 강제 변환 되고 넘어간 수는 삭제 되는 것을 확인 했다.

1010111000011101101111001101000110111100
11101101111001101000110111100 // >> 0
1110110111100110100011011110 // >> 1
111011011110011010001101111
11101101111001101000110111
1110110111100110100011011
111011011110011010001101
11101101111001101000110
1110110111100110100011
111011011110011010001
11101101111001101000
1110110111100110100
111011011110011010
11101101111001101
1110110111100110
111011011110011
11101101111001

위의 그림에서 2번째가 0bit >> shift 함과 동시에 11개의 bit가 사라지는것을 볼 수 있다.

이유는 40bits를 singed Int 31로 변화 함으로써 31개의 bit로 변화되었기 때문이다.

(참고로 32는 signed bit이기 때문에 사용되면 안된다.)

참고로 최 왼쪽이 0이어서 해당 값이 같이 삭제 되어 몇개가 없어져 보이는 착각이 생길 수 있다.

00011101101111001101000110111100 

그럼 32bits 이상의 값은 어떻게 bit shift가 가능한가? 그것은 BigInt를 통해서 가능하다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

let num = BigInt.asIntN(64, "747823223228");

console.log(num.toString(2));
console.log((num >> 0n).toString(2));
console.log((num >> 1n).toString(2));
console.log((num >> 2n).toString(2));
console.log((num >> 3n).toString(2));
console.log((num >> 4n).toString(2));
console.log((num >> 5n).toString(2));
console.log((num >> 6n).toString(2));
console.log((num >> 7n).toString(2));
console.log((num >> 8n).toString(2));
console.log((num >> 9n).toString(2));
console.log((num >> 10n).toString(2));
1010111000011101101111001101000110111100
1010111000011101101111001101000110111100
101011100001110110111100110100011011110
10101110000111011011110011010001101111
1010111000011101101111001101000110111
101011100001110110111100110100011011
10101110000111011011110011010001101
1010111000011101101111001101000110
101011100001110110111100110100011
10101110000111011011110011010001
1010111000011101101111001101000
101011100001110110111100110100

bigint를 사용함으로써 bit가 없어지지 않는 것을 확인 가능하다.

앞서 만든 코드를 다음과 같이 수정함으로써 해당 문제가 정상적으로 해결 되는 것을 확인 할 수있었다.

var toHexspeak = function(num) {
    num = BigInt.asIntN(64,num);
    
    //10,11,12,13,14,15,1,0 으로만 구성된 값이 필요
    const hex = {10:'A',11:'B',12:'C',13:'D',14:'E',15:'F',1:'I',0:'O'};
    const filter = 15n;
    let result = '';
    
    while(0n !== num){
        if(hex[num & filter]){
            result = hex[num & filter] + result;
        } else {
            return "ERROR"
        }
        num = num >> 4n;
    }
    return result;
};

 

728x90
반응형

'Problem Solving' 카테고리의 다른 글

Jump Game II  (0) 2021.08.30
Sparse Matrix Multiplication  (0) 2021.08.17
Longest Repeating Character Replacement  (0) 2021.08.13
Power of Four  (0) 2021.08.13
Data Stream as Disjoint Intervals  (0) 2021.08.10