ビット演算でステータス管理
ビット演算の良いサンプルをみつけた
さんぷるクリプト: PHPでビット演算、シフト演算
上記サイトの丸コピーです。
各桁のフラグが立っているかどうかで、ステータス管理を行う。
sprintfでビット表示する場合、「b」を使う
<?php // 色情報 $items=array('red'=>1, 'blue'=>2, 'green'=>3, 'white'=>4, 'black'=>5); // 人情報 $peoples = array('LILY'=>0, 'LOGAN'=>0, 'OLIVIA'=>0); /* * 選択情報を作る */ $peoples['LILY'] = (1 << $items['red']) | (1 << $items['green']) | (1 << $items['black']) ; // red, green, black を選ぶ $peoples['LOGAN'] = (1 << $items['blue']) | (1 << $items['green']) | (1 << $items['black']) ; // blue, green, black を選ぶ $peoples['OLIVIA'] = (1 << $items['red']) | (1 << $items['white']) | (1 << $items['black']) ; // red, white, black を選ぶ printf("name:%7s int:%4d bit:%08b\n" , 'LILY' , $peoples['LILY'] , $peoples['LILY']); printf("name:%7s int:%4d bit:%08b\n" , 'LOGAN' , $peoples['LOGAN'] , $peoples['LOGAN']); printf("name:%7s int:%4d bit:%08b\n" , 'OLIVIA' , $peoples['OLIVIA'] , $peoples['OLIVIA']); print "======================\n"; /* * 皆が選択している色だけを選らぶ * (論理積) */ $common_col=0; $common_col=$peoples['LILY'] & $peoples['LOGAN'] & $peoples['OLIVIA']; printf("common colors int:%4d bit:%08b\n", $common_col, $common_col); chkSelections($common_col); print "======================\n"; /* * 選択されている全ての色を選ぶ * (論理和) */ $common_col=0; $common_col=$peoples['LILY'] | $peoples['LOGAN'] | $peoples['OLIVIA']; printf("common colors int:%4d bit:%08b\n", $common_col, $common_col); chkSelections($common_col); exit; /* * ビットが立っているものを探す */ function chkSelections($selections) { global $items; foreach ($items as $col_name => $col_num) { $chk_bit = ( 1 << $col_num ); if ( $selections & $chk_bit ) { // ビットが立ってる printf("Select color:% 6s\n", $col_name); } } }
mysqlで例えばgreenを選択しているデータを取得したい場合
select * from col & bin(3)
のようにすればOK
ちなみにphpで2進数を変数として扱いたい場合、数値の先頭に0bをつければよい。
ただしphp5.4.0以降のみ対応。
10進数→2進数はdecbin()で行う
シフト演算メモ
<?php $a = 1 << 0; // 1 (1をシフトしないわけだから1のまま) $a = 1 << 1; // 2 $a = 1 << 2; // 4