프로그래밍 언어/C

[C(++)언어 참조] 비트 단위 연산

순정법사 2023.08.17

 

A. 비트 단위 연산(bitwise operation)

1. 비트 연산자

a. 비트 연산자란?

🌟 컴퓨터에서 데이터를 비트 단위로 조작하는 데 사용되는 연산자

 

b. 비트 단위 연산을 사용하는 이유

하드웨어의 발달로 비트단위로 연산을 예전처럼 하지는 않지만,

사용되는 메모리 공간을 줄이거나, 성능의 향상을 기대할 수 있기 때문에

하드웨어 관련 프로그래밍이나 시스템 프로그래밍 등 제한된 자원을 가진 시스템을 위한 프로그램에서는 비트 단위의 연산이 자주 사용

 

c. 비트 연산을 사용하는 곳

  • 비트(bit) 단위로 논리 연산
  • 비트 단위로 오른쪽이나 왼쪽으로 이동시킬 떄 사용
  • 1의 보수로 사용

 

d. 비트 연산의 특징

  • 데이터의 비트를 가지고 논리를 따짐
  • 오른쪽으로 이동 시 값 X2 / 왼쪽으로 이동시 값 /2

 

e. 비트 연산자의 종류

비트 연산자 설명
& 대응되는 비트가 모두 1이면 1을 반환함. (비트 AND 연산)
| 대응되는 비트 중에서 하나라도 1이면 1을 반환함. (비트 OR 연산)
^ 대응되는 비트가 서로 다르면 1을 반환함. (비트 XOR 연산)
~ 비트를 1이면 0으로, 0이면 1로 반전시킴. (비트 NOT 연산)
<< 지정한 수만큼 비트들을 전부 왼쪽으로 이동시킴. (left shift 연산)
>> 부호를 유지하면서 지정한 수만큼 비트를 전부 오른쪽으로 이동시킴. (right shift 연산)

 

f. 비트 연산자의 진리표

비트1 비트2 비트1 &  비트2 비트1 | 비트2 비트1 ^ 비트2 ~ 비트1 ~ 비트2
0 0 0 0 0 1 1
0 1 0 1 1 1 0
1 0 0 1 1 0 1
1 1 1 1 0 0 0

 

 

2. 비트 연산자의 종류

a. 비트 AND(&) 연산 

둘다 참이여아지 참

 

  • 두 개의 피연산자 비트가 모두 1일 때만 1을 반환
  • 두 개의 피연산자를 가지는 이항 연산자

 

🤓 예제

int x = 7;           // 00000000 00000000 00000000 00000111

int y = 10;          // 00000000 00000000 00000000 00001010  

printf("%d", x & y); // 00000000 00000000 00000000 00000010 : 2

 

b. 비트 OR(|) 연산

둘중 하나라도 참이면 참

 

  • 두 개의 피연산자 비트 중 하나라도 1일 때는 1을 반환
  • 두 개의 피연산자를 가지는 이항 연산자

 

🤓 예제

int x = 7;           // 00000000 00000000 00000000 00000111

int y = 10;          // 00000000 00000000 00000000 00001010  

printf("%d", x | y); // 00000000 00000000 00000000 00001111 : 15

 

c. 비트 XOR(^) 연산

천생연분 혐오연산자

 

  • 배타적 논리합(exclusive OR)이라고도 불리며, 두 개의 피연산자 중 하나만이 1일 때 1을 반환
  • 두 개의 피연산자를 가지는 이항 연산자

 

🤓 예제

int x = 7;           // 00000000 00000000 00000000 00000111

int y = 10;          // 00000000 00000000 00000000 00001010  

printf("%d", x ^ y); // 00000000 00000000 00000000 00001101 : 13

 

d. 비트 NOT(~) 연산

청개구리 연산

 

  • 비트 NOT 연산자는 주어진 비트가 1이면 0으로, 0이면 1로 반전시켜 1의 보수로 만듦
  • 피연산자가 단 하나뿐인 단항 연산자
  • 비트 NOT 연산은 부호 비트도 반전시키므로, 결괏값이 음수로 변경됨

 

🤓 예제

int x = 7;        // 00000000 00000000 00000000 00000111  

printf("%d", ~x); // 11111111 11111111 11111111 11111000 : -8

 

e. 왼쪽 시프트 연산(<<)

왼쪽 비트 시프트(shift) 연산자는 비트 이동 연산자라고도 하며, 지정한 수만큼 모든 비트를 전부 왼쪽으로 이동

 

📘 문법

피연산자<<이동할비트수  	//왼쪽 시프트 연산자

 

왼쪽 시프트 연산자(<<, left shift)는 지정한 수만큼 피연산자의 모든 비트를 전부 왼쪽으로 이동

맨 왼쪽의 비트는 지정된 수만큼 버려지고, 오른쪽 비트는 0이 채워짐

 

🤓 예제

int x = -1;        // 11111111 11111111 11111111 11111111
int y = x<<2;      // 왼쪽으로 2비트만큼 이동시킴.
int z = x<<3;      // 왼쪽으로 3비트만큼 이동시킴.  

 

printf("%d\n", y); // 11111111 11111111 11111111 11111100 : -4
printf("%d", z);   // 11111111 11111111 11111111 11111000 : -8

 

 왼쪽 시프트 연산으로 1비트씩 모든 비트를 이동시킬 때마다 피연산자의 값은 두 배씩 증가

이러한 특징을 이용하여 속도가 다소 느린 산술 곱셈 연산을 왼쪽 시프트 연산으로 대체할 수 있음

 

f. 오른쪽 시프트 연산(>>)

지정한 수만큼 모든 비트를 전부 오른쪽으로 이동

 

📘 문법

피연산자>>이동할비트수	//오른쪽 시프트 연산자

 

오른쪽 시프트 연산은 왼쪽 시프트 연산과는 달리 시스템마다 약간의 차이가 발생함

시스템마다 최상위 부호 비트(MSB)까지 연산의 대상이 될때가 있고 안될때가 있음

(현재 대부분의 시스템에서는 최상위 부호 비트(MSB)를 시프트 연산의 대상에서 제외)

따라서 최상위 부호 비트가 중요한 의미를 가지는 부호있는 정수에 대해서는 가급적 시프트 연산 ❌ 

 

🤓 예제

int x = -8;        // 11111111 11111111 11111111 11111000
int y = x>>2;      // 오른쪽으로 2비트만큼 이동시킴.
int z = x>>3;      // 오른쪽으로 3비트만큼 이동시킴.  


printf("%d\n", y); // 11111111 11111111 11111111 11111110 : -2
printf("%d", z);   // 11111111 11111111 11111111 11111111 : -1

 

✏ 오른쪽 시프트 연산으로 1비트씩 모든 비트를 이동시킬 때마다 피연산자의 값은 두 배씩 감소

이러한 특징을 이용하여 속도가 다소 느린 산술 곱셈 연산을 왼쪽 시프트 연산으로 대체할 수 있음

 

 

 


출처 : http://www.tcpschool.com/c/c_refer_bitCalculation

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com