2011-01-26

PHPでビット演算、シフト演算

ビットをフラグ代りに使うことが増えてきたので。。。
1ビット1アイテムって思うと、最大で63個まで持ってるか分かるようになる的な。
なんで63個かっていうと64個だとMySQLにしまえない可能性があるみたい。
(使ってるVerが古いってのもあるし、そもそも勘違いかもだけどー。)
とりあえず、PHPで書いたさんぷる。

さんぷるクリプト


  1. // 色情報  
  2. $items=array('red'=>1, 'blue'=>2, 'green'=>3, 'white'=>4, 'black'=>5);  
  3. // 人情報  
  4. $peoples = array('LILY'=>0, 'LOGAN'=>0, 'OLIVIA'=>0);  
  5. /* 
  6.  * 選択情報を作る 
  7.  */  
  8. $peoples['LILY'] =  
  9.  (1 << $items['red'])  
  10.  | (1 << $items['green'])  
  11.  | (1 << $items['black']) ;  // red, green, black を選ぶ  
  12.   
  13. printf("name:% 7s int:% 4d bit:%08b\n",  
  14.  'LILY'$peoples['LILY'], $peoples['LILY']);  
  15.   
  16. $peoples['LOGAN'] =  
  17.  (1 << $items['blue'])  
  18.  | (1 << $items['green'])  
  19.  | (1 << $items['black']) ;  // blue, green, black を選ぶ  
  20.   
  21. printf("name:% 7s int:% 4d bit:%08b\n",  
  22.  'LOGAN'$peoples['LOGAN'], $peoples['LOGAN']);  
  23.   
  24. $peoples['OLIVIA'] =  
  25.  (1 << $items['red'])  
  26.  | (1 << $items['white'])  
  27.  | (1 << $items['black']) ;  // red, white, black を選ぶ  
  28.   
  29. printf("name:% 7s int:% 4d bit:%08b\n",  
  30.  'OLIVIA'$peoples['OLIVIA'], $peoples['OLIVIA']);  
  31.   
  32. print "======================\n";  
  33.   
  34. /* 
  35.  * 皆が選択している色だけを選らぶ 
  36.  * (論理積) 
  37.  */  
  38. $common_col=0;  
  39. $common_col=  
  40.  $peoples['LILY'] & $peoples['LOGAN'] & $peoples['OLIVIA'] ;  
  41. printf("common colors int:% 4d bit:%08b\n"$common_col$common_col);  
  42. chkSelections($common_col);  
  43.   
  44. print "======================\n";  
  45.   
  46. /* 
  47.  * 選択されている全ての色を選ぶ 
  48.  * (論理和) 
  49.  */  
  50. $common_col=0;  
  51. $common_col=  
  52.  $peoples['LILY'] | $peoples['LOGAN'] | $peoples['OLIVIA'] ;  
  53. printf("common colors int:% 4d bit:%08b\n"$common_col$common_col);  
  54. chkSelections($common_col);  
  55.   
  56. exit;  
  57.   
  58. /* 
  59.  * ビットが立っているものを探す 
  60.  */  
  61. function chkSelections($selections)  
  62. {  
  63.   global $items;  
  64.     
  65.   foreach ( $items as $col_name => $col_num )  
  66.   {  
  67.     $chk_bit=( 1 << $col_num );  
  68.     if$selections & $chk_bit ) // ビットが立ってる  
  69.     {  
  70.       printf("Select color:% 6s\n"$col_name);  
  71.     }  
  72.   }  
  73. }  

シフト演算でビットが立っているところを探していく方法もあるけど。
  1. $col_num=0;  
  2. while$selections )  
  3. {  
  4.   if$selections & 1 )  
  5.   {  
  6.     printf("Select color number:%d bit:%08b\n"$col_num$selections);  
  7.   }  
  8.    $selections = $selections >> 1;  
  9.   $col_num++;  
  10. }  


MySQL


選択情報をMySQLに格納して、クエリで取得することもできる。

SELECT * hoge WHERE select_bit & ${col_num} ;

これでその色を選択している情報が引っ張れるです。