정수의 이진수 표현을 자료 구조로 쓰는 기법을 비트마스크라고 부른다.
<vetor<bool>, int> 를 사용하고 있다고 할 때, 비트마스크를 써서 같은 정보를 정수 변수로 나타내면 단순한 int[]를 사용해 같은 정보를 나타낼 수 있다.비트마스크를 사용하기 위해서는 정수 변수를 비트별로 조작할 수 있는 비트 연산자를 사용해야 한다.
AND 연산: 두 비트가 모두 켜져있을 때만 결과의 비트를 켠다.OR 연산: 두 비트 중 하나라도 켜져 있을 경우 결과의 비트를 켠다.XOR 연산: 하나는 켜져 있고 하나는 꺼져 있을 경우 결과의 비트를 켠다.NOT 연산: 정수 하나를 입력받아 켜져 있는 비트는 끄고, 꺼져 있는 비트는 켜서 반환한다.시프트(shift) 연산: 정수 의 비트들을 왼쪽 또는 오른쪽으로 원하는 만큼 움직인다. 움직이고 나서 빈자리는 0으로 채워진다.JS에서 비트마스크를 사용하면 비트 연산의 피연산자가 32비트 정수로 변환된다
| 연산 | 코드 |
|---|---|
두 정수 , 를 비트별로 AND 연산 | a & b |
두 정수 , 를 비트별로 OR 연산 | a ⅼ b |
두 정수 , 를 비트별로 XOR 연산 | a ^ b |
정수 의 비트별로 NOT 연산 결과 | ~a |
| 정수 를 왼쪽으로 비트 시프트 | a << b |
| 정수 를 오른쪽으로 비트 시프트 | a >> b |
비트마스크의 가장 중요한 사용 사례는 집합을 구현하는 것이다.
이 표현에서 비트 정수 변수는 0부터 -1까지의 정수 원소를 가질 수 있는 집합이 된다.
원소 가 집합에 속해 있는지 여부는 을 나타내는 비트가 켜져 있는지 여부로 나타낸다.
집합
{1, 4, 5, 6, 7}을 표현하는 정수는754이다.
피자는 0부터 19까지의 번호를 갖는 스무 가지의 토핑이 있으며, 주문시 토핑을 넣기 / 넣지 않기를 선택할 수 있다.
-> 피자의 토핑을 비트마스크를 이용해 표현해본다.
const plainPizza = 0; // 공집합
const fullPizza = (1 << 20) - 1; // 꽉 찬 집합
const toppings |= (1 << p);
if (topping & (1 << p))
// 1 << p: 포함되어 있음
// 0 : 포함되어 있지 않음
topping &= ~(1 << p))
toppings ^= (1 << P);
result = (a | b) // a와 b의 합집합
result = (a & b) // a와 b의 교집합
result = (a & ~b) // a에서 b를 뺀 차집합
result = (a ^ b) // a와 b중 하나에만 포함된 원소들의 집합
function bitCount(x) {
if(x === 0) return 0;
return x % 2 + bitCount(x / 2);
}
const firstTopping = (toppings & -toppings);
toppings &= (toppings - 1);
topping-1의 이진수 표현은 최하위 비트를 끄고 그 밑의 비트들을 전부 킨 것이다. let pizza;
for(let subset = pizza; subset; subset = ((subset-1) & pizza)) {
}
subset = ((subset-1) & pizza)
subset-1은 subset의 최하위 비트가 꺼지고, 그 밑의 비트들은 전부 켜진다.var dec = 123;
var hex = dec.toString(16); // === "7b"
var bin = dec.toString(2); // === "1111011"
var hex = "7b";
var bin = "11110111";
var dec1 = parseInt(hex, 16); // === "123"
var dec2 = parseInt(bin, 2); // === "123"