このページの解説は C99 をベースとしています。
以下は目次です。
ある符号無し整数型の値を構成する複数のビットの中の、任意の位置のビットが 0 かどうかを判定したいとします。
ビット演算は原則的に、符号無し整数型に対して使用します(第49章)
ここでいう「任意のビット」は、特定の1つのビットでもいいですし、2ビット以上連続したり、飛び飛びであったりしてもいいものとします。たとえば、
といった具合です。
あるビットが 0 かどうか判定するには、ビット積(ビットAND)(第49章)を使います。
調べたいビットにだけ “1” が立っている整数を用意し(これを BITS とします)、ターゲットの整数とのあいだでビット積を取ります。その結果が(ビットでなく整数全体として)0 になれば、指定のビットのすべてが 0 になっています。
if ((ターゲットの整数 & BITS) == 0) {
// 調べたいビットのすべてが 0 になっている
}
else {
// 調べたいビットのいくつかは 0 になっていない
}
実際に試してみます。結果をみたいので、if文はなくなり、printf関数の実引数の中で判定しています。
#include <stdio.h>
int main(void)
{
unsigned char n1 = 0xf0;
unsigned char n2 = 0x80;
unsigned char n3 = 0x7f;
// 一番上位のビットが 0 かどうか
("%d\n", (n1 & 0x80) == 0);
printf("%d\n", (n2 & 0x80) == 0);
printf("%d\n", (n3 & 0x80) == 0);
printf("----");
puts
// 下位から数えて、3~7 ビット目の範囲がすべて 0 かどうか
("%d\n", (n1 & 0x3c) == 0);
printf("%d\n", (n2 & 0x3c) == 0);
printf("%d\n", (n3 & 0x3c) == 0);
printf("----");
puts
// 奇数ビットがすべて 0 かどうか
("%d\n", (n1 & 0x55) == 0);
printf("%d\n", (n2 & 0x55) == 0);
printf("%d\n", (n3 & 0x55) == 0);
printf("----");
puts}
実行結果:
0
0
1
----
0
1
0
----
0
1
0
----
桁が多いと分かりづらいので、ここでは unsigned char型を使って、8bit の符号無し整数型で試しています。もっと大きい型を使っても、ビットの数が増えるだけで、やり方はなんら変わりません。
指定したビット “だけ” が 0
であるという判定ではないことに注意してください。指定しなかったビットも
0 になっている可能性はあります。たとえば、最後から2つ目のところ
(n2 & 0x55) == 0
という判定結果が真になっています。n2
は 0x80 で2進法では 10000000、0x55 は2進法 01010101 ですから、
10000000
& 01010101
----------
00000000
という演算になります。余計なところにも 0 がありますが、結果としては 0
になりますから、(0x80 & 0x55) == 0
は真です。
指定したビット “だけ” が 0
であるという判定が必要な場合は、「指定したビット以外はすべて 1
である」と考えればいいです。つまり、BITS
を反転させたもの(~BITS
)との一致を調べます((target == ~BITS)
)。
return 0;
を削除(C言語編全体でのコードの統一)
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |