본문 바로가기
프로그래밍/공부

[C++] 비트 연산자

by Sik.K 2022. 12. 13.

수업을 듣는 도중 오랜만에 나온 비트 연산자, 하지만 뭔가 머릿속에 확 남지 않아 다시 정리해본다.

 

비트는 무엇인가. 간단하다. 컴퓨터에서 가장 작은 단위는 바이트이다.

 

이 바이트는 다시 8비트로 이뤄져 있다. 이 8비트는 무엇인가 바로 여덟 자리의 이진수이다.

 

00000000 이것이 바로 8비트이다.

 

그렇다면 비트 연산자는 무엇일까?

 

바로 이 비트를 연산하는 연산자(Operator)이다.

 

이 중 밑의 3개는 시프트 연산자라 하여 비트의 이동을 연산하는 연산자이다.

 

비트 연산자 &, |, ~, ^는 비트에 대해 논리 연산을 한다. 참과 거짓을 반환하는 논리 연산자처럼 비트 연산자는 두 개의 비트에 대해서 결과에 따라 1과 0을 반환한다.

 

비트 연산자의 연산 결과

 

 

그렇다면 밑의 시프트 연산자는 어떻게 연산이 될까?

 

예를 들어 int 자료형 a가 있고 a 에는 2라는 값이 담겨 있다고 가정해보자.

 

이 a의 값인 2를 비트로 표현하면

 

'00000000 00000000 00000000 00000010'

 

이 된다. 4바이트 자료형인 int 이기 때문에 32비트가 되고 이를 표현하면 저렇게 된다.

 

이 때 a << 3을 하게 되면 어떤 일이 일어날까?

 

바로 코드로 확인해보자

 

#include <iostream>

using namespace std;

int main()
{
	int a = 2;

	a <<= 2;

	cout << a << endl;

	return 0;
}

a << 2를 한 뒤 대입하고 바로 a의 값을 출력해보았다.

 

결과값

결과는 놀랍게도 8이다.

 

사실 그닥 놀랍지는 않지만 처음 배우는 것처럼 하기 위해서 놀란 척을 해보았다.

 

이유는 다음과 같다. a의 값은 2이고 int 자료형은 32비트이다. 그러니까 다음과 같다는 말이다.

 

 '00000000 00000000 00000000 00000010'

 

이 때 a에 시프트 연산자로 <<= 2를 하게 되면 현재 a의 비트를 왼쪽으로 2칸 밀고 다시 a에 대입한다는 말이 된다. 즉 다음과 같다는 것이다.

 

 '00000000 00000000 00000000 00001000'

 

따라서 이를 10진법으로 계산하면 2^3 즉, 8이 되는 것이다.

 

그렇다면 이것을 오른쪽으로 4칸 미는, >>= 4를 하게 되면 어떻게 될까? 이에 대한 결과값을 확인해 보았다.

 

#include <iostream>

using namespace std;

int main()
{
	int a = 2;

	a <<= 2;

	cout << a << endl;

	a >>= 4;

	cout << a << endl;

	return 0;
}

 

왜 이런 결과가 나온 걸까? 위에서 말했지만 int 자료형은 32비트이다. 그리고 자료형을 선언하게 되면 메모리 상에 특정 공간에 할당이 된다. 이 때 int 자료형의 크기인 32비트만큼 담겨 있는 이 a라는 자료형의 비트를 오른쪽으로 4칸 밀게 되면 다음과 같아진다.

 

 '00000000 00000000 00000000 00000000' 1 

 

즉, a의 범위를 벗어나기 때문에 값이 사라지고 a는 0이 되는 것이다. 결과적으로 비트 연산을 잘못하여 데이터 손실이 생긴 것이다.

 

이런 위험성이 있기 때문에 비트 연산을 할 때에는 잘 생각하며 해야 오류를 줄일 수 있다.

댓글