1. 程式人生 > >二進位制位運算和狀態儲存

二進位制位運算和狀態儲存

在很多系統的許可權/選項設定中 很多都用到了位運算的方法來儲存多種標誌位。在系統設計中只要是狀態只有兩種狀態(0,1)的都可以用二進位制位來表示,如果有多個狀態用多個位或者還是新加欄位吧。

(1)可以節省欄位。一個欄位只需要一個數字 就可以標識很多種設定和資訊。

(2)可以處理位置狀態需求,而無需更改資料表結構,比如需求增加是否繫結微信。

  1. 案例:User使用者表stat欄位

    1. #二進位制-標誌位
      0000 0000 0000 0001 第一位是否刪除
      0000 0000 0000 0010 第二位手機認證
      0000 0000 0000 0100 第三位微信認證

2. 如何用一個數字來標識這些許可權位呢

以剛才的user表中stat欄位為例,假如通過select stat from user where name='yubing'; 檢索出來的狀態值為$stat =5, 

如何檢查是否微信認證呢? 看上面的對照表第三位1表示微信認證。

$stat=5;原來的狀態值

$b=0b100;//第三位二進位制值

$stat&$b = 5 & 0100 = 0b100 = 4 兩個值相等表示狀態為1,表示認證過了。

因此 檢查,某個數代表的第N個許可權標誌位有沒有置位(是1) 。同理檢查是否手機認證,手機狀態位為第二位

$stat&0b10==0b10 結果為0,表示沒有手機認證。


3.php對應的演算法
 /*
 * $stat 狀態值
 * $position 對應的第幾位標誌位
 * return 返回標誌位是否為1
 */ 
 function getStat($stat,$position){
	$t = pow(2, $position - 1);
	return ((int)$stat&$t)==$t;
 }
 /*
 * $stat 狀態值
 * $position 對應的標誌值
 * $val 設定標誌位值1或者0
 * return 狀態值
 */ 
 function setStat($stat,$position=1,$val=1){
    $t = pow(2, $position - 1);
	return $val==1? ((int)$stat | $t) : ((int)$stat & ~$t);
 }
4.如何直接修改資料庫中的標誌位值呢?    比如修改使用者的手機認證狀態為認證 ,update user set stat=stat|2 where user='yubing'; 

修改使用者的微信狀態為不認證 update user set stat=stat&(~4) where user='yubing'; 同時修改狀態為手機認證,微信不認證 update user set stat=stat|2&(~4) where user='yubing';

5.使用二進位制位的不便之處就是需要記憶各個位表示什麼狀態,程式的可讀性比較差。折中的解決辦法,直接設定一個數組變數

$stat=['del'=>1,'mobile'=>0b10,'wx'=>4];  值為運算後的的2進位制或者10進位制值