비트연산자
- 비트(bit)단위, 즉 2진수 단위로 논리연산을 위해 사용하는 연산자
- 비트 단위로 전체 비트를 오른쪽, 왼쪽 이동시킬 때에도 사용한다.
- 실행 과정 : 2진수 변환 → 비교(연산 실행) → 결과 반환(10진수)
비트연산자의 종류
a & b : AND 연산
- 대응되는 비트가 모두 1일 때 1을 반환한다. (둘 다 1이면 1, 아니라면 0을 반환)
1 & 3;
// 1 = 0001(2)
// 3 = 0011(2)
---------------
// 0001(2) = 1
a | b : OR 연산
- 대응되는 비트 중 하나라도 1이면 1을 반환한다. (하나라도 1이면 1, 둘 다 0이면 0을 반환)
1 | 3;
// 1 = 0001(2)
// 3 = 0011(2)
---------------
// 0011(2) = 3
a ^ b : XOR 연산
- 대응되는 비트가 서로 다르면 1을 반환한다. (둘이 다르면 1, 같다면 0을 반환)
1 ^ 3;
// 1 = 0001(2)
// 3 = 0011(2)
---------------
// 0010(2) = 2
~a : NOT 연산
- 비트가 1이면 0으로, 0이면 1로 반전시킨다.
~1;
// 1 = ...0001(2)
-----------------
//~1 = ...1110(2)
a << b : LEFT SHIFT 연산
- a를 b비트만큼 왼쪽으로 이동 (시프트)
- 이동 후 빈 자리는 0으로 채운다.
1 << 3;
// 1 = 0001(2)
---------------
// 1000(2)
a >> b : RIGHT SHIFT 연산
- a를 b비트만큼 오른쪽으로 이동 (시프트)
- 오른쪽으로 밀려난 만큼 범위를 벗어난 데이터는 잘려나감
9 >> 2;
// 9 = 1001(2)
---------------
//0000 0010(2)
a >>> b : LOGICAL RIGHT SHIFT 연산
- 음,양을 구분하는 사인 비트(Sign Bit)를 염두에 두지 않고 비트를 오른쪽으로 시프트하는 연산이다.
비트연산자 활용 (비트마스크)
GET BIT
function getBit(num,i){
let answer = false;
//해당 인덱스를 제외한 나머지가 0인 마스크
let mask = 1 << i; //1000
//num과 mask를 &(AND연산)으로 비교
if(shift&num) answer = true;
return answer;
}
console.log(getBit(9,3));
//1001
//1000
-------
//1000 (true)
SET BIT
function setBit(num,i){
//num과 mask를 |(OR연산)으로 비교
//OR 연산:대응되는 비트가 하나라도 1이면 1을 반환
return num | (1<<i);
}
console.log(setBit(5,3));
//0101(2)
//1000(2)
---------
//1101(2)
CLEAR BIT
function clearBit(num,i){
//마스크를 i번째 인덱스는 0, 나머지는 1로 세팅한다.
//1<<i = 1000, ~(1<<i) = 0111 (NOT 연산자 : 결과를 반대로 반환)
//num과 셋팅값을 &비교 : 대응되는 비트가 모두 1이어야 1을 반환
return num & ~(1<<i);
}
console.log(clearBit(9,3).toString(2));
//1001(2)
//0111(2)
-----------
//0001(2)
CLEAR LEFT BITS
- 인덱스 기준 오른편은 1, 왼편은 0으로 초기화
function clearLeftBits(num,i){
//mask : 1000(2) -> 0111(2)
return num & (1<<i)-1;
}
console.log(clearLeftBits(169,3).toString(2));
//...10101001(2)
//...00000111(2)
------------------
//...00000001(2)
- 1000(2) → 0111(2) 로 만들기 위해 (1<<i)-1 이진수 연산을 사용
- ~(1<<i) NOT연산을 사용할 경우 모든 0이 1로 바뀌므로 의도와 다르게 동작한다.
CLEAR RIGHT BITS
function clearRightBits(num,i){
//mask : ...11110000(2)
return num & (-1<<(i+1));
}
console.log(clearRightBits(169,3).toString(2));
//...10101001(2)
//...11110000(2)
-----------------
//...10100000(2)
- 시프트 이동을 할 때 빈 공간은 0으로 채워짐
- -1은 1111...1111(2) 이므로 인덱스를 포함해 i+1만큼 시프트 이동을 해 0으로 초기화한 마스크를 만들 수 있다.
UPDATE BIT
- i번째 인덱스의 값을 1 or 0으로 업데이트
function updateBit(num,i,bool){
return (num&~(1<<i))|((bool? 1 : 0) <<i);
}
console.log(updateBit(169,3,false).toString(2));
//...10101001(2)
//&..11110111(2)
-----------------
//...10100001(2)
//|..00000000(2)
-----------------
//...10100001(2)
참고자료