데이터의 연산(산술연산, 논리 연산등) 수행 시 대부분의 경우 수치 및 논리적 조건을 다룰 때 bit 단위가 아닌 변수가 나타내는 데이터의 단위로 연산이 수행된다.
그러나, ip나 서브넷 마스크를 다루거나, 플래그 설정 및 해제 등의 경우에서는 비트 단위의 연산이 요구된다.
이러한 연산을 수행하기 위한 연산자를 bitwise operator(비트 연산자)라 한다.
: 비트 연산을 위해 사용되는 연산자는 다음과 같다.
① left shift ( << )
x << y
- x의 모든 비트를 왼쪽으로 y만큼 이동
// x : 0011
int x=3;
// y : 0110 = 6
int y= (x<<1);
// z : 1100 = 12
int z= (x<<2);
② right shift ( >> )
x >> y
- x의 모든 비트를 오른쪽으로 y만큼 이동
// x : 1100
int x=12;
// y : 0110 = 6
int y= (x>>1);
// z : 0011 = 3
int z= (x>>2);
① Bitwise NOT (~)
: 변수 단위의 NOT 연산자는 "!" 인반면 비트 단위의 NOT 연산자는 "~"이다.
~(X)
- X의 모든 비트를 반전(0->1, 1->0)
② Bitwise AND (&)
: 변수 단위의 AND 연산자는 "&&" 인반면 비트 단위의 AND 연산자는 "&"이다.
X&Y
- X와 Y의 모든 비트를 AND 연산한 결과
③ Bitwise OR (|)
: 변수 단위의 OR 연산자는 "||" 인반면 비트 단위의 OR 연산자는 "|"이다.
X|Y
- X와 Y의 모든 비트를 OR 연산한 결과
④ Bitwise XOR (^)
: 변수 단위의 XOR 연산자는 "!=" 인반면 비트 단위의 XOR 연산자는 "^"이다.
X^Y
- X와 Y의 모든 비트를 XOR 연산한 결과
bit 연산자를 활용해 문제 해결에 적용해보도록 한다.
ⓐ 짝수의 경우
6 (0110)
→ 0111
ⓑ 홀수의 경우
11 (1011)
→ 1'1'11
→ 11'0'1 (13)
7 (0111)
→ '1'111
→ 1'0'11 (11)
if (no % 2 == 0)
{
answer.push_back(no + 1);
continue;
}
else
{
// 뒤에서부터 처음으로 '0'인 곳->'1' (npos)
// '1'이 나온 다음 위치에서부터 처음으로 '1'인 숫자 -> '0' (xpos)
int npos = 0;
while (npos <= 63)
{
//1LL = 1 (long long) = 0000...0001
// no의 npos 위치가 0이라면
if ((no & (1LL << npos)) == 0)
break;
npos++;
}
int xpos = npos-1;
bool isval = false;
while (xpos >= 0)
{
if ((no & (1LL << xpos)) != 0)
{
isval = true;
break;
}
xpos--;
}
no += pow(2, npos);
if(isval)
no -= pow(2, xpos);
answer.push_back(no);
}
ⓐ 홀수인 경우 - npos 구하기
: 뒤에서부터 최초로 '0'이 아닌 비트의 위치 탐색
while (npos <= 63)
{
if ((no & (1LL << npos)) == 0)
break;
npos++;
}
ⓑ 홀수인 경우 - xpos 구하기
: npos로부터 최초로 '1'인 비트의 위치 탐색 (없다면 isval(false))
while (xpos >= 0)
{
if ((no & (1LL << xpos)) != 0)
{
isval = true;
break;
}
xpos--;
}