K&R 演習2-6 解答 (プログラミング言語C 第2版)

スポンサーリンク

鍛錬 308

K&R 演習2-6 解答 (プログラミング言語C 第2版)

位置 p から始まる n ビットを y の右端の n ビットにセットし,他のビットはそのままにした x を返す関数 setbits(x,p,n,y) を書け。

B.W.カーニハン D.M.リッチー 石田晴久 訳 『プログラミング言語C 第2版 ANSI 規格準拠』, (共立出版, 2017), pp.61.

スポンサーリンク

プログラム

以下は、指定したビット位置から指定したビット数を右詰めにセットし、他のビットはそのままにしたビット列を取得するプログラム kr_2_6.c です。

(※ 右端をビット位置 0 とします。)

// include
#include <stdio.h>

// prototype
unsigned int setbits(unsigned int x, int p, int n, unsigned int y);

// main
int main(void)
{
	unsigned int x;
	unsigned int y;
	int p;
	int n;
	
	// 初期化
	x = 0;    // セット後のビット列
	y = 123;  // セット前のビット列
	p = 6;    // セットするビットの開始位置
	n = 3;    // 右端にセットされるビット数
	
	x = setbits(x, p, n, y);
	printf("%d\n", x);
	
	return 0;
}

// =====================================================================
// @brief     指定したビット位置から指定したビット数を右詰めにセットし,
// @brief     他のビットはそのままにした x を返す
// @param[in] x  セット後のビット列
// @param[in] p  セットするビットの開始位置
// @param[in] n  右端にセットされるビット数
// @param[in] y  セット前のビット列
// @return    x -> セット後のビット列
// @note      無し
// =====================================================================
unsigned int setbits(unsigned int x, int p, int n, unsigned int y)
{
	unsigned int tmp;
	
	tmp = y;
	y = (y >> (p + 1 - n)) & ~(~0 << n);
	tmp = tmp >> n;
	tmp = tmp << n;
	x = y | tmp;
	
	return x;
}
スポンサーリンク

実行結果の予測

上記に示した kr_2_6.c は、各パラメータを以下の通りに設定しています。

int n;

// 初期化
x = 0;    // セット後のビット列
y = 123;  // セット前のビット列
p = 6;    // セットするビットの開始位置
n = 3;    // 右端にセットされるビット数

x = setbits(x, p, n, y);
printf("%d\n", x);
項目 値 (10進数) 値 (2進数)
x:セット後のビット列 0 0000 0000
y:セット前のビット列 123 ‭0111 1011‬
p:取得開始ビット位置 6
n:取得ビット数 3

(※ 右端をビット位置 0 とします。)
 
よって、関数 setbits(x,p,n,y) のビット演算を行うと、以下に示す結果となるはずです。

1. tmp = y

tmp = y
tmp = (‭0111 1011)

2. y = (y >> (p + 1 – n)) & ~(~0

y = ((‭0111 1011) >> (6 + 1 - 3)) & ~(~0 << 3)
y = ((‭0111 1011) >> 4) & ~(~0 << 3)
y = (0000 0111) & ~(1111 1111 << 3)
y = (0000 0111) & ~(1111 1000)
y = (0000 0111) & (0000 0111)
y = (0000 0111)

3. tmp = tmp >> n

tmp = tmp >> n
tmp = (‭0111 1011) >> 3
tmp = (‭0000 1111)

4. tmp = tmp

tmp = tmp << n
tmp = (‭0000 1111) << 3
tmp = (0111 1000)

5. x = y | tmp

x = (0000 0111) | (0111 1000)
x = (0111 1111)

6. 結果予測

以上の結果より、プログラムを実行すると以下の値を取得できるはずです。

n進数
2進数 0111 1111
10進数 127

 
上記の予測される結果は、以下に示す通り、「指定したビット位置から指定したビット数を右詰めにセットし、他のビットはそのままにしたビット列を取得する」ことができています。

入出力
入力 ‭0111 1011
出力 0111 1111
スポンサーリンク

実行結果

以下は、プログラム kr_2_6.c を実行しています。

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall kr_2_6.c -o kr_2_6
***@ubuntu:~/***/test/c$ ./kr_2_6
127

 
上記に示した通り、予測通り10進数の 127 (2進数の場合は 0111 1111) を取得することができました。

タイトルとURLをコピーしました