전기전자공학/프로젝트

[Kernighan - C] #2-9 비트 연산자

LinZBe4hia 2017. 6. 25. 22:18

2-9 비트 연산자

The C Programming - Kernighan



[예제 2-6]

x의 우측 p번째 부터 n개의 비트를 y의 최우측 n개의 비트로 대체하고 다른 비트는 그대로 두고 리턴하는 함수 setbits(x,p,n,y)

를 작성하라 (단, 0을 우측 끝이라고 나타낸다.)


setbits.c

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
#include <stdio.h>
 
void displayBit(int);
 
int setbits(int x, int p, int n, int y) {
    int sum = 0;
    int x_mask = (~0 << p + 1| (~(~0 << p - n +1));     // ~0 << p + 1의 경우 예시:    1111110000
                                                        // ~(~0 << p -n + 1) 경우 예시: 0000000011 (n = 2인 경우)
    int y_mask = ~x_mask;
 
    x &= x_mask;
    y &= y_mask;
    // x와 y 시각적으로 계산 확인
    //printf("x: "); displayBit(x);
    //printf("y: "); displayBit(y);
    return x ^ y;
 
}
/* displayBit: 2진수로 표현하는 함수 */
void displayBit(int n) {
    int i = 9;
 
    for (i; i >= 0--i)
        printf("%d", (n >> i) & 1);
    printf("\n");
}
cs


 *** setbits 함수의 리턴형을 unsigned로 바꾸고, x의 자료형을 unsigned로 바꾸는 것이 더 안전한 것 같다 ...

정확한 이유는 아직 모름


main.c

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
main() {
    int a = 117, b = 31// a = 1010101, b = 0011111
    int p = 5, n = 4;
 
    printf("\n");
 
    // result = 0001011101 (자리수: 10개)
    displayBit(setbits(a, p, n, b));
}
cs


[예제 2-7] 

x의 p번째 비트부터 n개의 비트를 역전(즉, 0은 1로, 1은 0으로) 시키고나머지는 그대로 두는 함수invert(x,p,n)을 작성하라


invert.c

1
2
3
4
5
int invert(int x, int p, int n) {
    int x_mask = ~((~0 << p + 1| (~(~0 << p - n + 1)));
 
    return x ^ x_mask;
}
cs


main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
main() {
    int a = 117, b = 31// a = 1010101, b = 0011111
    int p = 5, n = 4;
    displayBit(a);
 
    printf("\n");
 
    // result = 0001011101 (자리수: 10개)
    displayBit(invert(a, p, n)); 
 
}
cs



[예제 2-8]

정수 x를 우측으로 n비트 만큼 이동한 값을 리턴하는 함수 rightrot(x, n)을 작성하라 (참고 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>
 
unsigned rightrot(unsigned x, unsigned n);
 
main(void)
{
    printf("%u\n", rightrot(31));
 
}
 
/* rightrot: rotates x to the right by n bit positions */
unsigned rightrot(unsigned x, unsigned n)
{
    while (n > 0) {
        if (x & 1/* rightmost bit of x is 1 */
            x = (x >> 1| (~0U >> 1); // 0U: unsigned int형 0이라는 의미
        else
            x = x >> 1;
        --n;
    }
    return x;
}
cs


Q. ~0U를 하는 이유는 x를 우측 n비트만큼 이동하는 동안 원래 존재하는 부호 비트 자리를 고려하지 않고

옮기기 위해서?