◈ 이 글은 강의를 위하여 제가 직접 작성한 내용입니다. 따라서 퍼가실 경우, 출처를 명확히 해주시기 바랍니다!!
◈ This ariticle was written by me for teaching. So if you want to copy this article, please clarify the source!!
◈ This ariticle was written by me for teaching. So if you want to copy this article, please clarify the source!!
2,8,16진수에 대해서 먼저 이해하고 비트 연산자를 알아보도록 하자.
// 2,8,16진수에 대해 설명한다. /* 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27 30 31 8421 8421 1011 / 0101 = b5 = b*16 + 5 = 11*16 + 5 = 176 + 5 = 181 1+2+8 = b, 1+4 = 5 21 421 421 10 / 110 / 101 = 265 = 2 * 64 + 6 * 8 + 5 = 128 + 48 + 5 = 181 2, 2+4=6, 1+4 = 5 */ // 기본적인 연산자에 대한 설명을 한다. /* AND(&) 1&1=1 1&0=0 0&1=0 0&0=0 OR(|) 1&1=1 1&0=1 0&1=1 0&0=0 XOR(^) 1&1=0 1&0=1 0&1=1 0&0=0 1의보수(~) ~1=0 ~0=1 ~1001=0110 컴퓨터에서는 음수를 2의 보수로 표현한다. 2의 보수는 1의 보수에 1을 더하면 된다. 즉, ~5의 의미는 5의 1의 보수이므로 2의 보수인 -5에서 1을 빼주면 -6이 된다. int a = 5; ~a = -6이 된다. 00000000 00000000 00000000 00001010 = 10 11111111 11111111 11111111 11111010 = -6 끝자리 1은 버림 421 100000000 00000000 00000000 00000100 = 4 */ #includeusing namespace std; //shift 연산 int main( ) { cout << "\n-------- Shift 연산 -------------" << endl; cout << 65 << " << " << 3 << " = " << (65 << 3) << endl; //01000001 << 3 cout << 65 << " >> " << 3 << " = " << (65>>3) << endl; //01000001 >> 3 cout << endl; int n=65; for(int i=0;i <= 32/3;i++) { int num=(n&(7)); //7 -> 111(2진수) //00 000 000 000 000 000 000 000 001 000 001 & 111 cout << num; n = n>>3; //오른쪽 쉬프트 01100 >>3은 01 //00 000 000 000 000 000 000 000 001 000 3칸(001) 버림 }//반대 방향으로 출력 cout << " <--여기서 부터 읽자." << endl; return 0; } // 2진수 출력구문으로 변경해보자. // 수정해야 할 곳은 3군데이다. // 1. 32/3 -> 32 // 2. 7 -> 1 // 3. n>>3 -> n>>1
비트 연산을 이용하여 플래그를 조작해보자.
#includeusing namespace std; typedef unsigned int UINT; /* 1 -> 00000001 2 -> 00000010 4 -> 00000100 8 -> 00001000 16 -> 00010000 */ const UINT PLAYER_NONE = 0; const UINT PLAYER_ATTACK = 1; const UINT PLAYER_DEFENCE = 2; const UINT PLAYER_MAGIC = 4; const UINT PLAYER_HEAL = 8; const UINT PLAYER_BUFF = 16; void ShowPlayerStatus(UINT status); void main( ) { UINT playerStatus = PLAYER_ATTACK | PLAYER_MAGIC | PLAYER_BUFF; ShowPlayerStatus(playerStatus); } void ShowPlayerStatus(UINT status) { if(status & PLAYER_ATTACK) cout << "플레이어가 공격중입니다." << endl; if(status & PLAYER_DEFENCE) cout << "플레이어가 방어중입니다." << endl; if(status & PLAYER_MAGIC) cout << "플레이어가 마법중입니다." << endl; if(status & PLAYER_HEAL) cout << "플레이어가 치료중입니다." << endl; if(status & PLAYER_BUFF) cout << "플레이어가 버프중입니다." << endl; }
연습문제
// 2진수를 정방향으로 출력하시오. #includeusing namespace std; void ShowToBinary(int NUM); void main() { int num = 0; cout << "양 또는 음의 10진 정수를 입력하세요. " << endl; cin>>num; cout << "12345678901234567890123456789012" << endl << endl; ShowToBinary(num); } void ShowToBinary(int NUM) { const int BinarySizeOfInt = sizeof(NUM)*8; char BIN[BinarySizeOfInt+1]; BIN[BinarySizeOfInt] = '\0'; for(int X=0, Y=BinarySizeOfInt-1; X < BinarySizeOfInt; X++, Y--) { int LSB = NUM & (1 << X); if(LSB) BIN[Y] = '1'; else BIN[Y] = '0'; } cout << BIN << endl; }
// 11부터 50까지의 숫자를 8로 나눈 몫과 나머지를 구하되 비트연산자만을 이용하시오. // 출력결과는 아래와 같다. /* Index : 11 11/8 = 1 11%8 = 3 Index : 12 12/8 = 1 12%8 = 4 Index : 13 13/8 = 1 13%8 = 5 . . . Index : 47 47/8 = 5 47%8 = 7 Index : 48 48/8 = 6 48%8 = 0 Index : 49 49/8 = 6 49%8 = 1 Index : 50 50/8 = 6 50%8 = 2 */ #includeusing namespace std; void main() { for( int index=11; index<=50; index++ ) { int indexDiv8 = index >> 3; int indexMod8 = index & 7; cout << "Index : " << index << "\t" << index << "/8 = " << indexDiv8 << "\t" << index << "%8 = " << indexMod8 << endl; } }
#includeusing namespace std; typedef unsigned int UINT; const UINT PLAYER_NONE = 0; const UINT PLAYER_ATTACK = 1; const UINT PLAYER_DEFENCE = 1 << 1; const UINT PLAYER_MAGIC = 1 << 2; const UINT PLAYER_HEAL = 1 << 3; const UINT PLAYER_BUFF = 1 << 4; void SetStatus(UINT& status, UINT flag); void AddStatus(UINT& status, UINT flag); void DelStatus(UINT& status, UINT flag); void ShowPlayerStatus(UINT status); void main( ) { UINT playerStatus = PLAYER_NONE; SetStatus(playerStatus, PLAYER_DEFENCE); ShowPlayerStatus(playerStatus); AddStatus(playerStatus, PLAYER_HEAL); ShowPlayerStatus(playerStatus); AddStatus(playerStatus, PLAYER_ATTACK | PLAYER_BUFF); ShowPlayerStatus(playerStatus); DelStatus(playerStatus, PLAYER_HEAL | PLAYER_DEFENCE); ShowPlayerStatus(playerStatus); SetStatus(playerStatus, PLAYER_MAGIC | PLAYER_BUFF); ShowPlayerStatus(playerStatus); } void SetStatus(UINT& status, UINT flag) { status = flag; } void AddStatus(UINT& status, UINT flag) { status |= flag; } void DelStatus(UINT& status, UINT flag) { status &= ~flag; // XOR연산을 사용해도 제거할 수는 있지만, // 없는 값을 제거하려고 하면 오히려 추가가 되어버리므로 사용해선 안된다. } bool HasStatus(UINT& status, UINT flag) { return ((status & flag) == flag); } void ShowPlayerStatus(UINT status) { cout << "NowStatus is..." << endl; if(HasStatus(status, PLAYER_ATTACK)) cout << " PLAYER_ATTACK" << endl; if(HasStatus(status, PLAYER_DEFENCE)) cout << " PLAYER_DEFENCE" << endl; if(HasStatus(status, PLAYER_MAGIC)) cout << " PLAYER_MAGIC" << endl; if(HasStatus(status, PLAYER_HEAL)) cout << " PLAYER_HEAL" << endl; if(HasStatus(status, PLAYER_BUFF)) cout << " PLAYER_BUFF" << endl; cout << endl; } // void ShowPlayerStatus(UINT status) // { // cout << "NowStatus is..." << endl; // if(status & PLAYER_ATTACK) cout << " PLAYER_ATTACK" << endl; // if(status & PLAYER_DEFENCE) cout << " PLAYER_DEFENCE" << endl; // if(status & PLAYER_MAGIC) cout << " PLAYER_MAGIC" << endl; // if(status & PLAYER_HEAL) cout << " PLAYER_HEAL" << endl; // if(status & PLAYER_BUFF) cout << " PLAYER_BUFF" << endl; // cout << endl; // }