ビット演算とは
コンピュータは内部的に全てのデータを2進数(ビット列)で扱います。ビット演算は、この2進数の各桁を直接操作する演算です。
何に使う? フラグ管理、マスク処理、高速な乗除算、ハードウェア制御、暗号処理など。組込み系・システムプログラミングでは必須です。
前提知識: 10進数の 12 は 2進数で 00001100。各桁が1か0かで値を表します。
シフト演算 (<<, >>)
ビット列を左右に移動させる演算です。
左シフト ( << )
a << n = a × 2n
5 << 1 → 10(5×2)
5 << 3 → 40(5×8)
右シフト ( >> )
a >> n = a ÷ 2n(切り捨て)
40 >> 1 → 20(40÷2)
40 >> 3 → 5(40÷8)
// 5 を 2進数で見る
// 00000101 = 5
// 5 << 2
// 00010100 = 20 (5 × 4)
// 20 >> 1
// 00001010 = 10 (20 ÷ 2)
左シフト1回 = ×2、右シフト1回 = ÷2。乗除算より高速なので、パフォーマンスが重要な場面で使われます。
活用例
偶数・奇数の判定
if (n & 1) printf("奇数\n");
else printf("偶数\n");
// 最下位ビットが1なら奇数、0なら偶数
フラグ管理
#define FLAG_READ (1 << 0) // 0001 = 1
#define FLAG_WRITE (1 << 1) // 0010 = 2
#define FLAG_EXEC (1 << 2) // 0100 = 4
int perm = 0;
perm |= FLAG_READ; // フラグをON
perm |= FLAG_WRITE; // フラグをON
if (perm & FLAG_READ) ... // フラグをチェック
perm &= ~FLAG_WRITE; // フラグをOFF
Linuxのファイルパーミッション(rwx = 読み書き実行)は、まさにこのビットフラグの仕組みです。
特定ビットの抽出(マスク)
int color = 0xFF5733; // RGB色
int r = (color >> 16) & 0xFF; // 255
int g = (color >> 8) & 0xFF; // 87
int b = color & 0xFF; // 51