【第1部】C言語(K&R検証)編
0015.ビット演算
K&Rでは
第2章:データ型・演算子・式に記述されています。
ビットごとの論理演算子のところで、
getbits()関数という、変数の各ビットの状態を調べる関数が紹介されていますが、ちょっとここでは省略します。
代わりとして、よく使用される
ビット演算を紹介します。
ソース紹介
CPPファイルに記述
#include <iostream>
#include <cstdio>
using namespace std;
#define FLG_A 0x0001
#define FLG_B 0x0002
#define FLG_C 0x0004
#define FLG_D 0x0008
#define FLG_E 0x0010
#define FLG_F 0x0020
#define FLG_G 0x0040
#define FLG_H 0x0080
int main()
{
unsigned int a = FLG_B | FLG_F;
if (a & FLG_B) {
cout << "FLG_Bが有効です" << endl;
}
else {
cout << "FLG_Bが無効です" << endl;
}
a ^= FLG_B;
if (a & FLG_B) {
cout << "FLG_Bが有効です" << endl;
}
else {
cout << "FLG_Bが無効です" << endl;
}
return 0;
}
出力
サンプル説明
ここでは、
ビット演算が
フラグとして使用される例を紹介します。
#define FLG_A 0x0001
#define FLG_B 0x0002
#define FLG_C 0x0004
#define FLG_D 0x0008
#define FLG_E 0x0010
#define FLG_F 0x0020
#define FLG_G 0x0040
#define FLG_H 0x0080
は、各ビットごとのフラグです。
main()関数では
unsigned int a = FLG_B | FLG_F;
と
FLG_B と FLG_Fを
立てて(有効にして)います。これを検証するには
のように
& 演算子で行います。
そのフラグをクリアするには
のようにします。
続いて、
ビットシフトのサンプルを紹介します。
ソース紹介
CPPファイルに記述
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
unsigned int n = 567;
n <<= 3; //この結果、n == 4536 になる。(567 * 8)
cout << n << endl;
n = 56;
n >>= 1; //この結果、n == 28 になる。(56 / 2)
cout << n << endl;
n = 2587;
n >>= 3; //この結果、n == 323 になる。(2587 / 8)
cout << n << endl;
return 0;
}
出力
サンプル説明
左に1つビットシフトすると、
2倍にするという意味になります。
2つだと
4倍です、この例では
と、
3個ビットシフトしてますので
8倍です。
右にビットシフトはこの逆です。
右に1つビットシフトは
2分の1、
2つで4分の1、
3つで8分の1です。整数での計算ですから、
余りが出た場合は、切り捨てられます。
もう一つ紹介します。今度は
K&Rのビット操作の関数を
C++で書き直したものです。
ソース紹介
CPPファイルに記述
#include <iostream>
#include <cstdio>
using namespace std;
/*
xの中の1であるビットを数える
*/
int bitcount(unsigned int x) {
int b;
for (b = 0; x != 0; x >>= 1) {
if (x & 01) {
b++;
}
}
return b;
}
/*
ビットカウントのテスト
*/
int main()
{
cout << "56: " << bitcount(56) << endl;
cout << "0X1b: " << bitcount(0X1b) << endl;
return 0;
}
出力
サンプル説明
bitcount()関数内の
for (b = 0; x != 0; x >>= 1) {
の条件式は重要です。
unsigned intの場合、
右シフトすると、左端のビットは
0 で埋められます。
ですから、
右にどんどんシフトしていくと、最終的に
0 になります。この特性を利用して、
forの条件式を記述しています。
K&Rでの記述
元になった
bitcount()関数は
第2章:データ型・演算子・式に記述されています。
代入演算子と式の説明のところです。