비트 마스킹이란 무엇입니까?


191

나는 C 프로그래밍을 처음 접했고 비트 마스킹에 직면했다. 누군가 비트 마스킹의 일반적인 개념과 기능을 설명 할 수 있습니까? 예가 많이 인정됩니다.


1
&와 같은 비트 연산자를 이해합니까? ^ 등과 부울 논리는 일반적으로? 마스크 작업에 대한 설명은이를 필요로합니다.
Paul R

1
예, 비트 연산자와 부울 논리를 이해했습니다
Mr.Z

2
링크를 게시해서는
안되지만

2
@pevik 링크를 게시해도 괜찮지 만 일부 설명을 사용하여 링크가 언젠가 죽어도 게시물의 응답 목적을 제공 할 수 있습니다. 또한 링크는 단순한 홍보 목적으로 사용해서는 안됩니다.
Dexter

답변:


245

마스크는 유지하려는 비트와 지울 비트를 정의합니다.

마스킹은 값에 마스크를 적용하는 작업입니다. 이것은 다음을 수행하여 수행됩니다.

  • 값에서 비트의 서브 세트를 추출하기위한 비트 AND
  • 값에서 비트의 서브 세트를 설정하기위한 비트 단위 ORing
  • 값에서 비트의 서브 세트를 토글하기위한 비트 XORing

아래는 값에서 비트의 서브 세트를 추출하는 예입니다.

Mask:   00001111b
Value:  01010101b

마스크를 값에 적용하면 첫 번째 (높은) 4 비트를 지우고 마지막 (낮은) 4 비트를 유지하려고합니다. 따라서 하위 4 비트를 추출했습니다. 결과는 다음과 같습니다.

Mask:   00001111b
Value:  01010101b
Result: 00000101b

마스킹은 AND를 사용하여 구현되므로 C에서 다음을 얻습니다.

uint8_t stuff(...) {
  uint8_t mask = 0x0f;   // 00001111b
  uint8_t value = 0x55;  // 01010101b
  return mask & value;
}

다음은 상당히 일반적인 사용 사례입니다. 큰 단어에서 개별 바이트를 추출합니다. 워드의 상위 비트를 첫 번째 바이트로 정의합니다. 우리는이 두 개의 연산자를 사용 &하고, >>(시프트 오른쪽). 32 비트 정수에서 4 바이트를 추출하는 방법은 다음과 같습니다.

void more_stuff(uint32_t value) {             // Example value: 0x01020304
    uint32_t byte1 = (value >> 24);           // 0x01020304 >> 24 is 0x01 so
                                              // no masking is necessary
    uint32_t byte2 = (value >> 16) & 0xff;    // 0x01020304 >> 16 is 0x0102 so
                                              // we must mask to get 0x02
    uint32_t byte3 = (value >> 8)  & 0xff;    // 0x01020304 >> 8 is 0x010203 so
                                              // we must mask to get 0x03
    uint32_t byte4 = value & 0xff;            // here we only mask, no shifting
                                              // is necessary
    ...
}

위의 연산자 순서를 전환 할 수 있으며 마스크를 먼저 수행 한 다음 시프트를 수행 할 수 있습니다. 결과는 동일하지만 이제 다른 마스크를 사용해야합니다.

uint32_t byte3 = (value & 0xff00) >> 8;

5
좋은 대답이지만 마스킹은 OR 또는 XOR 연산 및 적절한 마스크를 사용하여 특정 비트 를 설정 하거나 토글하는 데 적용될 수도 있습니다 .
Paul R

@ user239558 예제와 적절한 구문에 감사드립니다. @ Paul R. user239558이 제공 한 예제에서 마스크 AND 값을 간단히 말하겠습니다
Mr.Z

@ Mr.Z : C, C ++ 및 관련 언어에서는 비트 AND 연산자를 사용 &합니다.
Paul R

@ Mr.Z 예 : 내용을 마스킹하여 uint32_t의 1 바이트를 지 웁니다 #define MASK 0x000000FF .... my_uint32_t &= ~MASK.
Lundin

b나타낼 진 리터럴은 올바른, 모든 컴파일러에 의해 지원되지 않는 이유는 무엇입니까?
Ungeheuer

76

마스킹 은 정보의 원하는 부분을 유지 / 변경 / 제거하는 것을 의미합니다. 이미지 마스킹 작업을 볼 수 있습니다. 이 마스킹 작업은 피부가 아닌 것을 제거합니다.

여기에 이미지 설명을 입력하십시오

이 예에서는 AND 연산을 수행하고 있습니다. 다른 마스킹 연산자 인 OR , XOR도 있습니다.


비트 마스킹 은 부과하는 것을 의미합니다. 여기서 비트 마스킹 함께 AND -

     1 1 1 0 1 1 0 1   [input]
(&)  0 0 1 1 1 1 0 0    [mask]
------------------------------
     0 0 1 0 1 1 0 0  [output]

따라서 (이 비트 1가이 마스크에 있기 때문에) 중간 4 비트 만 남아 있습니다.

XOR로 이것을 볼 수 있습니다 -

     1 1 1 0 1 1 0 1   [input]
(^)  0 0 1 1 1 1 0 0    [mask]
------------------------------
     1 1 0 1 0 0 0 1  [output]

이제 가운데 4 비트가 뒤집 힙니다 (1 되었고 0, 0이되었다 1).


비트 마스크를 사용하여 개별 비트에 액세스 할 수 있습니다. ]. 때때로이 기술은 성능 향상을 위해 사용될 수도 있습니다. 이것을 예로 들어 봅시다.

bool isOdd(int i) {
    return i%2;
}

이 함수는 정수가 홀수 / 짝수인지 알려줍니다. 우리는 비트 마스크를 사용하여 더 높은 효율로 동일한 결과를 얻을 수 있습니다.

bool isOdd(int i) {
    return i&1;
}

간단한 설명 : 이진수의 최하위 비트1 가 홀수이면 홀수입니다. 에 대한 0그것도있을 것입니다. 그래서 수행하여 AND1우리가 최하위 비트 즉 제외한 다른 모든 비트를 제거 :

     55  ->  0 0 1 1 0 1 1 1   [input]
(&)   1  ->  0 0 0 0 0 0 0 1    [mask]
---------------------------------------
      1  <-  0 0 0 0 0 0 0 1  [output]

1
또한 정수를 홀수로 변환합니다. 짝수 인 경우 : i = i | 1. 이것은 1, 3, 5, ..., 2, 4, 6, ...과 같은 시퀀스를 생성하려고 할 때 유용합니다.
Harshit Sharma

또한 다음 연산을 사용하여 정수에서 최하위 비트 만있는 숫자를 찾을 수 있습니다. lsb = i & -i
Harshit Sharma
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.