今回のテーマは、「ビット単位の論理演算」である。
プログラムの条件は、unsigned型の整数値を読み込んで、その内部のビット構成を表示することである。
なお、本プログラムは、Windows 11 Home(23H2)上で、Visual Studio Code(1.87.2)を使用して作成し、gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 でコンパイルしている。
C言語のインストールについてはこちらをご参照ください↓
unsigned型の構成ビットを表示するプログラム
//unsigned型の構成ビットを表示するプログラム
#include <stdio.h>
//整数x中にセットされたビット数を返す
int count_bits(unsigned x)
{
int bits = 0;
while(x) {
if (x & 1U) bits++;
x >>= 1;
}
return bits;
}
//unsigned型のビット数を返す
int int_bits(void)
{
return count_bits(~0U);
}
//unsigned型のビット内容を表示
void print_bits(unsigned x)
{
for (int i = int_bits() - 1; i >= 0; i--)
putchar(((x >> i) & 1U) ? '1' : '0');
}
int main(void)
{
unsigned x;
printf("非負の整数:"); scanf("%u",&x);
printf("その整数の中身は"); print_bits(x); printf("です\n");
return 0;
}
実行結果
非負の整数:10
その整数の中身は00000000000000000000000000001010です
ビット単位の論理演算
整数型の内部を構成する個々のビットに対しては、4種類の論理演算が行える。
論理積
x | y | x & y |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
論理和
x | y | x | y |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
排他的論理和
x | y | x ^ y |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
1の補数
x | ~x |
0 | 1 |
1 | 0 |
ビット単位のAND演算子
a & b・・・ aとbのビット単位の論理積を求める。
ビット単位のOR演算子
a | b・・・aとbのビット単位の論理和を求める。
ビット単位の排他OR演算子
a ^ b・・・aとbのビット単位の排他的論理和を求める
~演算子
~a・・・aの1の補数(すべてのビットを反転した値)を求める。
整数型の内部とビット数
int count_bits(unsigned x);
整数x中のセットされたビット数を求める。
if (x & 1U) bits++;
xと1U(最下位ビットのみが1の符号なし整数)との論理積を求める。xの最下位ビットが1であればbitsをインクリメントする。
x >>= 1;
調べ終わった最下位ビットを弾き出すために、全ビットを1ビット右にシフトする。
以上の作業をxの値が0になる(xの全ビットが0になる)まで繰り返すと、セットされたビットの個数が変数bitsに入る。
int int_bits(void)
int型/unsigned型のビット数を調べる
~0Uは全ビットが1であるunsigned型整数なので、それを関数count_bitsに渡すことで、unsigned型のビット数を求めている。
void print_bits(unsigned x);
整数xの全ビット構成を表示する。(1と0の並びとして表示する)
(参考)新・解きながら学ぶC言語 第2版 柴田望洋 (監修・著)、 由梨かおる(著)SBクリエイティブ
コメント