본문 바로가기
기타/보관소

C언어 :: 비트 연산자, 비트 이동 연산자

by rockykim 2015. 11. 22.


조금씩 C언어에 대해 공부 중인데요. 공부하면서 틈틈히 관련된 내용을 올릴 예정입니다.




C언어 :: 비트 연산자, 비트 이동(Shift) 연산자





비트 단위로 연산을 진행하는 비트 연산자는 주로 하드웨어 관련 프로그래밍에 활용되지만,


그 이외의 영역에서도 사용되어 메모리 공간의 효율성을 높이고 연산의 수를 줄이는 요인이 되기도 한다.




 연산자

연산자의 기능 

&


 AND 연산

 예) num1 & num2;


|


 OR 연산

 예) num1 | num2;


^


 XOR 연산

 예) num1 ^ num2


~


 단항 연산자로 피연산자의 모든 비트를 반전시킴

 예) ~num; // num은 변화 없음, 반전 결과만 반환


<<


 피연산자의 비트 열을 왼쪽으로 이동시킴

 예) num<<2; // num은 변화 없음, 두 칸 왼쪽 이동 결과만 반환


>>


 피연산자의 비트 열을 오른쪽으로 이동시킴

 예) num>>2; // num은 변화 없음, 두 칸 오른쪽 이동 결과만 반환




<< 연산자와 >> 연산자는 '비트 이동(Shift) 연산자'






& 연산자: 비트단위 AND


& 연산은 두 개의 비트가 모두 1일 때 1을 반환하는 연산.


따라서 & 연산자의 비트단위 연산의 결과는 다음과 같다.


      • 0 & 0            0을 반환

      • 0 & 1           0을 반환

      • 1 & 0            0을 반환

      • 1 & 1            1을 반환



예제를 살펴보자.





예제에 대한 결과는 이렇다.




결과에 대한 이해를 돕자면


num1    00000000 00000000 00000000 00001111

num2    00000000 00000000 00000000 00010100


&연산 


num3    00000000 00000000 00000000 00000100


num1의 비트와 num2의 비트가 모두 1이여야만 1을 반환한다.


따라서 4가 된다.








| 연산자: 비트단위 OR


| 연산은 두 개의 비트 중 하나라도 1이면 1을 반환하는 연산.


따라서 | 연산자의 비트단위 연산의 결과는 다음과 같다.


      • 0 | 0           0을 반환

      • 0 | 1            1을 반환

      • 1 | 0            1을 반환

      • 1 | 1           1을 반환



예제를 살펴보자.





예제에 대한 결과는 이렇다.




결과에 대한 이해를 돕자면


num1    00000000 00000000 00000000 00001111

num2    00000000 00000000 00000000 00010100


|연산 


num3    00000000 00000000 00000000 00011111


num1의 비트와 num2의 비트 중 하나라도 1이면, 1을 반환한다.


따라서 31이 된다.








^ 연산자: 비트단위 XOR


^ 연산은 두 개의 비트가 서로 다른 경우에 1을 반환하는 연산.


따라서 ^ 연산자의 비트단위 연산의 결과는 다음과 같다.


      • 0 ^ 0            0을 반환

      • 0 ^ 1            1을 반환

      • 1 ^ 0            1을 반환

      • 1 ^ 1            0을 반환



예제를 살펴보자.





예제에 대한 결과는 이렇다.




결과에 대한 이해를 돕자면


num1    00000000 00000000 00000000 00001111

num2    00000000 00000000 00000000 00010100


^연산 


num3    00000000 00000000 00000000 00011011


num1의 비트와 num2의 비트가 서로 다르면 1을 반환한다.


따라서 27이 된다.









~ 연산자: 비트단위 NOT


~ 연산은 비트를 0에서 1로, 1에서 0으로 반전하는 연산. 보수연산이라고도 불림.


따라서 ~ 연산자의 비트단위 연산의 결과는 다음과 같다.


      • ~ 0            1을 반환

      • ~ 1            0을 반환



예제를 살펴보자.





예제에 대한 결과는 이렇다.




결과에 대한 이해를 돕자면


num1    00000000 00000000 00000000 00001111


~연산 


num3    11111111 11111111 11111111 11110000


num1의 모든 비트의 0과 1이 반전시킨 결과이다. MSB 역시 반전되어 음수로 나타난다.


따라서 -16이 된다.








<< 연산자: 비트의 왼쪽 이동 Shift


<< 연산자는 두 개의 피연산자를 요구하며 다음의 의미를 갖는다.

      • num1 << num2        num1의 비트 열을 num2칸씩 왼쪽으로 이동시킨 결과를 반환

      • 8 << 2                정수 8의 비트 열을 2칸씩 왼쪽으로 이동시킨 결과를 반환



예제를 살펴보자.





예제에 대한 결과는 이렇다.




결과에 대한 이해를 돕자면


num      00000000 00000000 00000000 00001111 


result1    00000000 00000000 00000000 00011110 // 10진수로 30

result1    00000000 00000000 00000000 00111100 // 10진수로 60

result1    00000000 00000000 00000000 01111000 // 10진수로 120


num의 비트를 각각 1, 2, 3칸씩 왼쪽으로 이동했다. 이로 인해서 생기는 오른쪽 빈 칸은 0으로 채워지고


왼쪽으로 밀려나는 비트들은(4바이트를 넘어서는 비트들) 그냥 버려진다.


비록 그 값이 1이더라도 말이다.



예제를 통해 한 가지 사실을 더 알 수 있는데,


비트의 열을 왼쪽으로 1칸씩 이동시킬 때마다 정수의 값은 두 배가 된다.


그리고 위의 내용을 토대로 다음 사실도 알 수 있다.


비트의 열을 오른쪽으로 1칸씩 이동시킬 때마다 정수의 값은 2로 나누어진다.



이 사실을 통해, 상황에 따라 곱셈과 나눗셈 연산을 비트 이동 연산으로 대체할 수 있다는 것도 알 수 있다.









>> 연산자: 비트의 오른쪽 이동 Shift


>> 연산자는 두 개의 피연산자를 요구하며 다음의 의미를 갖는다.

      • num1 >> num2        num1의 비트 열을 num2칸씩 오른쪽으로 이동시킨 결과를 반환

      • 8 >> 2                정수 8의 비트 열을 2칸씩 오른쪽으로 이동시킨 결과를 반환



>> 연산자에서 중요하게 볼 부분은 음수의 이동이다.


양수의 이동이야 MSB가 원래 0이었기 때문에, 자동으로 0이 채워지면 상관이 없지만 음수라면 이야기가 다르다.


다음 -16에 해당하는 비트 열을 >> 연산을 통해서 2칸씩 오른쪽으로 이동시킨다면 어떤 결과가 나올까?


11111111 11111111 11111111 11110000    // -16


이 결과는 사용하는 CPU에 따라서 다르다. 음의 값을 유지하기 위해 1을 채우는 CPU도 있고,


음의 값 유지와는 상관없이 0을 채우는 CPU도 있기 때문이다.



즉, 위의 비트 열을 오른쪽으로 2칸씩 이동시킬 경우 다음의 결과를 얻게 되거나,


00111111 11111111 11111111 11111100    // 0이 채워진 경우


다음의 결과를 얻게 된다.


11111111 11111111 11111111 11111100    // 1이 채워진 경우



예제를 살펴보자.


과연 내가 사용하는 CPU는 어떻게 처리할까? 궁금하다.





예제에 대한 결과는 이렇다.




내 CPU는 음수를 유지하기 위해 1을 채웠다.









참고서적 : 윤성우 저 열혈강의 C 프로그래밍 개정판 92p ~ 100p.












댓글