본문 바로가기
C++

3-3. C++ 비트 플래그, 비트 마스크

by kwon5346 2024. 1. 30.
반응형

1. 비트 플래그 (bit flag)

비트 연산자가 실제로 어떻게 사용이 되는지 예제로 알아보자.

#include <iostream>
#include <bitset>

using namespace std;

int main()
{
   const unsigned int opt1 = 1 << 0;
   const unsigned int opt2 = 1 << 1;
   const unsigned int opt3 = 1 << 2;
   const unsigned int opt4 = 1 << 3;

   cout << "\nopt1    " << bitset<8>(opt1) << endl;
   cout << "opt2    " << bitset<8>(opt2) << endl;
   cout << "opt3    " << bitset<8>(opt3) << endl;
   cout << "opt4    " << bitset<8>(opt4) << endl;

   unsigned int item_flag = 0;

   cout << "\nitem_flag      " << bitset<8>(item_flag) << endl;
   //item2 obtain.
   item_flag |= opt2;
   cout << "\nitem2 obtained " << bitset<8>(item_flag) << endl;
   //item2 lost.
   item_flag &= ~opt2;
   cout << "\nitem2 lost     " << bitset<8>(item_flag) << endl;
   //item4 obtain
   item_flag |= opt4;
   cout << "\nitem4 obtained " << bitset<8>(item_flag) << endl;
   //item4 has?
   if (item_flag &= opt4) { cout << "\nhas item4 is true"<< endl; }
   else { cout << "\nnot have item4   " << endl; }
   //item1,2 obtain
   item_flag |= (opt1 | opt2);
   cout << "\nitem1,2 obtained " << bitset<8>(item_flag) << endl;
   //has obtain item2,4?
   if ((item_flag & opt1) && (item_flag & opt4)) { cout << "\nhas item2,item4 is true" << endl; }
   else { cout << "\nhas item2,item4 is false" << endl; }
   //obtain -> lost, lost obtain
   if ((item_flag & opt1) && !(item_flag & opt3))
   {
      item_flag ^= (opt1 | opt3);
      cout << "\nitem1 lost && item3 obtained " << bitset<8>(item_flag) << endl;
   }

   return 0;
}

 

   const unsigned int opt1 = 1 << 0;
   const unsigned int opt2 = 1 << 1;
   const unsigned int opt3 = 1 << 2;
   const unsigned int opt4 = 1 << 3;

   cout << "\nopt1    " << bitset<8>(opt1) << endl;
   cout << "opt2    " << bitset<8>(opt2) << endl;
   cout << "opt3    " << bitset<8>(opt3) << endl;
   cout << "opt4    " << bitset<8>(opt4) << endl;

변수 4개를 한칸씩 left shift를 해서 선언하고 출력했다.

1바이트짜리 변수 하나가 있다면 8개의 비트로 8개의 상태를 활용할 수 있다.

이 4개의 변수가 게임 아이템이라고 생각해보자. 이걸 활용하면 플레이어의 아이템 소지 유무를 나타낼 수 있을 것 같다.

 

아이템 8개의 소지 유무를 bool타입 변수 8개를 사용하는게 아니라 char 타입 1바이트로 충분히 표현할 수 있는 것이다.

 

   unsigned int item_flag = 0;

   cout << "\nitem_flag      " << bitset<8>(item_flag) << endl;
   //item2 obtain.
   item_flag |= opt2;
   cout << "\nitem2 obtained " << bitset<8>(item_flag) << endl;
   //item2 lost.
   item_flag &= ~opt2;
   cout << "\nitem2 lost     " << bitset<8>(item_flag) << endl;
   //item4 obtain
   item_flag |= opt4;
   cout << "\nitem4 obtained " << bitset<8>(item_flag) << endl;

item_flag를 플레이어의 아이템창이라고 생각해보자.

이제 아이템을 얻고, 버리는 것을 표현하려면 전 게시글의 Bitwise operator를 사용하면 된다.

비트 계산을 해보면 왜 그렇게 되는지 알 수 있다.

 

   //item4 has?
   if (item_flag &= opt4) { cout << "\nhas item4 is true"<< endl; }
   else { cout << "\nnot have item4   " << endl; }
   //item1,2 obtain
   item_flag |= (opt1 | opt2);
   cout << "\nitem1,2 obtained " << bitset<8>(item_flag) << endl;
   //has obtain item2,4?
   if ((item_flag & opt1) && (item_flag & opt4)) { cout << "\nhas item2,item4 is true" << endl; }
   else { cout << "\nhas item2,item4 is false" << endl; }
   //obtain -> lost, lost obtain
   if ((item_flag & opt1) && !(item_flag & opt3))
   {
      item_flag ^= (opt1 | opt3);
      cout << "\nitem1 lost && item3 obtained " << bitset<8>(item_flag) << endl;
   }

마찬가지로 아이템의 소지 유무를 확인하는것, 두 아이템의 소지 여부, 동시에 소지 여부를 변경 하는 등

다양한 연산을 비트 연산자로 수행할 수 있다.

 

2. 비트 마스크

비트 마스크가 어떻게 사용되는지 실용적인 예제로 알아보자.

출처 : https://www.rapidtables.com/web/color/RGB_Color.html

rgb color table은 red, green, blue를 16진수로 표현한다.

 

orange를 예로 들어보면 RR부분이 FF로 표시가 되어있는데 16진수 FF는 255를 의미하는것이다.

0부터 255의 숫자를 이용하여 색깔의 강도를 나타내는 것이다.

즉 FF 두 숫자가 1바이트니까. (8bits  - 2^7 - 1 = 255)  FFA500은 3바이트이다. 

 

16진수로 카키를 받아왔을때 red = 240, green = 230, blue = 140을 한번 추출해보자.

픽셀 컬러에서 마스크를 이용해 red,green,blue의 컬러값을 추출하였다.

&연산자를 이용해 pixelColor의 값을 추출한다음 right shift 연산자를 이용해 비트를 오른쪽으로 당겨주면 컬러값을 얻을 수 있다.

반응형