잔잔이네
article thumbnail

비트플래그


비트플래그 ( |= / 아이템 획득 )

#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; }

&= ~의 비트연산을 통하여 아이템을 잃은 것도 표현할 수 있다.

 

item3optopt3인데(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, opt3or 연산한 결과를 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의 값을 나타낼 수 있다.


 

profile

잔잔이네

@잔잔잔잔

🌈

검색 태그