演習 2-8
無職の間にK&Rを再読。演習問題の解答をさらす。解く順番は適当。
演習 2-8
整数 x の値を右に n ビット回転する関数 rightrot(x, n)を書け
Exercise 2-8
Write a function rightrot(x, n) that returns the value of the integer x rotated to the right by n bit positions.
最下位ビットを1ビットずつ最上位ビットに持っていく。
最下位ビット (LSB: Least Significant Bit) は 0x01 なんで簡単、
最上位ビット (MSB: Most Significant Bit) は ~(~(unsigned)0 >> 1) でとった。
2ビットの場合 0x7FFF という形を作るために 0xFFFF (~0) を 1ビット右シフトするが、
~0 >> 1 だと符号拡張されるので、 ~(unsigned)0 >> 1 としている。
ループを使わずにはできんのかなぁ。
#include <stdio.h> /* Answer */ unsigned rightrot(unsigned x, int n) { while (n-- > 0) { int lsb = x & 0x01; x = x >> 1 | ~(~(unsigned)0 >> lsb); } return x; } void showbits(long num, int size); void _showbits(long num, int remain); int main(void) { unsigned a = 0x0ACDC987; unsigned b; showbits(a, sizeof(a)); b = rightrot(a, 8); showbits(b, sizeof(b)); return 0; } void showbits(long num, int size) { _showbits(num, size * 2 - 1); putchar('\n'); } void _showbits(long num, int remain) { static const char bitpattern[16][5] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111", }; if (remain > 0) { _showbits(num >> 4, remain - 1); putchar(','); } printf("%s", bitpattern[ num & 0x0F ]); }