비트연산을 굳이 알아야 할까?
실무에서 자주 쓰이지는 않지만 알아둬서 나쁠건 없다고 생각한다.
그래서 복습을 겸해서 정리해보았다.
JavaScript에서 숫자 타입은 64비트 부동소수점이다. (MDN 참고)
비트 연산자 사용 시에는 내부적으로 32비트 부호 있는 정수로 변환하여 계산한다.
음수는 내부적으로 2의 보수 형태로 표현된다.
<비트연산자 종류>
& | AND | a & b | 두 비트가 모두 1이면 1, 아니면 0 |
&= | AND 할당 | a &= b | a &= b는 a = a & b와 같음 |
~ | NOT | ~a | 비트를 반대로 뒤집음 (0 → 1, 1 → 0) |
| | OR | a | b | 둘 중 하나라도 1이면 1 |
|= | OR 할당 | a |= b | a |= b는 a = a | b와 같음 |
^ | XOR | a ^ b | 두 비트가 다를 때만 1 |
^= | XOR 할당 | a ^= b | a ^= b는 a = a ^ b와 같음 |
<< | 왼쪽 shift | a << b | 비트를 왼쪽으로 이동(2의 제곱 곱하기) |
<<= | 왼쪽 shift 할당 | a <<= b | a <<= b는 a = a << b와 같음 |
>> | 부호 있는 오른쪽 shift | a >> b | 비트를 오른쪽으로 이동 (음수일 경우 부호 유지) |
>>= | 부호 있는 오른쪽 shift 할당 | a >>= b | a >>= b는 a = a >> b와 같음 |
>>> | 부호 없는 오른쪽 shift | a >>> b | 부호 비트 무시하고 오른쪽으로 이동 |
>>>= | 부호 없는 오른쪽 shift 할당 | a>>>= b | a >>>= b는 a = a >>> b와 같음 |
여기서 몇 가지만 코드를 통해 이해를 해보고자 한다.
let a = 5; // 00000000 00000000 00000000 00000101
let b = 3; // 00000000 00000000 00000000 00000011
변수 a는 숫자 5, 변수 b에는 숫자 3을 할당했다.
& (AND)
console.log(a & b); // 1
오른쪽 끝부터 비교하여 같으면 1, 다르면 0이다.
비교 시 00000001이 되므로 콘솔에 찍히는 값은 1이 된다.
~ (NOT)
console.log(~a); // -6
a의 값을 2의 보수로 변경하면 11111111 11111111 11111111 11111010 이 된다.
여기서 가장 왼쪽 1비트가 부호비트이다. 0은 양수, 1은 음수를 표현한다.
1은 00000001, -1은 11111111
2는 00000010, -2는 11111110 ...
이리하여 11111010은 -6이다.
| (OR)
console.log(a | b); // 7
비트에 하나라도 1일 때 1이다.
00000101, 00000011을 OR 연산자를 통해 보면, 00000111이다.
10진수로 보면 7이 된다.
OR 연산자는 원미만 절삭할 때 매우 편리하다.
비트 연산을 하게 되면 정수로 강제 변환이 된다.
console.log( 13.7 | 0 ); // 13
13 = 00000000 00000000 00000000 00001101
0 = 00000000 00000000 00000000 00000000
----------------------------------------
OR → 00000000 00000000 00000000 00001101 = 13
13.7에서 소수점은 버려지게 되고 13만 남게 된다.
^ (XOR)
console.log(a ^ b); // 6
두 비트가 서로 다를 때만 1, 같으면 0이 된다.
00000101 ^ 00000011 = 00000110
10진수로 변환하면 6이다.
<< (왼쪽 시프트)
console.log(a << 1); // 10
00000101을 왼쪽으로 이동시키게 되면 00001010이다.
이를 10진수로 변환하면 10이 된다.
>> (오른쪽 시프트, 부호 유지)
console.log(a >> 1); // 2
let neg = -5;
console.log(neg >> 1); // -3
00000101을 부호를 유지하고 오른쪽으로 이동시키면 00000010이 된다.
이를 10진수로 변환하면 2이다.
-5를 비트로 변환하면 11111011이다.
이를 오른쪽으로 이동시키면 11111101이다.
이를 10진수로 변환하면 -3이 된다.
>>> (오른쪽 시프트, 부호 무시)
console.log(5 >>> 1); // 2
let neg2 = -5;
console.log(neg2 >>> 1); // 2147483645
양수일 때는 오른쪽 시프트 부호 유지된 상태와 같다.
음수일 때가 달라진다.
11111111 11111111 11111111 11111011에서
011111111 11111111 11111111 1111101이 된다.
부호가 양수로 바뀌게 되고 이를 10진수로 변환하면 2147483645이다.
끝!
'공부합시다 > Javascript' 카테고리의 다른 글
[알고리즘] 이분탐색 (1) | 2025.03.28 |
---|---|
배열 순서 바꾸기 (0) | 2025.03.19 |
JavaScript로 이벤트 및 HTML요소 지우기 (1) | 2025.03.18 |
[개념 정리] 얕은 복사(Shallow Copy)&깊은 복사(Deep Copy) (1) | 2025.03.12 |
JavaScript에서 시간 다루기 (1) | 2024.09.05 |