전자공학과에서 비트단위 연산자는 많이 쓰인다. 실제로 모터를 제어할 때, 비트 단위 연산자를 사용하여 구동시킨 적도 있다. 빠른 프로그래밍을 돌려야 할 때 사용한다. 이처럼 제어 부에서 엄청나게 많이 쓰이는 것이 비트 단위 연산자이다. C++에선 어떤 식으로 혹은 어떤 상황일 때 사용하는지 한번 알아보도록 하자.
비트 단위 연산자는 총 6개로 구성되어 있다.
left shift : <<
right shift : >>
Not : ~
And : &
Or : |
Xor : ^
우선 간단한 프로그램부터 살펴보자.
#include <iostream>
#include <bitset>
int main()
{
using namespace std;
unsigned int a = 1;
cout << std::bitset<4>(a) << endl;
return 0;
}
output : 0001
bitset
헤더 파일을 이용하면 bit단위로 어떻게 저장되는지 확인할 수 있다. std::bitset<4>(a) 는 a
라는 변수를 4bit로 출력하라는 뜻이다.
그렇다면 bit단위 연산자를 사용하여 실제로 bit가 어떻게 움직이는지 확인해보자.
#include <iostream>
#include <bitset>
int main()
{
using namespace std;
unsigned int a = 3;
cout << std::bitset<4>(a) << endl;
unsigned int b = a << 1;
cout << std::bitset<4>(b) << endl;
return 0;
}
output : 0011
0110
<<
비트 단위 연산자를 이용하여 0011
을 왼쪽으로 한칸 움직여0110
로 만든 것을 알 수 있다. 그 뒤의 값 경우 0으로 채워 넣는 것 까지 알 수 있다. 만약 2칸을 움직인다면?
#include <iostream>
#include <bitset>
int main()
{
using namespace std;
unsigned int a = 3;
cout << std::bitset<4>(a) << endl;
unsigned int b = a << 2;
cout << std::bitset<4>(b) << endl;
return 0;
}
output : 0011
1100
이제 규칙성을 알 것이다. << 연산자 뒤에 표시하는 정수만큼 비트가 움직이는 것으로 보면 된다.
예를 들어, 2의 제곱을 곱하고 싶을 때에는 shift 연산자를 사용하는 것이 곱하기 연산자보다 훨씬 빠르게 작동한다. 계산량이 많아진다면 shift 연산자를 사용하게 된다.
#include <iostream>
#include <bitset>
int main()
{
using namespace std;
unsigned int a = 64;
cout << std::bitset<8>(a) << endl;
unsigned int b = a >> 1;
cout << std::bitset<8>(b) << endl;
return 0;
}
output : 01000000
00100000
left shift 연산자를 제대로 이해했다면 매우 쉽게 이해된다. 한번 >> 2
를 사용하여 출력을 해보라.
#include <iostream>
#include <bitset>
int main()
{
using namespace std;
unsigned int a = 0b1100;
unsigned int b = 0b0110;
cout << std::bitset<4>(a & b) << endl;
cout << std::bitset<4>(a | b) << endl;
cout << std::bitset<4>(a ^ b) << endl;
return 0;
}
output : 0100
1110
1010
output을 보면 이해가 되지 않을까 싶은데,,, 해석을 하자면
&
같은 경우에는 같은 위치에 있는 bit값이 둘다 1이여야 1이 출력된다.
|
같은 경우에는 같은 위치에 있는 bit값이 하나라도 1이면 1이 출력된다.
^
같은 경우에는 같은 위치에 있는 bit값이 서로 달라야 1이 출력된다.