PHP入門 ビット演算子

ビット演算を行うための演算子です。ビット演算とは、整数を2進数で表したときの各桁(ビット単位)に対して論理計算を行う演算のことです。

主なビット演算子

演算子概要用例
&論理積。左式/右式の双方にセットされているビットをセット10&1→1010&0001→0000→0
|論理和。左式/右式のいずれかにセットされているビットをセット10|1→1010|0001→1011→11
^排他的論理和。左式/右式のいずれかでセットされており、かつ、双方にセットされていないビットをセット10^1→1010^0001→1011→11
~(チルダ)否定。ビットを反転~10→~1010→0101→-11
<<ビットを左にシフト10<<1 → 1010 << 1 →10100→20
>>ビットを右にシフト10>>1 → 1010 >> 1 →0101→5

ビット論理演算子

ビット演算では、与えられた整数を2進数に変換した上で、それぞれの桁について論理演算を行います。論理積では、双方のビットが1(true)である場合にのみ結果も1(true)、それ以外は0(false)になります。ビット演算子は、演算の結果を再び10進数に戻したものを返します。

否定演算子では、すべてのビットを反転させます。否定演算子が正負を表す符号も反転させます。ビット値で負数を表す場合「ビットを反転させて1を加えたものが、その絶対値になる」というルールがあります。例えば、「1010(10進数では10)」を反転させた「0101」に1を加えた「0110」(10進数では6)が絶対値となり、結果は-6となります。

ビットシフト演算子

ビットシフト演算も、10進数をまず2進数ととらえるのは同じです。その桁を左または右に指定の桁だけ移動します。左シフトした場合、シフトした分、右側の桁は0で埋められます。例えば、「1010(10進数では10)」が左シフトの結果「101000」となります。演算結果は、これを10進数に書き戻し40となります、

ビットフィールドによるフラグ管理

ビット演算子の用途としてビットフィールドがあります。ビットフィールドとは、複数のフラグ(オンオフ)をビットの並びとして表現する手法のことです。定数値として2の塁乗を割り当てることで表現します。

const SPRING = 1 << 0;   //0001
const SUMMER = 1 << 1;   //0010
const AUTUMN = 1 << 2;   //0100
const WINTER = 1 << 3;   //1000

ビットフィールドは、「|」演算子を用いることで1つにまとめられます。例えば「SPRING + WINTER」であれば「SPRING | WINTER」です。論理和をとって1001のような値が生成されます。

ビットフィールドは、オンオフを検査することもできます。例えば、$flagsにSUMMERが含まれるか検査する例です。

$flags = SPRING | WINTER;
var_dump( $flags & SUMMER );  //結果:int(0)(SUMMERは無効)

「&」演算子を利用することでビットがオンでなければ、すべてのビットが0となります。

より複雑なパターンとして「SPRING/WINTERを含んでいるか」「SPRING/WINTERだけを含んでいるか」のような表現も可能です。

$flags = SPRING | AUTUMN | WINTER;
//最低でもSPRING/WINTERを含んでいるか(結果はtrue)
var_dump(($flags & (SPRING | WINTER)) === (SPRING | WINTER));
//SPRING/WINTERだけを含んでいるか(結果はfalse)
var_dump(($flags | (SPRING | WINTER)) === (SPRING | WINTER));