조금씩 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.
'기타 > 보관소' 카테고리의 다른 글
C언어 :: 자료형의 변환 (2) | 2015.11.23 |
---|---|
C언어 :: unsigned 선언 (0) | 2015.11.23 |
C언어 :: 아스키 코드표 (0) | 2015.11.22 |
C언어 :: scanf 함수 관련 C4996 에러 해결 방법 (1) | 2015.11.22 |
C언어 :: sizeof 연산자 (0) | 2015.11.22 |
언턴드(Unturned) 팁 - 캐릭터 주특기 설정 (0) | 2015.11.19 |
언턴드(Unturned)를 며칠간 플레이하고 나온 결론 (0) | 2015.11.17 |
언턴드(Unturned) 외국 서버 탐방기#1 (0) | 2015.11.16 |
언턴드(Unturned) 플레이일지#3 (0) | 2015.11.16 |
언턴드(Unturned) 플레이일지#2 (0) | 2015.11.15 |
댓글