비트플래그
비트플래그 ( |= / 아이템 획득 )
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
const unsigned char opt0 = 1 << 0;
const unsigned char opt1 = 1 << 1;
const unsigned char opt2 = 1 << 2;
const unsigned char opt3 = 1 << 3;
cout << bitset<8>(opt0) << endl;
cout << bitset<8>(opt1) << endl;
cout << bitset<8>(opt2) << endl;
cout << bitset<8>(opt3) << endl;
unsigned char items_flag = 0;
cout << "No item " << bitset<8>(items_flag) << endl;
// item0 on
items_flag |= opt0;
cout << "Item0 obtained " << bitset<8>(items_flag) << endl;
// item3 on
items_flag |= opt3;
cout << "Item3 obtained " << bitset<8>(items_flag) << endl;
return 0;
}
비트플래그는 2진수에서 0과 1을 On / Off 나 True / False로 사용하는 것이다.
이를 이용하여 공간을 효율적으로 사용할 수 있고, 여러 속성을 지정할 때, 편하게 사용할 수있게 된다.
예로, 8개의 bool 타입 변수 8개를 선언하고 저장하는 것 보다
1개의 char(8bit) 타입 변수로 저장하면 8개를 저장할 수 있다. (1byte = 8bit)
비트플래그 ( &= ~ , & / 아이템 잃음과 보유 여부)
// item3 lost
items_flag &= ~opt3; //off시킴
cout << "Item3 lost " << bitset<8>(items_flag) << endl;
// has item1 ?
if (items_flag & opt1) {cout << "Has item1" << endl;}
else { cout << "Not have item1" << endl; }
// has item0 ?
if (items_flag & opt0) { cout << "Has item0" << endl; }
&= ~의 비트연산을 통하여 아이템을 잃은 것도 표현할 수 있다.
item3의 opt는 opt3인데(0000 1000), ~연산을 통해 1111 0111이 되고,
items_flag(0000 1001)과 &연산을 하면 item3에 대한 자리 표시가 0으로 바뀌어
(0000 0001)없음을 표현할 수 있다.
또한 & 비트연산을 사용해서 아이템의 보유 여부를 출력하는 예제도 가능하다.
items_flag & opt1 ( 0000 0001 & 0000 0011 )에서 opt1의 자리에서 0을 반환하기 때문에 갖고 있지 않음을 표현할 수 있다.
비트플래그 ( |= (a | b ) / 여러 아이템 획득 )
// obtain item 2, 3
items_flag |= (opt2 | opt3);
cout << bitset<8>(opt2 | opt3) << endl;
cout << "Item2,3 obtained " << bitset<8>(items_flag) << endl;
2개의 아이템을 동시에 얻었을때 opt2, opt3을 or 연산한 결과를 items_flag와 한번더 or 연산을하여 표현할 수 있다. 0000 0100 | 0000 1000 = 0000 1100
0000 1100 | 0000 0001 = 0000 1101
비트플래그 ( ^ / XOR / 비트의 토글 )
if ((items_flag & opt2) && !(items_flag & opt1))
{
items_flag ^= opt2;
items_flag ^= opt1;
}
cout << bitset<8>(items_flag) << endl;
비트마스크 ( RGB 색추출의 예 )
#include <iostream>
#include <bitset>
// 색 추출
using namespace std;
int main()
{
const unsigned int red_mask = 0xFF0000;
const unsigned int green_mask = 0x00FF00;
const unsigned int blue_mask = 0x0000FF;
cout << std::bitset<32>(red_mask) << endl;
cout << std::bitset<32>(green_mask) << endl;
cout << std::bitset<32>(blue_mask) << endl;
unsigned int pixel_color = 0xDAA520;
cout << std::bitset<32>(pixel_color) << endl;
unsigned char red = (pixel_color & red_mask) >> 16;
unsigned char green = (pixel_color & green_mask) >> 8;
unsigned char blue = pixel_color & blue_mask;
cout << "red " << std::bitset<8>(red) << " " << int(red) << endl;
cout << "green " << std::bitset<8>(green) << " " << int(green) << endl;
cout << "blue " << std::bitset<8>(blue) << " " << int(blue) << endl;
return 0;
}
비트플래그의 비트를 조작하거나 검사할 때 사용하는 숫자를 비트 마스크라고 한다.
RGB의 2진수 값과 pixel_color의 비트연산 (&)를 활용해서 색을 추출하고,
RGB의 2진수 자리에 맞게 >> (right shift)하고 int로 캐스팅하여 10진수로 RGB의 값을 나타낼 수 있다.
'개발 > C++' 카테고리의 다른 글
[C++] 3.3 비트단위 연산자 (0) | 2023.06.13 |
---|---|
[C++] 3.2 sizeof, 쉼표, 조건부 연산자 [ comma operator ] (0) | 2023.06.13 |
[C++] 3.1 연산자와 증감연산자 (0) | 2023.06.13 |
[C++] 2.4 리터럴 상수, 심볼릭 상수 (0) | 2023.06.12 |
[C++] 2.3 불리언 자료형과 if문, 문자형(Char) [캐스팅, 버퍼, limits] (0) | 2023.06.01 |