[C 기초 - 비트 이동 연산자]
비트 이동 연산자
<< 연산자 (왼쪽 Shift)
<<
연산자는 지정한 획수대로 비트의 자리를 왼쪽으로 이동시키는 연산자 입니다.
#include <stdio.h>
int main(void)
{
unsigned char a = 4 << 1; // 0000 0100
unsigned char b = 8 << 2; // 0000 1000
printf("4 << 1 : %d\n", a);
printf("8 << 2 : %d\n", b);
a = 6 << 3; // 0000 0110
b = 10 << 4; // 0000 1010
printf("6 << 3 : %d\n", a);
printf("10 << 4 : %d\n", b);
return 0;
}
출력
4 << 1 : 8
8 << 2 : 32
6 << 3 : 48
10 << 4 : 160
4를 8비트 2진수로 나타낸 0000 0100을 왼쪽으로 한 자리 이동
4는 8비트 2진수로 0000 0100 입니다.
첫번째 연산에서 4가 1자리, 8이 2자리 만큼 왼쪽으로 이동한다. 왼쪽으로 이동해서 생기는 오른쪽 빈 비트들은 0으로 채워지며, 제일 왼쪽에서 밀려나는 비트들은 버려진다. 따라서 0000 0100 (4) => 0000 1000 (8)이 되고, 0000 1000 (8) => 0010 0000 (32)가 됩니다.
두번째 연산에서는 6이 3자리, 10이 4자리 만큼 왼쪽으로 이동합니다. 따라서 0000 0110 (6) => 0011 0000 (48)이 되고, 0000 1010 (10) => 1010 0000 (160)이 됩니다.
비트가 한 자리씩 왼쪽으로 이동할 때마다 정수의 값은 2배가 된다.
2진수이기 때문에 2칸을 이동하면 4배, 3칸 이동시 8배 즉, 2의 n승 만큼 곱하면 된다.
주의할 사항
- char형의 겨우 8비트지만, int형의 경우 32비트이기 때문에 왼쪽으로 비트 이동을 할 때 잘리는 크기가 다르다.
- 또한, unsigned 형의 경우 끝자리까지 정상적으로 이동하지만, 부호비트가 있는 자료형의 경우 MSB의 자리로 비트가 이동했을 떄에 보수연산을 하게된다.
코드
코드로 확인하기
#include <stdio.h>
int main(void)
{
char a = 1 << 8; // 0000 0001
int b = 1 << 8; // 0000 0000 0000 0000 0000 0000 0000 0001
printf("(char) 1 << 8 : %d\n", a);
printf("(int) 1 << 8 : %d\n", b);
unsigned char c = 1 << 7;
char d = 1 << 7;
printf("(unsigned) 1 << 7 : %d\n", c);
printf("(signed) 1 << 7 : %d\n", d);
}
출력
(char) 1 << 8 : 0
(int) 1 << 8 : 256
(unsigned) 1 << 7 : 128
(signed) 1 << 7 : -128
예제코드 확인
char형은 8비트기 때문에 8자리를 이동하게 되면 1이 잘려서 사라져서 0이된다.
하지만, int형은 32비트기 때문에 8자리를 이동할 수 있고, 정상적으로 256이 된다.
또한, unsigned char인 c의 경우 정상적으로 128이 되지만, 일반 char의 경우 마지막 비트가 MSB이기 때문에 음수처리되어 보수연산을 하고 그 값은 -128이 된다.
비트 이동을 할 때는 자료형을 꼭 고려할 것.
>> 연산자 (오른쪽 Shift)
>>
연산자는 지정한 획수대로 비트의 자리를 오른쪽으로 이동시키는 연산자 입니다.<<
연산자와 정확히 반대이다.
#include <stdio.h>
int main(void){
unsigned char a = 4 >> 1; // 0000 0100
unsigned char b = 8 >> 2; // 0000 1000
printf("4 >> 1 : %d\n", a);
printf("8 >> 2 : %d\n", b);
a = 14 >> 3; // 0000 1110
b = 16 >> 4; // 0001 0000
printf("14 >> 3 : %d\n", a);
printf("16 >> 4 : %d\n", b);
char c = -16 >> 2; // 1111 0000
printf("-16 >> 2 : %d\n", c);
}
출력
4 >> 1 : 2
8 >> 2 : 2
14 >> 3 : 1
16 >> 4 : 1
4를 8비트 2진수로 나타낸 0000 0100을 오른쪽으로 한 자리 이동
천번째 연산에서는 4가 1자리, 8이 2자리 만큼 오른쪽으로 이동하며, 제일 오른쪽으로 밀려나는 비트들은 버려진다. 따라서 0000 0100 => 0000 0010 (2)가 되고, 0000 1000 => 0000 0010 (2)가 된다.
두번째 연산에서는 14가 3자리, 16이 4자리 만큼 오른쪽으로 이동한다. 따라서 0000 1110 => 0000 0001 (1)이 되고, 0001 0000 => 0000 0001 (1)이 된다.
여기서 알 수 있는 것은 왼쪽으로 이동할 때에는 2의 n승 만큼 곱해지지만, 오른쪽으로 이동할 떄에는 2의 n승 만큼 나누어 진다.
주의할 사항
-
오른쪽으로 이동하면서 생기는 빈 비트들을 채워야 하는데, 양수일 때는 unsigned이든 signed이든 0이 채워져도 상관이 없다. 그러나, signed 자료형이고 음수일 때에는 맨 왼쪽값이 1이어야 하는데, 이 연산은 CPU마다 다르다. 어떤 CPU는 음수를 유지하기 위해 빈 비트들을 1로 채우고, 음수와는 상관없이 무조건 0을 채우는 CPU도 있다.
-
일반적으로 MSB와 같은 숫자를 채우는 쪽이 많음.
-
위 예제에서 c의 경우, 16 (1111 0000)을 2칸 오른쪽으로 이동했을 때, -4 (1111 1100)가 나오므로, MSB와 같은 1로 채워주는 것을 확인할 수 있다.
Author And Source
이 문제에 관하여([C 기초 - 비트 이동 연산자]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@fredkeemhaus/C-기초-비트-이동-연산자저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)