演習 2-6
無職の間にK&Rを再読。演習問題の解答をさらす。解く順番は適当。
演習 2-6
位置 p から始まる n ビットを y の右端の n ビットにセットし、他のビットはそのままにした x を返す関数 setbits(x, p, n, y) を書け
Exercise 2-6
Write a function setbits(x, p, n, y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged.
位置 p から始まる n ビットのビットマスクを作るのに全部 1 のビットパターン (&HFFFFFFFF) を左右からビットシフトすればいい(左右から 0 を挿入)と思ったけど、ビット長は決め打ちできないので、左シフトだけでビットマスクを作る。
#include <stdio.h> /* Answer */ unsigned setbits(unsigned x, int p, int n, unsigned y) { n = (n > p + 1) ? p + 1 : n; unsigned mask = ~(~0 << n) << (p - n + 1); return (x & ~mask) | (y & mask); } void showbits(long num, int size); void _showbits(long num, int remain); int main(void) { unsigned short a = 0x5678; unsigned short b = 0xABCD; unsigned short c; showbits(a, sizeof(a)); showbits(b, sizeof(b)); c = setbits(a, 11, 8, b); showbits(c, sizeof(c)); 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 ]); }