풀스택개발자될거임

[Do it C언어 입문 정리] 10.시프트 연산자와 비트 연산자 본문

C/do it C언어 입문

[Do it C언어 입문 정리] 10.시프트 연산자와 비트 연산자

FullStack_dev178 2022. 12. 25. 08:59

비트 단위 연산자가 필요한 이유

//전등상태표현
unsigned char lamp_state = 0;
lamp_state = 1;

만약 80개의 전등을 위 방법대로 관리한다고 하면 변수 80개가 필요함. 즉 80바이트가 필요

그런데 비트단위 연산자를 이용하면 10바이트만 있으면됨. -> 메모리절약

※일단 기본적으로 진수변환 방법을 알아야함

시프트 연산자

기능

"<<" 또는 ">>"으로 비트를 옮김

unsigned char data = 0x1A;
//이동전 : 0001 1010
data = data << 2;
//이동후 : 0110 1000

특성

<< : 2^이동한비트수 만큼 곱함

>> : 2^이동한비트수 만큼 나눔

주의할점

1. 연산자 우선순위가 낮음

2. 변수에 부호가 있으면 빈자리를 부호비트랑 동일한 상수로 채워짐

비트 연산자

AND(&) , OR(|), NOT(~), XOR(^) 연산을 수행

지정한 비트를 0으로 설정하기

1단계

unsigned char lamp_state; //값 모름
lamp_state = lamp_state & 0xFB // 0xFB = 1111 1011

2번비트만 0으로 만듦

2단계

unsigned char lamp_state;
unsigned char bit_num = 2;
unsigned char mask = ~(0x01 << bit_num); //0000 0001 -> 0000 0100 -> 1111 1011
lamp_state = lamp_state & mask;

3단계

#include <stdio.h>

int ResetBit(unsigned char lamp_state, unsigned char bit_num)
{
    if (bit_num < 8)
        lamp_state = lamp_state & ~(0x01 << bit_num);
    
    return lamp_state;
}

int main()
{
    unsigned char lamp_state = 0x7F; //0111 1111
    printf("%d -> ",lamp_state);

    lamp_state = ResetBit(lamp_state,3);
    printf("%X\n",lamp_state);

}

지정한 비트를 1로 설정하기

1단계

unsigned char lamp_state;
lamp_state = lamp_state | 0x04; //0000 0100

2단계

unsigned char lamp_state;
unsigned char bit_num = 2;
lamp_state = lamp_state | (0x01 << bit_num); //0000 0100

3단계

#include <stdio.h>

int a(unsigned char desk, unsigned char bitnum)
{
    if(bitnum < 8) desk = desk | (0x01 << bitnum);

    return desk;
}
int main()
{
    unsigned char lamp_state = 0x77;
    
    printf("%x -> ",lamp_state);
    lamp_state = a(lamp_state,3);
    printf("%x\n",lamp_state);

}

특정 비트의 값 얻기

AND연산자 이용

1단계

unsigned char lamp_state;
unsigned char bit_state;
bit_state = lamp_state & 0x04;

bit_state = bit_state >> 2;

2단계

unsigned char lamp_state;
unsigned char bit_num = 2;
unsigned char bit_state;
unsigned char mask = 0x01 << bit_num;
bit_state = lamp_state & mask;

bit_state = bit_state >> bit_num;

3단계

#include <stdio.h>

unsigned char GetBit(unsigned char desk_data,unsigned char bit_num)
{
    unsigned char bit_state = 0;
    /*1바이트 변수라서 비트 이동은 0~7까지만 가능함*/
    if(bit_num < 8)
    {
        bit_state = desk_data & (0x01 << bit_num);
        bit_state = bit_state >> bit_num;
    }

    return bit_state;
}

int main()
{
    unsigned char lamp_state = 0x75;
    unsigned char bit_state;
    int i;

    printf("%X -> ",lamp_state);

    for(i = 0; i < 8; i++)
    {
        bit_state = GetBit(lamp_state,7 - i);
        printf("%d",bit_state);

        if(i == 3) printf(" ");
    }

    printf("\n");
    
    return 0;
}

'-' 안쓰고 뺄셈하기

A - B = A + ~(B) + 1

1의 보수 = ~(B)

2의 보수 = ~(B) + 1

#include <stdio.h>

int main()
{
    unsigned char data1 = 5;
    unsigned char data2 = 3;
    
    data1 = data1 + ~(data2)+1;

    printf("%d\n",data1);

    return 0;
}