ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kernighan - C] #2-9 비트 연산자
    전기전자공학/프로젝트 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비트만큼 이동하는 동안 원래 존재하는 부호 비트 자리를 고려하지 않고

    옮기기 위해서?



    댓글

Designed by Tistory.