본문 바로가기
개발/C, C++

[C/C++] 비트 연산자

by 77monkey 개발자 2023. 9. 11.
반응형

비트 연산자를 잘 활용하면 알고리즘이나 개발을 할 때 유용합니다. 비트 연산자에 대해서 알아보고 활용할 수 있도록 배워 봅시다. 

참고로 논리 연산자와 비트 연산자가 비슷하게 생겨서 헷갈리실 수 있습니다. 관련 글 링크를 올려둘 테니, 비교해 보시는 것도 도움이 되실 것 같습니다.

 

[C/C++] 논리 연산자

논리 연산자는 조건문과 논리적인 표현을 다룰 때 중요합니다. C/C++에는 논리 연산자가 3가지가 있는데 살펴보도록 하겠습니다. 논리 연산자 논리 AND 연산자 (&&) 논리 AND 연산자는 두 개의 조건

77monkey.tistory.com


 

비트 연산자

비트 연산자는 비트 단위로 데이터를 연산할 때 사용됩니다. 데이터 타입을 표현할 때에는 바이트 단위이지만, 우리는 그 하위 단위인 비트 단위로 연산을 하려고 합니다. 예를 들면 char는 1바이트로 가장 작은 단위이지만, 그 안에는 8bit가 포함되어 있습니다. 

 

1Byte는 1bit 입니다.
char(1Byte)는 8bit로 구성되어 있습니다.

 

비트 연산자에는 &(AND), |(OR), ^(XOR), ~(NOT), <<(left shift), >>(right shift)가 있습니다. 

 

AND 연산자 (&)

AND 연산자는 두 비트가 1일 때 결과가 1이고 그렇지 않으면 0이 됩니다. 

a와 b가 1bit를 표현한다는 가정하에 아래 표로 연산 결과를 확인해 보도록 하겠습니다.

a(1 bit) b(1 bit) a & b
0 0 0
0 1 0
1 0 0
1 1 1

논리 연산자에서 &&와 유사하지 않나요? 어쩌면 헷갈리실 수도 있을 것 같습니다. 천천히 다음 연산자도 알아보도록 하겠습니다. 

 

OR 연산자 (|)

OR 연산자는 한 비트가 1일 때 결과가 1이고 둘 다 0일 때 0이 됩니다. 

a와 b가 1bit를 표현한다는 가정하에 표를 통해서 연산 결과를 알아봅시다. 

a(1 bit) b(1 bit) a | b
0 0 0
0 1 1
1 0 1
1 1 1

논리 연산자에서 ||와 유사합니다. |와 || 연산 결과가 유사하다고 같은 것은 아닙니다. 예를 들면 1 | 1 의 결과는 1이지만, 3(0b11) | 5(0x101) 의 결과는 7(0x111) 입니다. 그에 반해 1 || 1의 결과는 1로 OR 연산자와 같지만, 3 || 5 의 결과는 1입니다. 차이점이 보이실까요??

 

XOR 연산자 (^)

두 비트 중 하나만 1인 경우 결과는 1이고 비트가 같은 값이면 0이 됩니다. 

a와 b가 1bit를 표현한다고 했을 때 연산 결과는 아래와 같습니다. 

a(1 bit) b(1 bit) a ^ b
0 0 0
0 1 1
1 0 1
1 1 0

AND 연산자도 아니고, OR 연산자도 아닌 게 조금 독특한 연산자입니다.

 

NOT 연산자 (~)

NOT 연산자는 1을 0으로, 0을 1로 반전시킬 때 사용하는 연산자입니다. 다른 연산자는 이항 연산자로 연산자 앞뒤로 피연산자가 필요하지만, NOT 연산자는 단일 연산자로 연산자 뒤에 피연산자 하나만 필요합니다. 

a(1 bit) ~a
0 1
1 0

주의하실 것은 NOT 연산자(~)와 논리 NOT 연산자(!)와 다릅니다. 8bit 내에서 ~2(0b00000010)은  -3(0b11111101)입니다. 하지만 !2(0b00000010)는 참의 부정이기 때문에 거짓인 0입니다. 

 

left shift 연산자 (<<)

left shift 연산자는 왼쪽으로 n비트만큼 이동합니다. 예를 들면 3(0b11)을 3<<1을 하게 되면 6(0b110)이 됩니다. 

왼쪽으로 이동한 만큼 0으로 채워지는데, 0의 개수가 피연산자 개수만큼 늘어난다고 생각하시면 편하실 수도 있을 것 같습니다.

left shift 연산자 표현
left shift 연산자의 피연산자만큼 왼쪽으로 이동하게 됩니다.

 

right shift 연산자(>>)

right shift 연산자는 오른쪽으로 n비트만큼 이동합니다. 예를 들면 3(0b11)을 3>>1을 하게 되면 1(0b1)이 됩니다.

오른쪽으로 이동한만큼 해당 비트가 사라지고 오른쪽으로는 0이 채워집니다. 

 

비트 연산자 예시

비트 연산자를 배워봤는데 코드로 살펴보도록 하겠습니다. 

#include <stdio.h>

int main() {
	int a = 2;
	int b = 3;

	printf("a & b => 0x%x\n", a & b); // 0b10 & 0b11 => 0b10
	printf("a | b => 0x%x\n", a | b); // 0b10 | 0b11 => 0b11
	printf("a ^ b => 0x%x\n", a ^ b); // 0b10 ^ 0b11 => 0b01
	printf("a << b => 0x%x\n", a << b); // 0b10 << 3 => 0b10000
	printf("a >> b => 0x%x\n", a >> b); // 0b10 >> 3 => 0b0
	printf("~a => 0x%x\n", ~a); // ~0b10 => 0xfffffffd
	
	return 0;
}

주석으로 bit로 연산을 표현해 보았는데 생각하신 결과와 같으신지요? 실제로 16진수로 출력을 하면 아래와 같이 나옵니다. 

a & b => 0x2
a | b => 0x3
a ^ b => 0x1
a << b => 0x10
a >> b => 0x0
~a => 0xfffffffd

 

마무리

비트연산자는 논리연산자와 비슷하게 생겨서 혼동하실 수도 있습니다. 그렇기 때문에 비트연산자와 논리 연산자를 잘 구별하여 알아두시길 바랍니다. 참고로 비트연산자는 비트연산이기 때문에 비트별로 표현을 하고 연산을 하시면 도움이 됩니다. 해당 값을 10진수로 표현하는 것보다는 16진수로 출력을 하시면 연산의 결과를 확인하실 때 도움이 되실 것입니다.

반응형

'개발 > C, C++' 카테고리의 다른 글

[C/C++] 쉼표 연산자(,)  (0) 2023.09.14
[C/C++] 삼항 조건 연산자(삼항 연산자)  (0) 2023.09.13
[C/C++] 논리 연산자  (0) 2023.09.09
[C/C++] 관계 연산자  (0) 2023.09.08
[C/C++] 증감 연산자(++, --)  (0) 2023.09.07