전기전자공학/프로젝트
[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(3, 1)); } /* 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비트만큼 이동하는 동안 원래 존재하는 부호 비트 자리를 고려하지 않고
옮기기 위해서?