반응형
비트 연산자( AND &, OR |, XOR ^, SHIFT <<, >>)에 대한 내용 및
이 비트 연산자를 이용하여 비트 연산을 응용하는 방법을 설명해 두었고,
중요한 내용은 [중요]라고 표기해 두었습니다.
모든 내용은 소스 코드에 수록되어있고, 소스 코드에 주석과 함께 설명을 달아두었습니다.
소스 코드 아래에는 스크린샷을 통해 출력 화면을 확인 할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | #include <iostream> #include <cstdio> #include <math.h> using namespace std; int main() { int val; // AND 연산 (&) val = 754 & 470; cout << "AND 연산 (&)\n" << endl; cout << "754의 bit 값 :: " << "0010 1111 0010" << endl; cout << "470의 bit 값 :: " << "0001 1101 0110" << endl; cout << "754 & 470 값 :: " << "0000 1101 0010 :: " << val << endl; cout << endl; // OR 연산 (|) val = 754 | 470; cout << "OR 연산 (|)\n" << endl; cout << "754의 bit 값 :: " << "0010 1111 0010" << endl; cout << "470의 bit 값 :: " << "0001 1101 0110" << endl; cout << "754 | 470 값 :: " << "0011 1111 0110 :: " << val << endl; cout << endl; // XOR 연산 (^) val = 754 ^ 470; cout << "XOR 연산 (^)\n" << endl; cout << "754의 bit 값 :: " << "0010 1111 0010" << endl; cout << "470의 bit 값 :: " << "0001 1101 0110" << endl; cout << "754 ^ 470 값 :: " << "0011 0010 0100 :: " << val << endl; cout << endl; // 좌측 쉬프트 연산 (<<) val = 1234 << 1; cout << "좌측 쉬프트 연산 (<<)\n" << endl; cout << "1234 bit 값 :: " << "0100 1101 0010" << endl; cout << "1234 << 1 값 :: " << "1001 1010 0100 :: " << val << endl; cout << endl; // 우측 쉬프트 연산 (>>) val = 2468 >> 1; cout << "우측 쉬프트 연산 (>>)\n" << endl; cout << "2468 bit 값 :: " << "1001 1010 0100" << endl; cout << "2468 >> 1 값 :: " << "0100 1101 0010 :: " << val << endl; cout << endl; cout << "* 즉, 좌측 쉬프트 연산을 하게 되면 <현재값 * 2>를 할 수 있고, *" << endl; cout << "* 우측 쉬프트 연산을 하게 되면 <현재값 / 2>를 할 수 있다. *" << endl; cout << endl; // 비트 연산 시 주의 사항 val = (6 & 4 == 4); cout << "비트 연산 시 주의 사항\n" << endl; cout << "6 & 4 값 :: :: " << "0100" << endl; cout << "6 & 4 == 4 값 :: " << val << endl; val = ((6 & 4) == 4); cout << "(6 & 4) == 4 값 :: \n" << val << endl; cout << "* 즉, bit 연산이 우선순위가 높다 해도 더 높은 우선순위 연산자가 있기에 *" << endl; cout << "* bit 연산 시에는 항상 괄호를 습관화 한다." << endl; cout << endl; // 쉬프트 연산 시 주의 사항 long long int ex1, ex2; ex1 = 1 << 30; cout << "1 << 30 :: " << ex1 << endl; ex1 = 1 << 32; cout << "1 << 31 :: " << ex1 << endl; cout << endl; ex2 = 1ull << 30; cout << "1ull << 30 :: " << ex2 << endl; ex2 = 1ull << 62; cout << "1ull << 31 :: " << ex2 << endl; cout << endl; cout << "* 즉, C++에서 1은 부호 있는 32비트 상수로 취급 되기 때문에" << endl; cout << "<< x에서 x값이 32 이상이면 오버 플로우가 발생한다.\n" << endl; cout << "따라서 경우에 따라 ull을 이용하여 부호 없는 상수로 취급하도록 만들어 주어야 한다." << endl; cout << endl; // 집합의 표현 cout << "집합의 표현 \n" << endl; cout << "집합 A :: {1, 4, 16, 64}" << endl; cout << "집합 B :: {2, 8, 32, 128}" << endl; cout << endl; int A = 0, B = 0; // 0000 0000비트에 합집합 |= 방식을 이용하여 집합을 생성 for (int i = 0; i < 4; i++) { A |= (1 << (i * 2)); B |= (1 << ((i * 2) + 1)); } cout << "현재 A :: 0101 0101" << endl; cout << "현재 B :: 1010 1010" << endl; cout << "A :: " << A << " B :: " << B << endl; cout << endl; // 집합의 확인은 & 기호를 이용하여 확인 할 수 있다. cout << "집합 A의 원소 나열 :: "; for (int i = 0; i < 8; i++) if (A & (1 << i)) cout << pow(2,i) << " "; cout << endl; cout << "집합 B의 원소 나열 :: "; for (int i = 0; i < 8; i++) if (B & (1 << i)) cout << pow(2, i) << " "; cout << "\n" << endl; // 전체 집합 만들기 int C = 0; cout << "집합 C로 1111 1111 만들기" << endl; C = (1 << 8) - 1; cout << "집합 C의 원소 나열 :: "; for (int i = 0; i < 8; i++) if (C & (1 << i)) cout << pow(2, i) << " "; cout << "\n" << endl; // 원소의 삭제 C -= 1 << 3; cout << "원소의 삭제를 통한 집합 C의 원소 나열 :: "; for (int i = 0; i < 8; i++) if (C & (1 << i)) cout << pow(2, i) << " "; cout << "\n" << endl; // 원소의 토글 (XOR 이용) for(int i = 0 ; i < 8 ; i ++) C ^= 1 << i; cout << "토글된 집합 C의 원소 나열 :: "; for (int i = 0; i < 8; i++) if (C & (1 << i)) cout << pow(2, i) << " "; cout << "\n" << endl; // 집합 크기 구하기 int cnt = 0; for (int i = 0; i < 8; i++) if (C & (1 << i)) cnt++; cout << "집합 C의 크기 :: " << cnt << endl; // [중요] 최하위 비트 구하기(펜윅 트리에 이용) /* :: 원리 :: 1100이 있다고 생각하자 1100의 2의 보수는 0011에서 + 1을 한 0100이다, 결국 1100은 val이고 0100은 -val이다. 이 두개를 & 연산을 하게 된다면 0100이 되는데 이때 1은 최하위 비트 위치를 의미하고 있다. 위의 예시를 이용하여 일반적인 식을 도출하면 (val & -val)을 이용하면 최하위 비트를 구할 수 있다. */ val = 12; // 1100 int first = (val & -val); cout << "최하위 비트 값 :: " << first << endl; cout << endl; // [중요] 최소 원소(최하위 비트) 지우기 /* :: 원리 :: 예를 들어보자. 40이라는 값이 있다. 이 값의 비트는 0010 1000이다. 이때 val - 1은 39 즉, 이 값의 비트는 0010 0111이다. 그럼 val & val - 1은 0010 0000이다. 즉, 값 - 1을 하게 되면 최하위 비트가 0이되고 그 뒤로는 모두 1이 되는데, 이 값을 &연산을 하게 된다면 최하위 비트부터 모두 0이된다. */ val = 12; // 1100 cout << "현재 값 :: " << val << endl;\ val &= val - 1; cout << "최소 원소(최하위 비트)를 지운 값 :: " << val << endl; cout << endl; // [중요] 모든 부분 집합 순회하기 // 위의 방식을 이용하여 모든 부분 집합을 나열 할 수 있다. val = 12; cout << "집합 val의 원소 나열 :: "; for (int i = 0; i < 8; i++) if (val & (1 << i)) cout << pow(2, i) << " "; cout << "\n" << endl; cout << "집합 val의 모든 부분 집합 나열 ::"; for(int subset = val; subset; subset = ((subset - 1) & val)) cout << subset << " "; return 0; } // This source code Copyright belongs to Crocus // If you want to see more? click here >> | Crocus |
반응형
'Applied > 자료구조' 카테고리의 다른 글
튜플(Tuple) STL 사용 방법 (2) | 2017.02.14 |
---|---|
페어(Pair) STL 사용 방법 (0) | 2017.02.14 |
배열을 이용한 이진 트리(Binary Tree) (0) | 2016.11.24 |
비트셋(Bitset) STL 사용 방법 (0) | 2016.11.22 |
스트링(String) STL 사용 방법 (0) | 2016.11.03 |