본문 바로가기
Language/C언어

C018_비트 연산

by OdOp 관리자 2023. 9. 20.
SMALL

연산자

& : 비트 AND

| : 비트 OR

^ : 비트 XOR(Exclusive OR)

~ : 비트 NOT

<< : 비트를 왼쪽으로 시프트

>> : 비트를 오른쪽으로 시프트

&=: 비트 AND연산 후 할당

|= : 비트 OR연산 후 할당

^= : 비트 XOR연산 후 할당

<<= : 비트를 왼쪽으로 시프트 한 후 할당

>>= : 비트를 오른쪽으로 시프트 한 후 할당 

 

#include <stdio.h>

int main()
{
    unsigned char num1 = 1;
    unsigned char num2 = 3;
    unsigned char num3 = 162;  //162: 1010 0010
    unsigned char num4;
    unsigned char num5 = 24;
    unsigned char num6 = 4;
    unsigned char num7 = 4;
    unsigned char num8 = 4;
    unsigned char num9 = 4;
    unsigned char num10 = 4;

    printf("%d\n", num1 & num2);  //01과 03을 비트 AND하면 01이 됨
    printf("%d\n", num1 | num2);  //01과 03을 비트 OR하면 11이 됨
    printf("%d\n", num1 ^ num2);  //01과 03을 비트 XOR하면 10이 됨
    num4 = ~num3;
    printf("%u\n", num4);  //93: 0101 1101
    printf("%u\n", num2 << 3);  //24: 0001 1000: num1의 비트 값을 왼쪽으로 3번 이동
    printf("%u\n", num5 >> 2);  //6: 0000 0110: num2의 비트 값을 오른쪽으로 2번 이동 
    num6 &= 5;  //5(0000 0101) AND 연산 후 할당
    num7 |= 2;  //2(0000 0010) OR 연산 후 할당
    num8 ^= 3;  //3(0000 0011) XOR 연산 후 할당
    num9 <<= 2;  //비트를 왼쪽으로 2번 이동한 후 할당
    num10 <<= 2;  //비트를 오른쪽으로 2번 이동한 후 할당
    printf("%u\n", num6);  //1: 0000 0001
    printf("%u\n", num7);  //6: 0000 0110
    printf("%u\n", num8);  //248: 1111 1000
    printf("%u\n", num9);  //16: 0001 0000
    printf("%u\n", num10); //1: 0000 0001
    return 0;
}

 

비트 연산자 응용

부호 있는 자료형의 첫 번째 비트를 부호 비트라 하고 이 비트가 1이면 음수, 0이면 양수가 됩니다.

최상위 비트(Most Significant Bit, MSB) : 비트에서 첫 번째 비트를 뜻합니다. 

최하위 비트(Least Significant Bit, LSB) :  비트에서 마지막 비트를 뜻합니다. 

 

#include <stdio.h>

int main()
{
    unsigned char num1 = 240;  //240: 1111 0000
    unsigned char num2 = 15;  //15: 0000 1111
    unsigned char num3, num6;
    unsigned num4 = 131;  //131: 1000 0011
    char num5 = -125;  //-125: 1000 0011
    char num7, num8;
    char num9 = 67;  //67: 0100 0011
    char num10 = 113;  //113: 0111 0001
    char num11 = -15;  //-15: 1111 0001
    char num12, num13;
    unsigned char flag = 0;  //0: 0000 0000

    //비트에서 첫째 자리나 마지막 자리를 넘어서는 비트는 그대로 사라짐 
    num3 = num1 << 2;
    printf("%u\n", num3);  //192: 1100 0000
    printf("%u\n", num2 >> 2);  // 3: 0000 0011
    num6 = num4 >> 5;
    num7 = num5 >> 5;
    printf("%u\n", num6);  //4: 0000 0100
    printf("%d\n", num7);  //-4: 1111 1100: 모자라는 공간은 부호 비트의 값인 1로 채워지므로 111 1100이 됨
    num8 = num9 >> 5;
    printf("%d\n", num8);// 2: 0000 0010: 모자라는 공간은 부호 비트의 값인 0으로 채워짐 
    //부호 있는 자료형에 시프트 연산을 할 때는 의도치 않는 결과가 나올 수 있으므로 항상 부호 비트를 생각해야 함
    num12 = num10 << 2;
    num13 = num11 << 4;
    printf("%d\n", num12);  //-60: 1100 0100: 부호 비트를 덮어쓰게 되므로 양수에서 음수가 됨 
    printf("%d\n", num13);  //16: 0001 0000: 부호 비트를 덮어쓰게 되므로 음수에 양수가 됨
    // 사용할 변수 |= 마스크 값: 마스크 값을 비트로 바꾸어서 1로 만든다.
    flag |= 1;  // 0000 0001 마스그와 비트 OR로 여덟 번쨰 비트를 켬
    flag |= 2;  // 0000 0010 마스그와 비트 OR로 일곱 번쨰 비트를 켬
    flag |= 4;  // 0000 0100 마스그와 비트 OR로 여섯 번쨰 비트를 켬
    printf("%u\n", flag);  //7: 0000 0111
    if (flag & 1)  //& 연산자로 0000 0001비트가 켜져 있는지 확인
    {
        printf("0000 0001은 켜져 있음\n");
    }
    else
    {
        printf("0000 0001은 꺼져 있음\n");
    }

    flag &= ~2;  //1111 1101: 마스크 값2(0000 0010)의 비트를 뒤집은 뒤 비트 AND로 일곱 번째 비트를 끔
    if (flag & 2)
    {
        printf("0000 0010은 껴져 있음\n");
    }
    else
    {
        printf("0000 0010은 꺼져 있음\n");
    }

    //flag = 0000 0101
    flag ^= 8;  //0000 1000마스크와 비트 XOR로 다섯 번째 비트를 토글
    printf("%u\n", flag);
    //flag = 0000 1101
    //비트가 껴져 있다면 끄고, 꺼져있다면 켜는 방법입니다. 다른 말로는 토글(toggle)이라고도 합니다. 
    if (flag & 1)
    {
        printf("0000 0001은 껴져 있음\n");
    }
    else
    {
        printf("0000 0001은 꺼져 있음\n");
    }
    return 0;
}
LIST

'Language > C언어' 카테고리의 다른 글

C020_함수 포인터  (0) 2023.09.22
C019_재귀 함수 사용하기  (0) 2023.09.21
C017_함수, 가변인자 사용하기  (0) 2023.09.19
C016_함수, 매개변수 사용  (0) 2023.09.18
C015_함수에 대해  (3) 2023.09.17