34. 쉬프트 연산자

C언어 – 비트, 쉬프트 연산자
00:19 비트 연산자
01:22 [실습] 비트 연산자
02:44 xor 연산을 이용한 대칭형 암호화
03:28 [실습] xor 연산을 이용한 대칭형 암호화
05:46 쉬프트 연산자
07:00 [실습] 쉬프트 연산

<<,>>

쉬프트 연산은 좌항에 있는 피연산자를 우항에 있는 수만큼 비트 자리 이동하는 연산을 수행해요.
<< 는 왼쪽 쉬프트 연산자이고 >> 는 오른쪽 쉬프트 연산자죠.

왼쪽 쉬프트 연산을 하면 좌항에 있는 피연산자의 값이 우항에 있는 수만큼 왼쪽으로 자리 이동하고 빈 자리는 0으로 채우죠.

만약 부호없는 수 3을 왼쪽으로 4자리 이동시키면 48이예요.
이진수로 생각해 보세요.
이진수 011(10진수 3)을 왼쪽으로 4자리 이동하면 이진수 0110000(10진수 48)이 되죠.
이것을 다시 16진수로 얘기하면 16진수 3(10진수 3)을 왼쪽으로 4자리 이동하면 16진수 30(10진수 48)이예요.
참고로 16진수의 한자리는 2진수 4자리를 차지하죠.

그리고 부호있는 수 -3을 왼쪽으로 4자리 이동시키면 -48이예요.

왼쪽 쉬프트 연산 수행 결과를 보면 왼쪽으로 한 자리 이동할 때마다 곱하기 2한 결과와 같아요.
3을 왼쪽으로 4자리를 이동하면 3에 2를 4번 곱한 결과인 48이예요.

◈ 왼쪽 쉬프트 연산 예

#include <stdio.h>
int main()
{
    unsigned u1 = 3, u2 = 0;
    int i1 = -3, i2 = 0;
    u2 = u1 << 4;
    printf("16진수 %X %X \n",u1, u2); //확인하기 쉽게 16진수로 출력
    printf("10진수 %u %u \n",u1, u2); //부호없는 10진수로 출력
    i2 = i1 << 4;
    printf("16진수 %X %X \n",i1, i2); //확인하기 쉽게 16진수로 출력
    printf("10진수 %d %d \n",i1, i2); //10진수로 출력
    return 0;
}

◈ 실행 결과

16진수 3 30
10진수 3 48
16진수 FFFFFFFD  FFFFFFD0
10진수 -3 -48

오른쪽 쉬프트 연산은 좌항에 오는 피연산자가 부호 없는 수와 부호 있는 수일 때 차이가 있어요.
부호 없는 수가 피 연산자로 오면 빈 자리에 0이 채워져요.
하지만 부호 있는 수가 피 연산자로 오면 부호 비트는 자리 이동하지 않고 빈 자리에 부호 비트가 채워지죠.
그렇지만 두 가지 모두 오른쪽 쉬프트 연산은 자리 이동하는 만큼 2로 나눈 결과와 같아요.

◈ 오른쪽 쉬프트 연산 예

#include <stdio.h>
int main()
{
    unsigned u1 = 48, u2 = 0;
    int i1 = -48, i2 = 0;
    u2 = u1 >> 4;
    printf("16진수 %X %X 10진수: %u %u \n",u1, u2, u1, u2); 
    i2 = i1>>4;
    printf("16진수 %X %X 10진수: %d %d\n",i1, i2, i1, i2);
    return 0;
}

◈ 실행 결과

16진수 30 30 10진수 48 3
16진수 FFFFFFD0  FFFFFFFD 10진수 -48 -3 

◈ 기본 연습 (정답 바로가기)
1. 다음 프로그램의 출력 결과를 예측하시오.

#include <stdio.h>
int main()
{
    unsigned u = 5;
    int i = -5;
    printf("%d \n",u<<3);
    printf("%d \n",i<<3); 
    return 0;
}

2. 다음 프로그램의 출력 결과를 예측하고 이유를 설명하시오.
참고:
unsigned int 형식의 0x80000000은 2147483648
int 형식의 0x80000000은 -2147483648

#include <stdio.h>
int main()
{
    unsigned u1 = 100;
    unsigned u2 = 0x80000000;
    int i1 = 100;
    int i2 = 0x80000000;
 
    printf("%d \n",u1>>3);
    printf("%d \n",i1>>3);
 
    printf("%d %#X\n",u2>>3, u2>>3);
    printf("%d %#X\n",i2>>3, i2>>3 ); 
 
    return 0;
}