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

スポンサーリンク

鍛錬 309

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

x のビット位置 p から n ビットを反転 (1 を 0, 0 を 1 にする) し、他のビットはそのままにした x を返す関数 invert(x,p,n) を書け。

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

スポンサーリンク

プログラム

以下は、指定したビット位置から指定したビット数を反転し、他のビットはそのままで取得するプログラム、kr_2_7.c です。

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

// include
#include <stdio.h>

// prototype
unsigned int invert(unsigned int x, int p, int n);

// main
int main(void)
{
	unsigned int x;
	int p;
	int n;
	
	// 初期化
	x = 123;  // ビット列
	p = 6;    // 反転するビットの開始位置
	n = 3;    // 反転されるビット数
	
	x = invert(x, p, n);
	printf("%d\n", x);
	
	return 0;
}

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

実行結果の予測

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

int n;

// 初期化
x = 123;  // ビット列
p = 6;    // 反転するビットの開始位置
n = 3;    // 反転されるビット数

x = invert(x, p, n);
printf("%d\n", x);
項目 値 (10進数) 値 (2進数)
x:ビット列 123 0111 1011
p:反転開始ビット位置 6
n:反転ビット数 3

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

1. tmp = ~(~0

tmp = ~(~0 << n)
tmp = ~(1111 1111 << 3)
tmp = ~(1111 1000)
tmp = (0000 0111)

2. tmp = tmp

tmp = tmp << (p - (n - 1))
tmp = (0000 0111) << (6 - (3 - 1))
tmp = (0000 0111) << 4)
tmp = (0111 0000)

3. x = x ^ tmp

x = x ^ tmp
x = (0111 1011) ^ (0111 0000)
x = (0000 1011)

4. 結果予測

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

n進数
2進数 0000 1011
10進数 11

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

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

実行結果

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

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall kr_2_7.c -o kr_2_7
***@ubuntu:~/***/test/c$ ./kr_2_7
11

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

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