관리 메뉴

FU11M00N

C언어 비트 연산자 본문

Programming/C Language

C언어 비트 연산자

호IT 2020. 4. 18. 21:51

C언어에서의 연산자는 총 10개의 종류가 있습니다.

이번 포스팅에서는 비트 연산자를 소개하고

나머지는 다음 글에 포스팅하겠습니다!

 

비트 연산자의 종류는 아래의 표와 같습니다.

연산자 사용 예 설명
~ ~a 값 a의 1의 보수(비트 반전)
& a & b 값 a와 b에 대한 AND 연산
| a | b 값 a와 b에 대한 OR 연산
^ a ^ b 값 a와 b에 대한 XOR 연산
<< a << 1

1비트를 좌측으로 이동

(좌측 시프트 연산)

>> a >> 1

1비트를 우측으로 이동

(우측 시프트 연산)

또한 비트 연산을 이해하기 위해서는 위의 비트 연산자 종류에 대한 이해와 함께

아래의 표의 비트 연산 진리표를 알아야 합니다.

a b a&b (and) a|b (OR) a^b (XOR) ~a (NOT)
0 0 0 0 0 1
0 1 0 1 1 1
1 0 0 1 1 0
1 1 1 1 0 0

 

AND는 a, b 모두 1이면 1 , 하나라도 다르면 0

OR는 a, b 둘중 하나라도 1이면 1 , 하나라도 0이면 0 

XOR 은 a,b 같으면 0 , 다르면 1

NOT 은 a 기준으로 a의 반대 값이라고 생각하면 됩니다. a가 0이라면 1 , a가 1이라면 0

 

진리표는 외워두는 게 좋습니다!

#include <stdio.h>

int main(){
	
	int a = 1;
	int b = 2;
	int c = 3;
	unsigned int d = 3;
	
	
	printf("---------------------------------------------\n");
	printf("and or xor 연산\n\n");
	printf("0x%08x | 0x%08x = 0x%08x\n",a,b, a|b);
	printf("0x%08x & 0x%08x = 0x%08x\n",a,b, a&b);
	printf("0x%08x ^ 0x%08x = 0x%08x\n",a,b, a^b);
	printf("~0x%08x = 0x%08x\n",a,~a);
	printf("---------------------------------------------\n");	
	printf("signed 비트 연산\n\n");	
	printf("signed int : 0x%08x >> 1 = 0x%08x\n",c,c >> 1);
	printf("signed int : 0x%08x << 1 = 0x%08x\n",c,c << 1);
	printf("signed int : 0x%08x >> 1 = 0x%08x\n",~c,~c >> 1);
	printf("---------------------------------------------\n");	
	printf("unsigned 비트 연산\n\n");	
	printf("unsigned int : 0x%08x >> 1 = 0x%08x\n",d,d >> 1);
	printf("unsigned int : 0x%08x << 1 = 0x%08x\n",d,d << 1);
	printf("unsigned int : 0x%08x >> 1 = 0x%08x\n",~d,~d >> 1);
				
	return 0;
}

위의 코드는 가독성을 위해 0x%08x를 하여 32비트만 표현하였습니다.

 

1. OR(|) 연산

printf("0x%08x | 0x%08x = 0x%08x\n", a, b, a|b); 이 코드를 보면 | 는 or연산이므로 비트 연산을 하게 되면

아래와 같습니다.

 

OR는 a, b 둘 중 하나라도 1이면 1 , 하나라도 0이면 0  이기 때문에 총결괏값은 3이 나옵니다.

00000000 00000000 00000000 00000001

00000000 00000000 00000000 00000010


00000000 00000000 00000000 00000010

 

 

2. AND(&) 연산

printf("0x%08x & 0x%08x = 0x%08x\n",a, b, a&b);

AND는 a,b 모두 1이면 1 , 하나라도 다르면 0 이기 때문에 총 결과 값은 0이 나옵니다.

 

 

00000000 00000000 00000000 00000001

00000000 00000000 00000000 00000010


00000000 00000000 00000000 00000000

 

3. XOR(^) 연산

printf("0x%08x ^ 0x%08x = 0x%08x\n",a, b, a^b);

XOR 은 a,b 같으면 0 , 다르면 1 이 나오기 때문에 총결괏값은 3이 나옵니다.

 

 

00000000 00000000 00000000 00000001

00000000 00000000 00000000 00000010


00000000 00000000 00000000 00000011

 

4. NOT(~) 연산

printf("~0x%08x = 0x%08x\n", a,~a);

NOT 은 a 기준으로 a의 반대 값이라고 생각하면 됩니다. a가 0이라면 1 , a가 1이라면 0

이기 때문에 총결괏값은 FFFFFFFE 가 나옵니다! 

 

00000000 00000000 00000000 00000001


11111111 11111111 11111111 11111110

 

5. >> (우측 시프트 연산) signed

>>는  우측 시프트 연산라고 부르며  자료형이 unsigned 혹은 signed 형태에 따라 결과 값이 다릅니다.

signed의 경우 가장 왼쪽의 최상의 비트가 1일 경우 우측으로 비트 이동 시 최상위 비트가 1로 채워지고,

최상위 비트가 0일 경우 우측으로 비트 이동 시 최상위 비트가 0으로 채워집니다.

 

00000010 이 오른쪽으로 한칸 시프트 연산하기때문에 00000001이 되어 1의값이 출력됩니다.

 

printf("signed int : 0x%08x >> 1 = 0x%08x\n",c,c >> 1);

00000000 00000000 00000000 00000010


00000000 00000000 00000000 00000001 

 

5-1. >> (우측 시프트 연산) signed

 

만약 최상위 비트가 1이라면 아래와같이 값이 나옵니다.

 

10000000 00000000 00000000 00000000


11000000 00000000 00000000 00000000

 

 

5-2. >> (우측 시프트 연산) unsigned

만약 아래와같이 최상위 비트가 0이라면 우측으로 이동된 비트가 0이 됩니다.

01111111 00000000 00000000 00000000


00111111 00000000 00000000 00000000

 

 

6. << (좌측 시프트 연산) signed , unsigned

printf("signed int : 0x%08x << 1 = 0x%08x\n", c, c << 1);

<<는 좌측 시프트 연산이라고 부르고 자료형이 unsigned와 signed 자료형 상관없이 

n개의 비트를 이동한다고 가정했을 때 오른쪽에서 n개의 비트만큼 0으로 채워지기 때문에

연산을 취하기 이전의 값에 두배가 되는 경우가 나타납니다.

그렇기 때문에 아래의 0 0 0 0 0 0 1 1 이란 3의 값은 좌측 시프트 연산한 칸을 했을 때

                           0 0 0 0 0 1 1 0 이 되기 때문에 6 이란 값이 나옵니다.

 

00000000 00000000 00000000 00000011


00000000 00000000 00000000 00000110

Comments