함정 시리즈

[JavaScript] Number는 64비트인데 비트 연산은 32비트까지만?

노새두마리 2023. 12. 8. 18:43

 

64비트 Number → 32비트 정수
비트 연산 수행
32비트 정수 → 64비트 Number

 

1 << 31

처음에는 단순히 숫자 2를 거듭하여 곱하는 것과 비트 연산 시프트를 수행하는 것의 시간을 간단히 비교하고자 하였습니다.

하지만 1 << 31부터 값이 예상과 달라짐을 발견하였습니다.

  • <<: 비트를 한 칸씩 왼쪽으로 이동하는 비트 연산자
  • 1 << 31: 1이 부호 비트로 넘어가면서 음수로 해석됨
  • 이후 추가 연산 진행 시 1이 비트 범위에서 완전히 제거됨(결과는 0)

이는 JavaScript의 비트 연산자가 32비트 정수형에 기반하여 작동하기 때문입니다. Number 자료형의 정수 표현 범위와는 관계없이 비트 연산으로는 최대 2^31 - 1까지의 수만을 표현할 수 있습니다.


한번에 32자리 이상을 시프트하도록 요구하면 그 값을 32로 나눈 나머지 만큼만 시프트가 적용되는 것을 확인했습니다.

// x << (n % 32)

1 << 32; // 1
(1 << 31) << 1; // 0

1 << 1; // 2
1 << 33; // 2

다른 비트 연산은?

시프트 연산 이외에 다른 연산도 해 봅시다.

let N = 2 ** 32;     // 1000...(2) 0이 32개 -> 4294967296
console.log(N & N);  // 0
console.log(N | N);  // 0
console.log(N ^ 0);  // 가장 큰 자릿수의 1을 살려도 32비트 범위를 벗어나므로 0

32자리를 벗어난 비트가 제거된 결과가 반환됩니다.


참고

https://www.w3schools.com/js/js_bitwise.asp

https://www.geeksforgeeks.org/javascript-bitwise-operators/