안녕하십니까. 김동우입니다.
이번 노트에서는 비트 플래그와 마스크에 대해서 얘기할까 합니다.
오늘은 소스가 길고, 많으니 나름대로의 구분을 하겠습니다.
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
// 이 시간은 배열을 더 최적화하여 사용하기 위한 시간이다.
// 즉, 실전용 수업이다.
/*
bool item1_flag = false;
bool item2_flag = false;
bool item3_flag = false;
bool item4_flag = false;
...
1byte 변수 하나로 아이템 8개를 컨트롤 할 수 있다. (bool 1bit on-off)
*/
// opt 선언 - 하드코딩
const unsigned char opt0 = 1 << 0;
const unsigned char opt1 = 1 << 1;
const unsigned char opt2 = 1 << 2;
const unsigned char opt3 = 1 << 3;
const unsigned char opt4 = 1 << 4;
const unsigned char opt5 = 1 << 5;
const unsigned char opt6 = 1 << 6;
const unsigned char opt7 = 1 << 7;
/*
cout << std::bitset<8>(opt0) << endl;
cout << std::bitset<8>(opt1) << endl;
cout << std::bitset<8>(opt2) << endl;
cout << std::bitset<8>(opt3) << endl;
cout << std::bitset<8>(opt4) << endl;
cout << std::bitset<8>(opt5) << endl;
cout << std::bitset<8>(opt6) << endl;
cout << std::bitset<8>(opt7) << '\n' << endl;
*/
// output 생략 이전 강의 참고
// output : 00000001
unsigned char items_flag = 0;
cout << std::bitset<8>(items_flag) << '\n' << endl;
// output : 00000000
// 스위치 on off 개념으로 생각하면
// 8개의 bool type 변수를 사용하는 효과를 낼 수 있다.
// 이후 opt 선언으로 올라가서 생각해보자.
cout << " No item " << bitset<8>(items_flag) << '\n' << endl;
// item0 on
items_flag |= opt0;
cout << " Item0 obtained " << bitset<8>(items_flag)
<< '\n' << endl;
// item3 on + item0 maintain
items_flag |= opt3;
cout << " Item3 obtained " << bitset<8>(items_flag)
<< '\n' << endl;
// item3 lost
items_flag &= ~opt3; // AND assignment + NOT bitwise
cout << " Item3 lost " << bitset<8>(items_flag)
<< '\n' << endl;
// item1 check
if(items_flag & opt1) { cout << " Has item1 " << '\n' << endl; }
else { cout << " Not have item1 " << '\n' << endl; }
// item0 check
if (items_flag & opt0){ cout << " Has item0 " << '\n' << endl; }
// obtain item 2, 3
items_flag |= (opt2 | opt3);
cout << std::bitset<8>(items_flag) << '\n' << endl;
// output : 0000 1101
if((items_flag & opt2) && !(items_flag & opt1))
{
// items_flag ^= opt2;
// items_flag ^= opt1;
items_flag ^= (opt2 | opt1); // 상태변화는 XOR로 처리하면 편하다.
cout << std::bitset<8>(items_flag) << endl;
}
return 0;
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
// 예시 1
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// parameter 정의에 있어 bitwise operator는 상당히 유용하다.
// 즉, API design에 있어 bit flag는 유용할 수 있다.
// 예시 2
// 프론트엔드, 그래픽 디자이너들의 경우 컬러테이블을 활용하는 경우가 많다.
// hex code 기반으로 작성된 컬러테이블은 3byte(rgb) + 1byte(alpha)
// 이를 RGB code로 바꿔보자. (영상처리에도 유용할 수 있겠다.)
const unsigned int red_mask = 0xFF0000;
const unsigned int green_mask = 0x00FF00;
const unsigned int blue_mask = 0x0000FF;
unsigned int pixel_color = 0xDAA520;
cout << bitset<32>(pixel_color) << endl;
// output : 00000000110110101010010100100000
cout << bitset<32>(red_mask) << endl;
cout << bitset<32>(green_mask) << endl;
cout << bitset<32>(blue_mask) << '\n' << endl;
//
unsigned char red, green, blue;
red = (pixel_color & red_mask) >> 16;
green = (pixel_color & green_mask) >> 8;
blue = pixel_color & blue_mask;
cout << " Red " << bitset<8>(red) << " " << int(red) << endl;
cout << " Green " << bitset<8>(green) << " " << int(green) << endl;
cout << " Blue " << bitset<8>(blue)<< " " << int(blue) << endl;
// 1, masking - 0xFF...
// 2. extract - AND bitwise
// 3. RGB - right shift bitwise
return 0;
}
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
// 1. 아래 플래그를 바꿔보세요.
// - 기사를 봤을 때
// - 기사의 좋아요를 클릭했을 때
// - 기사의 좋아요를 다시 클릭했을 때
// - 본 기사만 삭제할 때
unsigned char option_viewed(0x01);
unsigned char option_edited(0x02);
unsigned char option_liked(0x04);
unsigned char option_shared(0x08);
unsigned char option_deleted(0x80);
unsigned char my_article_flags = 0;
// - 기사를 봤을 때
my_article_flags |= option_viewed;
// - 기사의 좋아요를 클릭했을 때
my_article_flags |= option_liked;
// - 기사의 좋아요를 다시 클릭했을 때
if(my_article_flags & option_liked)
{
my_article_flags ^= option_liked;
}
// - 본 기사만 삭제할 때
if ((my_article_flags & option_viewed)
&& (my_article_flags & option_deleted))
{
my_article_flags ^= (option_deleted | option_viewed);
}
// 2. 아래 두 줄이 동일하게 작동하는 이유를 설명하세요
// 초기화 이후의 두 줄
unsigned char option4(1 << 4);
unsigned char option5(1<<5);
unsigned char myflags = 0;
myflags &= ~(option4 | option5);
myflags &= ~option4 & ~option5;
// 드모르간의 법칙을 적용하면 간단하게 설명할 수 있다.
// !A && !B = !(A || B)
// !(A && B) = !A || !B
return 0;
}
quiz.cpp 파일의 코드는 저 스스로의 문제풀이이기 때문에 오답이 존재할 수 있습니다. 또한 flag가 카운트되는 조건 또는 이전 상황이 코드에 존재하지 않는 것은 수업에서 배운 내용을 최대한 생략했기 때문입니다.
그러나 실제로 flag 카운트 이전 모든 option 변수를 0으로 초기화하고, 해당 상활에 맞게 각 문항별로 값을 재할당하는 등의 코드를 추가하면 보다 쉽게 이해할 수 있습니다.
그럼 이만 이번 글은 마치도록 하겠습니다. 감사합니다.