ビットが 0 かどうかを調べる | Programming Place Plus C言語編 逆引き

トップページC言語編逆引き

このページの概要 🔗

このページの解説は 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 かどうか
    printf("%d\n", (n1 & 0x80) == 0);
    printf("%d\n", (n2 & 0x80) == 0);
    printf("%d\n", (n3 & 0x80) == 0);
    puts("----");

    // 下位から数えて、3~7 ビット目の範囲がすべて 0 かどうか
    printf("%d\n", (n1 & 0x3c) == 0);
    printf("%d\n", (n2 & 0x3c) == 0);
    printf("%d\n", (n3 & 0x3c) == 0);
    puts("----");

    // 奇数ビットがすべて 0 かどうか
    printf("%d\n", (n1 & 0x55) == 0);
    printf("%d\n", (n2 & 0x55) == 0);
    printf("%d\n", (n3 & 0x55) == 0);
    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))。


参考リンク 🔗


更新履歴 🔗



逆引きのトップページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る