PHP入門 ≫ LESSON8 ビット演算
ビットとは?
ビットとは、コンピュータで扱うデータの最小単位です。
1ビットに入るのは、「ある」か「なし」かどちらかの状態です。これを便宜上1と0で表したものが2進数となります。

2進数については、スカラー:数値でちょっと説明しています。
1ビットが8つ繋がった8ビットは、8桁の2進数ととみなされます。複数桁のビットは、ビット列とも呼ばれます。
正直何のプログラムを書いてもあんまり使うことはありません。
ですが、基本ですので一応知っておきましょう。
2進数の表現は、
$hensu = 0b10;
と、数値の前に「0b」をつけますが、この値を普通に出力すると10進数になってしまいます。
2進数、つまりビット列としてそのまま出力したい場合は。10進数から2進数に変換するdecbin関数を使いましょう。
$hensu = 0b10;
echo "$hensu\n";
echo decbin($hensu);
結果は以下。
2
10
最初はそのまま10進数として出力したもので、次は2進数として出力したものです。
ビット演算の結果は、この方法で確認しましょう。
ビット演算とは、ビットを対象に行う演算で、基本的に桁ごとに演算を行います。
ビット演算子
ビットの演算を行うには、ビット演算子を使います。
ビット演算子には次のようなものがあります
a & b | ビット積。aとb両方1なら1、それ以外は0 |
---|---|
a | b | ビット和。aとb両方0なら0、それ以外は1 |
~a | ビット否定。aと逆のビット値 |
a ^ b | 排他的論理和。aとbが両方同じビットなら0、それ以外は1 |
a >> b | 左シフト。aを左にbビットシフトする |
a << b | 右シフト。aを右にbビットシフトする |
↑で説明している1と0はビットの値のことです。
ビットもよくわからなければ、積とか和ってなに!?って人もいると思います。
なので簡単な順に説明していきます。
否定
ビット否定は、「~」という記号を使います。その後に続く値が1なら0、0なら1にひっくりかえります。 ビット列の場合、それぞれビットごとにひっくりかえります。

最初の1は0、次の0は1、最後の1は0になります。
$hensu = 0b101;
echo decbin(~$hensu);
結果は以下。
11111111111111111111111111111010
101がすべてビットごとに逆になるので、010となる。。。と思うのですが、実際この環境では32ビットでデータを扱うので、101の前の29桁は全部0でうまって
00000000000000000000000000000101
になってます。これを全部桁ごとにひっくり返すので
11111111111111111111111111111010
となります。
積
積は、「&」という記号を使います。記号左右の値が両方1なら1、それ以外は0になります。

1と1の桁だけ1、あとは0になります。
$hensu = 0b1010;
$hensu2 = 0b1100;
echo decbin($hensu & $hensu2);
結果は以下。
1000
和
和は、「|」という記号を使います。記号左右の値が両方0なら0、それ以外は1になります。

0と0の桁だけ0、あとは1になります。
$hensu = 0b1010;
$hensu2 = 0b1100;
echo decbin($hensu | $hensu2);
結果は以下。
1110

和、というと足し算かと思っちゃうかもしれませんが、足し算の答えの「和」とは違います。積も掛け算の答えではありません。
ビット演算は、ビットごとに0か1を返すもので、四則演算のように演算結果が隣の桁に影響する繰上りや繰り下がりはありません。
ごっちゃにならないように気をつけましょう!
排他的論理和
排他的論理和は、「^」という記号を使います。記号左右の値が両方同じビットなら0、それ以外は1になります。

両方1か0の場合は0、違う場合は1になります。
$hensu = 0b1010;
$hensu2 = 0b1100;
echo decbin($hensu | $hensu2);
結果は以下。
110
こちら、正確には0110ですが、最初の0は表現されずに110となっています。
シフト
シフトは、右シフトは「>>」左シフトは「<<」という記号を使います。記号左の値を、左右どちらかに記号右ビット分移動します。

右シフトの場合、右端の部分は押し出されてなくなります。

左シフトの場合、空いた右端には勝手に0が入ります。
$hensu = 0b110;
echo decbin($hensu >> 1) . "\n";
echo decbin($hensu << 2);
結果は以下。
11
11000