1
이라면 1
을 리턴하고 그렇지 않다면, 0
을 리턴합니다.let bitAnd = 12 & 15;
// 1100 (12)
// 1111 (15)
// 1100 (12)
console.log(bitAnd); // 12
1
이라면 1
을 리턴하고, 그렇지 않다면 0
을 리턴합니다. let bitOR = 12 | 15;
// 1100 (12)
// 1111 (15)
// 1111 (15)
console.log(bitOR); // 15
let bitNOT = ~3;
// 0011 (3)
// 1100 (-4)
console.log(bitNOT); // -4
0
을 리턴하고, 다르면 1
을 리턴합니다.let bitXOR = 12 ^ 15;
// 1100 (12)
// 1111 (15)
// 0011 (3)
console.log(bitXOR); // 3
let leftShift = 7 << 2;
// 0000 0111 (7)
// 0001 1100 (28)
console.log(leftShift); // 28
let rightShift = 7 >> 1;
// 0000 0111 (7)
// 0000 0011 (3)
console.log(rightShift); // 3
최상위 비트 (Most Significant Bit)
를 부호 비트로 사용한다. // 0001 (1)
// 1001 (-1)
이 방식에는 큰 문제점이 있는데, 바로 2진수의 연산이 불편하다는 점이다.
// 0001 + 1001 = 1010 (0)
연산상으로는 1010이 0000이 되어야하지만, 그렇지 않다.
~
연산자가 하는 방식이 바로 1의 보수와 동일하다.
// 0001 (1)
// 1110 (-1)
이 방법 또한 하나의 단점이 존재하는 데, 바로 0이 두 가지 방식으로 표현된다는 것이다.
// 0001 + 1110 = 1111 (0)
// 0000 (0)
// 1111 (0)
그래서 앞선 두 가지 방식을 해결하기 위해 2의 보수가 등장한다
2의 보수: 양수의 1의 보수를 구한 뒤, 1을 더해주는 방식
// 0001 (1)
// 1111 (-1)
// 0001 + 1111 = 10000
위의 결과가 나오는데, 위 값의 최상위 비트가 1이지만 범위를 벗어났기 때문에 무시하여 10000 => 0000 => 0이 되는 것을 확인할 수 있다.
function isEven(num) {
return !(num & 1);
// 0000 0111 (7)
// 0000 0001 (1)
}
isEven(2) // true
isEven(7) // false
function isPositive(num) {
return !((num >> 31) & 1);
}
function switchSign(num) {
return ~num + 1;
}