논리연산자
의 AND, OR과 헷갈릴 수 있으나 논리연산자는 기호를 두 개씩(&&
, ||
), 비트연산자
는 한 개씩(&
, |
) 사용한다.2진수
(binary)를 연산할 때 사용하는 연산자이다.JavaScript
는 비트를 표현할 때 최대 32비트
까지 표현할 수 있다.a & b
&
)는 두 개의 피연산자의 각 자리마다 대응하는 비트가 모두 1
일 경우 1
을 반환합니다. 10진수인 두 정수를 2진수로 변환 했을 때, 두 수가 1이 일치하는 자리를 찾아 1을 반환, 나머지는 0으로 반환한다. 이후 2진수 → 10진수로 변환한 값을 리턴 함. 9 (base 10) = 00000000000000000000000000001001 (base 2)
14 (base 10) = 00000000000000000000000000001110 (base 2)
--------------------------------
14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
14 & 9 // 8
let a = 8;
console.log(a.toString(2)); // 1000
// 아래 예제와 같이, 대응하는 비트가 없는 경우 0 반환
5 & 2; // 0
// 5: 00000000000000000000000000000101
// 2: 00000000000000000000000000000010
a | b
I
)는 두 개의 피연산자의 각 자리의 대응하는 비트가 연산자 둘 중 한 쪽만 1인 경우 혹은 둘 다 1인 경우 1을 반환하고, 둘 다 0인 경우 0으로 반환한다. 9 (base 10) = 00000000000000000000000000001001 (base 2)
14 (base 10) = 00000000000000000000000000001110 (base 2)
--------------------------------
14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
14 | 9 // 15
let a = 15;
console.log(a.toString(2)); // 1111
a ^ b
9 (base 10) = 00000000000000000000000000001001 (base 2)
14 (base 10) = 00000000000000000000000000001110 (base 2)
--------------------------------
14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
14 ^ 9 // 7
let a = 7;
console.log(a.toString(2)); // 111
~a
let [a, b] = [5, -5];
console.log(a.toString(2)); // 101
console.log(b.toString(2)); // -101
🔷 2의 보수 방식으로 음수 비트의 정수값 구하는 법
0101 (2진수) = 5 (10진수)이라는 양수의 비트가 있다.
1의 보수 방식으로 비트를 뒤집으면 1010 (2진수)이다.
MSB(최상위 비트)가 1로 시작하는 비트는 음수이므로 0을 가진 비트의 값을 계산한다. 0을 가진 비트의 값은 2² + 2⁰ = 5이다.
2의 보수는 1의 보수 방식에서 1을 더한 값이므로 5 + 1 = 6이고 음수 기호를 붙여 최종적으로 -6이 된다.
2³ 2² 2¹ 2⁰
0 1 0 1 (base2) = 5 (base 10)
1 0 1 0 (base2) = -6 (base 10)
4 + 1 = 5 + 1 = 6 => -6
console.log(~5); // -6
a << b
<<
) 연산자는 첫 번째 피연산자
를 명시된 비트 수(32의 나머지)만큼 왼쪽으로 이동합니다. 왼쪽으로 이동된 초과 비트는 폐기됩니다. 오른쪽은 움직인 비트 수 만큼 0비트로 채워집니다. 9 (10진수): 00000000000000000000000000001001 (2진수)
--------------------------------
9 << 2 (10진수): 00000000000000000000000000100100 (2진수) = 36 (10진수)
9 << 2; // 36
// 9 * (2 ** 2) = 9 * (4) = 36
// 9 * Math.pow(2, 2) = 9 * 4 = 36
9 << 3; // 72
// 9 * (2 ** 3) = 9 * (8) = 72
// 9 * Math.pow(2, 3) = 9 * 8 = 72
a <<= b
<<=
) 연산자는 지정된 비트 수 만큼 왼쪽으로 비트를 이동시키고 그 결과를 변수에 반영합니다.x <<= y
// x = x << y
let a = 5;
console.log(a.toString(2));
// 00000000000000000000000000000101
a <<= 2;
// 00000000000000000000000000010100
console.log(parseInt(10100, 2)); // 20
console.log(a); // 20
// 변수 a는 지정된 비트 수(2) 만큼 왼쪽으로 이동되고, 그 결과는 변수 a에 반영된다.
a >> b
a >>> b
지정한 수만큼 비트를 전부 오른쪽으로 이동시키며, 새로운 비트는 전부 0이 됨.
양수에서는 >>
와 동일하게 동작하지만 음수일 경우 다르다. 1의 보수
로 비트의 반전(0,1을 반대로 뒤집기)한 다음, 새로운 비트를 0으로 채우게 되는데, 양수 비트와 달리 음수 비트의 경우 0인 비트의 값들을 계산하게 되므로, 큰 값이 될 수 있다. 다음 예제 참고 ⬇️
// a >>> b
const a = 5 >>> 2;
const b = -5 >>> 2;
console.log(a); //1
// 00000000000000000000000000000101 (base 2) = 5 (base 10)
// 00000000000000000000000000000001 (base 2) = 1 (base 10)
// (우측으로 2비트 이동하고 새로운 비트 전부 0으로 채워 줌)
console.log(b); //1073741822
// -00000000000000000000000000000101 (base 2) = -5 (base 10)
//(=11111111111111111111111111111010) (1의 보수로 비트를 뒤집은 형태)
// 00111111111111111111111111111110 (base 2) = 1 (base 10)
// (우측으로 2비트 이동하고 새로운 비트 전부 0으로 채워 줌)
// 0인 비트의 값들을 계산하면 1073741822```
자료 출처: MDN 문서 및 각종 자료들 참고