読者です 読者をやめる 読者になる 読者になる

ビット演算でステータス管理

ビット演算の良いサンプルをみつけた
さんぷるクリプト: 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以降のみ対応。

PHP: 整数 - Manual


10進数→2進数はdecbin()で行う

シフト演算メモ

<?php
$a = 1 << 0; // 1 (1をシフトしないわけだから1のまま)
$a = 1 << 1; // 2
$a = 1 << 2; // 4