본문으로 바로가기

비트 마스크

category Algorithm/개념 2021. 5. 16. 12:55

비트가 0과 1로 이루어져있다는 것을 이용해서 두 가지의 상태로 마스킹하여 일종의 자료구조 처럼 사용하는 방법이다

어떻게 사용하는지는 예시를 보면 알기가 쉽다

숫자 집합 {1,2,3,4}가 있다고 가정하고 이 집합에서 숫자를 뽑을 수 있는 경우의 수를 표현하려고 한다

배열의 경우

다음과 같이 참/거짓을 1/0으로 표현해서 배열로 표현할 수 있다

const arr = [1,1,1,1]; {1,2,3,4}
const arr = [1,1,1,0]; {1,2,3  }
const arr = [1,1,0,1]; {1,2,  4}
const arr = [1,0,1,1]; {1,  3,4}
...

비트의 경우

위에서 1과 0으로 표현했듯이 비트로도 똑같이 표현할 수 있다

1111 {1,2,3,4}
1110 {1,2,3}
1101 {1,2,4}
1011 {1,3,4}
...

배열과 똑같이 각 자리의 비트는 해당하는 숫자가 존재하는지를 그렇지 않은지를 0과 1로 표현하고 있다

차이점

사람의 눈으로 보기에는 둘 다 1과 0으로 표현하고 있기 때문에 차이가 거의 없어보이지만 하지만 컴퓨터의 입장에서는 굉장히 다르다

비트는 하나의 정수로 표현이 가능하기 때문에 배열보다 훨씬 효율적이기 때문이다

1111 {1,2,3,4} => 15
1110 {1,2,3} => 14
1101 {1,2,4} => 13
1011 {1,3,4} => 11
...

집합들의 순서 조합을 정수 하나로 표현할 수 있는 것과 같은 효과를 보고 있다

그렇다면 이 비트에서 원하는 자릿수에 어떻게 0과 1을 표현할 수 있을까?

비트 연산

기본적으로 비트 연산자를 알고있다는 가정하에 진행한다

다음과 같은 두 번째 비트가 켜져있는 4자리의 비트를 연산하는 모습이다

원하는 자리의 비트 켜기

  const bit = 2 // '0010'
  console.log((bit|(1<<3))) // 1010, 10
  console.log((bit|(1<<1))) // 0010, 2
  console.log((bit|(1<<2))) // 0110, 6

(0010|(1<<3))을 설명해 보면

1을 왼쪽으로 3번 시프트해서 1000의 이진수를 만든 뒤에
0010
1000 OR 연산으로
1010를 만들어 주었다

이제 4번째와 2번째의 비트가 켜져있는 1010의 상태는 정수 10으로도 나타낼 수 있다

다른 것들도 마찬가지

원하는 자리의 비트 끄기

const bit = 14 // '1110'

console.log((bit & ~(1 << 1)).toString(2)) // 1100, 12
console.log((bit & ~(1 << 2)).toString(2)) // 1010, 10
console.log((bit & ~(1 << 3)).toString(2)) // 0110, 6
console.log((bit & ~(1 << 0)).toString(2)) // 1110, 14

1110 & ~(1 << 2) 의 경우

1을 왼쪽으로 두 번 시프트 한 후 100을 만든 후 ~를 취해서 011을 만든다 앞의 빈자리는 1로 취급되어

1110
1011 AND 연산으로
1010 을 만들어 주었다

비트 값이 켜져있나 확인

    const bit = 11 // '1001'

    console.log(bit&(1<<2)) // 0, false
    console.log(bit&(1<<0)) // 8, true

'Algorithm > 개념' 카테고리의 다른 글

Heap  (0) 2021.06.07
Graph  (0) 2021.04.25
2차원 배열 회전시키기  (0) 2021.04.17
Sort - 기본  (0) 2020.12.18
에라토스테네스의 체  (0) 2020.12.13