본문 바로가기
카테고리 없음

비트 마스킹(Bit-Masking)

by mozzi329 2022. 8. 2.
728x90
 

 

     

     

    📌 비트 마스킹(Bit-Masking)

    컴퓨터는 내부적으로 모든 자료를 이진수로 표현한다.
    이와 같은 특성을 이용해 정수의 이진수 표현을 자료구조로 쓰는 기법을 비트마스크라고 한다.

     

    📌 비트 연산자(Bitwise Operator)

    비트마스킹에 사용되는 기본 연산자를 말한다.

     

    비트 연산자 설명
    & 대응되는 비트가 모두 1이면 1을 반환함 (비트의 AND 조건 연산)
    | 대응되는 비트 중 하나라도 1이면 1을 반환함 (비트의 OR 조건 연산)
    ^ 대응되는 비트가 서로 다르면 1을 반환함 (비트의 XOR 연산)
    ~ 비트를 1이면 0으로, 0이면 1로 반전시킴 (비트의 NOT 연산, 1의 보수)
    << 명시된 수만큼 비트들을 전부 왼쪽으로 이동시킴 (LEFT SHIFT 연산)
    >> 부호를 유지하면서 지정된 수만큼 비트를 전부 오른쪽으로 이동시킴 (RIGHT SHIFT 연산)
    >>> 지정한 수만큼 비트를 전부 오른쪽으로 이동시키며, 새로운 비트는 전부 0이 된다.

    ※ 보수(Complement) : 보충해주는 수를 의미
    어떤 수 A에 무언가를 더했을 때, 깔끔한 [N진법의 수]를 만들어 냈다면, 그 무언가를 A의 N의 보수라고 부른다.

     

    ✔️ AND(&) 연산

    대응되는 두 쌍의 비트가 모두 1이면 1을 반환한다.

    비트의 AND 연산(&)

     

    ✔️ OR(|) 연산

    대응되는 두 비트 중 하나라도 1이라면 1을 반환한다.

     

     

    ✔️ XOR(^) 연산

    대응되는 두 비트가 서로 다르다면 1을, 같다면 0을 반환한다.

    비트의 XOR 연산(^)

     

    ✔️ NOT 연산(~)

    비트가 1이라면 0을 반환하고, 0이면 1을 반환한다.

    비트의 NOT 연산(~)

     

    ✔️ LEFT SHIFT 연산(<<) - Arithmetic

    비트의 칸 수를 주어진 숫자만큼 왼쪽으로 이동시킨다.

    비트의 LEFT SHIFT 연산(<<)

    비트가 왼쪽으로 이동함에 따라 비워지는 비트는 0을 채워주고, 왼쪽으로 이동함에 따라 MSB 영역을 넘어가는 비트 공간은 제거한다.
    해당 연산은 부호 비트를 제외한다.

    ※ MSB(Most Significant Bit) : 최상위 비트를 말한다.

     

    ✔️ RIGHT SHIFT 연산(>>) - Arithmetic

    부호 비트를 제외한 비트의 칸 수를 주어진 숫자만큼 오른쪽으로 이동시킨다.

    비트의 RIGHT SHIFT 연산(>>)

    비트가 오른쪽으로 이동함에 따라 비워지는 비트는 1을 채워주고, 오른쪽으로 이동함에 따라 LSB 영역을 넘어가는 비트 공간은 제거한다.
    해당 연산은 부호 비트를 제외한다.

    ※ LSB(Least Significant Bit) : 최하위 비트를 말한다.

     

    ✔️ RIGHT SHIFT 연산(>>>) - Logical

    부호 비트를 포함하여 비트의 칸 수를 주어진 숫자만큼 오른쪽으로 이동시킨다.

    비트의 RIGHT SHIFT 연산(>>>)

    비트가 오른쪽으로 이동함에 따라 비워지는 비트는 0을 채워주고, 오른쪽으로 이동함에 따라 LSB 영역을 넘어가는 비트 공간은 제거한다.
    해당 연산은 부호 비트를 포함한다.

     

    📌 비트 마스킹의 장점

    • 빠른 수행시간
      시간복잡도 O(1)에 구현되는 것이 많다.
      비트마스크를 사용할 수 있다는 말은 원소의 수가 많지 않다는 뜻이다. 때문에 큰 속도를 항상 기대할 수는 없지만 여러번 수행해야 하는 경우에는 작은 최적화도 큰 속도 향상을 가져올 수 있다.
    • 간결한 코드
      양한 집합 연산자들을 반복문 없이 한 줄에 사용할 수 있다.
    • 작은 메모리 사용량
      적은 메모리를 사용할 수 있다는 말은 데이터를 미리 계산하여 저장해 둘 수 있으므로 캐시 효율이 좋다는 의미이기도 하다.
    • 연관 배열을 배열로 대체
      Map<String, Integer>와 같은 맵 객체를 단순 배열 int[]로도 사용할 수 있다.

     

    📌 비트 마스킹의 활용

    ✔️ getBit

    특정 인덱스의 비트 값을 가져온다.

    class ImplBitMask {
    	// 해당 인덱스의 값에 1이 있다면 true, 없다면 false를 반환
    	static boolean getBit(int num, int i) {
        	return (num & (1<<i)) != 0;
        }
    
    	public static void main(String[] args) {
        	// 1001 -> 1 : true
        	System.out.println(getBit(9, 3));
            // 0101 -> 0 : false
            System.out.println(getBit(5, 3));
        }
    }

     

    ✔️ setBit

    특정 인덱스의 비트 값 1로 설정한다.

    class ImplBitMask {
    	// 해당 인덱스의 값을 1로 변경해준다.
    	static int setBit(int num, int i) {
        	return num | (1<<i);
        }
    
    	public static void main(String[] args) {
        	// 0101 -> 1101 : 13
        	System.out.println(setBit(5, 3));
        }
    }

     

    ✔️ clearBit

    특정 인덱스에 있는 비트를 0으로 설정한다.

    class ImplBitMask {
    	// 해당 인덱스의 값을 0으로 변경해준다.
    	static int clearBit(int num, int i) {
        	return num & ~(1<<i);
        }
    
    	public static void main(String[] args) {
        	// 1001 -> 0001 : 1
        	System.out.println(clearBit(9, 3));
        }
    }

     

    ✔️ clearLeftBits

    특정 인덱스 이상의 비트를 모두 0으로 설정한다.

    class ImplBitMask {
    	// 해당 인덱스 이상의 비트를 모두 0으로 설정해준다.
    	static int clearLeftBits(int num, int i) {
        	return num & ((1<<i)-1);
        }
    
    	public static void main(String[] args) {
        	// 10101001 -> 00000001 : 1
        	System.out.println(getBit(169, 3));
        }
    }

     

    ✔️ clearRightBits

    특정 인덱스 이하의 비트를 모두 0으로 설정한다.

    class ImplBitMask {
    	// 해당 인덱스 이하의 비트를 모두 0으로 설정해준다.
    	static int clearRightBits(int num, int i) {
        	return num & (-1<<(i+1));
        }
    
    	public static void main(String[] args) {
        	// 10101001 -> 10100000 : 160
        	System.out.println(clearRightBits(169, 3));
        }
    }

     

    ✔️ updateBit

    특정 인덱스의 값을 업데이트한다.

    class ImplBitMask {
    	// 해당 인덱스에 특정 값의 비트를 업데이트해준다.
    	static int updateBit(int num, int i, boolean val) {
        	return (num & ~(1 << i)) | ((val? 1:0) << i);
        }
    
    	public static void main(String[] args) {
        	// 10101001 -> 10100001 : 161
        	System.out.println(updateBit(169, 3, false));
        }
    }

     

    ✔️ 순열 구현(작성 예정중)

    준비중입니다 ㅎㅎ;

     

    📌 참조

    53. 비트마스킹(bit mask)

     

    [ 개념 ] 53. 비트마스킹(bit mask)

    > 비트마스킹 bitmask : 정수의 이진수 표현을 자료구조로 쓰는 기법 데이터들은 0과 1의 집합이라고 합니다. 비트는 네트워크 외에도 운영체제 등에서도 자주 접할 수 있는데요 때문에 최적의 성

    coder-in-war.tistory.com

    [자료구조 알고리즘] 비트연산 완전정복 -Bit Operation

    비트 연산자 - TCP SCHOOL

     

    댓글