Coding & Programming/C, C++

[C언어/C++]32bit 정수(integer)에서 특정 비트(bit)값 추출(get), 설정(set), 반전(invert), 비트열(bit string) 출력하기

mainCodes 2022. 12. 30. 16:35

[C언어/C++]32bit 정수(integer)에서 특정 비트(bit)값 추출(get), 설정(set), 반전(invert), 비트열(bit string) 출력하기

 

안녕하세요 JollyTree입니다 (•̀ᴗ•́)و

일반적으로 32bit 컴퓨터 프로그램에서 int/unsigned int는 32bit(4바이트) 크기를 가집니다.

int a = 10; 일때

a의 값 10은 10진수이며 16진수로 0xA, 그리고 이진 수로 00001010 라는 비트열의 이진수로 표현할 수 있습니다. 32bit 시스템이기 때문에 모든 비트열을 표현하면, 0000000 00000000 00000000 00001010 가 됩니다. 64bit의 경우 2배의 길이를 가지게 됩니다.

다음은 아래 예제에 포함된 4개의 정수형 변수입니다.

unsigned int a = 0x0F;   //15
unsigned int b = 0xFF;   //255
unsigned int c = 0xFFFF;  //65535
unsigned int d = 0x00FFFFFF; //16777215

위 int 형 변수 a, b, c, d 각 값을 2진수와 10진수로 나타내면 아래와 같습니다.

0000000 00000000 00000000 00001111 (15), 0x0F
0000000 00000000 00000000 11111111 (255), 0xFF
0000000 00000000 11111111 11111111 (65535), 0xFFFF
0000000 11111111 11111111 11111111 (16777215), 0x00FFFFFF

이를 토대로 아래 예제는 int 형 변수 즉, 32bit 비트열에서 특정 n 번째 비트를 추출, 설정, 초기화하고 int 형 변수의 값을 2진수 문자열로 변환하는 기능을 포함합니다.

🔗 32bit 정수에서 특정 비트(bit)값 추출(get), 설정(set), 반전(invert), 비트열(bit string) 출력하기(Example):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
 
#define INT_SIZE 32 
 
void set_bit(unsigned int *value, int bit_pos, int flag)
{
    if(flag) //set to 1
        *value |= (0x1 << bit_pos);
    else     //set to 0
        *value &= ~(0x1 << bit_pos);
}
 
int get_bit(unsigned int value, int bit_pos)
{
    return value & (0x1 << bit_pos);
}
 
void print_bits(unsigned int value)
{
    for (int i = INT_SIZE-1; i >= 0; i--){
        if((i != (INT_SIZE-1)) && ((i + 1) % 4 == 0)) printf(" ");
 
        printf("%d", get_bit(value, i) ? 1 : 0);
    }
    puts("");
}
 
void invert_bit(unsigned int *value, int bit_pos)
{
    *value ^= (0x1 << bit_pos);   
}
 
void clear_bit(unsigned int *value, int bit_pos)
{
    *value &= ~(0x1 << bit_pos);   
}
 
void clear_bits(unsigned int *value, int bits, int skip_bit_pos)
{
    *value &= ~(bits << skip_bit_pos);
}
 
char* int2bin(unsigned int value, int flag)
{
    static char buf[INT_SIZE + 1];
    int j = 0;
 
    if (flag) { //in reverse, 31 ~ 0 
        for (int i = INT_SIZE - 1, j = 0; i >= 0; i--, j++)
            buf[j] = get_bit(value, i) ? '1' : '0';
    }
    else {
        for (int i = 0, j = 0; i < INT_SIZE; i++, j++)
            buf[j] = get_bit(value, i) ? '1' : '0';
    }
    buf[INT_SIZE] = 0x00;
    return buf;
}
 
int main(void)
{
    unsigned int a = 0x0F;
    unsigned int b = 0xFF;
    unsigned int c = 0xFFFF;
    unsigned int d = 0x00FFFFFF;
 
    printf("2진수 비트열로 출력(31~0비트 순):\n"); 
    printf("a = 0x%08X:", a); print_bits(a);
    printf("b = 0x%08X:", b); print_bits(b);
    printf("c = 0x%08X:", c); print_bits(c);
    printf("d = 0x%08X:", d); print_bits(d);
    puts("");
 
    printf("특정 비트 출력(31~0비트 순): \n");
    for (int i = INT_SIZE - 1; i >= 0; i--)
        printf("%d", get_bit(a, i) ? 1 : 0);
    puts("");
 
    printf("특정 비트를 반대(invert)로 출력(31~0비트 순): \n");
    for (int i = INT_SIZE - 1; i >= 0; i--) {
        invert_bit(&a, i);
        printf("%d", get_bit(a, i) ? 1 : 0);
    }
    puts("\n");
 
    printf("특정 비트를 모두 0과 1로 설정: \n");
    printf("   1개 비트씩  32개 비트 모두 0으로 설정\n");
    for (int i = INT_SIZE - 1; i >= 0; i--)  
        set_bit(&a, i, 0);                    //set to 0, all bits
    print_bits(a);
 
    printf("   1개 비트씩  32개 비트 모두 1으로 설정\n");
    for (int i = INT_SIZE - 1; i >= 0; i--)  
        set_bit(&a, i, 1);                    //set to 1, all bits
    print_bits(a);
    puts("");
 
    printf("일부 비트들을 clear: \n");
    clear_bits(&a, 158);                    //set to 0, from the 8th bit, 15(0b0000)
    print_bits(a);
 
    clear_bits(&a, 516);                    //set to 0, from 16th bit, 5(0b010)
    print_bits(a);
    puts(""); 
 
    printf("특정 1비트만 clear: \n");          //clear bit from 0 ~ 31 bit, in reverse
    for (int i = INT_SIZE - 1; i >= 0; i--){
        if( (i+1) % 2)
            clear_bit(&d, i);
    }
    print_bits(d);
    puts("");
 
    printf("32비트 -> 문자열로 변환: \n");
    printf("%s\n", int2bin(c, 1));           //31 ~ 0
    printf("%s\n", int2bin(c, 0));           //0 ~ 31
 
    d = 0x00FFFFFF;  
    printf("%s\n", int2bin(d, 1));           //31 ~ 0
    puts("");
 
    return 0;
}
cs

🔗 실행결과(Output):

이상 JollyTree였습니다. (•̀ᴗ•́)و