位運算

在實際應用中能夠作用戶權限的應用
002 我這裏說到的權限管理辦法是一個廣泛採用的方法,主要是使用到」位運行符」操做,& 位與運算符、| 位或運行符。參與運算的若是是10進制數,則會被轉換至2進制數參與運算,而後計算結果會再轉換爲10進制數輸出。
003 它的權限值是這樣的
004 2^0=1,相應2進數爲」0001″(在這裏^我表示成」次方」,即:2的0次方,下同)
005  
006 2^1=2,相應2進數爲」0010″
007 2^2=4,相應2進數爲」0100″
008 2^3=8,相應2進數爲」1000″
009 要判斷一個數在某些數範圍內就可使用 & 運算符(數值從上面的表中得來)
010 如:7=4|2|1 (你也能夠簡單理解成7=4+2+1)
011 用 & 來操做,能夠知道7&四、7&二、7&1都是真的,而若是7&8則是假的
012 &、| 不熟悉的就要去查查手冊,看看是怎麼用的了
013 下面來看例子吧:
014 // 賦予權限值-->刪除:八、上傳:四、寫入:二、只讀:1
015 define(「mDELETE」,8);
016 define(「mUPLOAD」,4);
017 define(「mWRITE」,2);
018 define(「mREAD」,1);
019 //vvvvvvvvvvvvv使用說明vvvvvvvvvvvvv
020 //部門經理的權限爲(假設它擁有此部門的全部權限),| 是位或運行符,不熟悉的就查查資料
021 echo mDELETE|mUPLOAD|mWRITE|mREAD ,」
022 「;// 至關因而把上面的權限值加起來:8+4+2+1=15
023 // 設我只有 upload 和 read 權限,則
024 echo mUPLOAD|mREAD ,」
025 「;//至關因而把上傳、只讀的權限值分別相加:4+1=5
026 /*
027 *賦予它多個權限就分別取得權限值相加,又好比某位員工擁有除了刪除外的權限其他都擁有,那它的權限值是多少?
028 *應該是:4+2+1=7
029 *明白了怎麼賦值給權限吧?
030 */
031 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
032 //判斷某人的權限可用,設權限值在$key中
033 /*
034 *判斷權限用&位與符,
035 */
036 $key = 13;//13=8+4+1
037 if($key & mDELETE) echo 「有刪除權限
038 「; //8
039 if($key & mUPLOAD) echo 「有上傳權限
040 「; //4
041 $a=$key & mWRITE; echo 「有寫權限
042 「.$a//無此權限
043 if($key & mREAD) echo 「有讀權限
044 「; //1
045 ?>
046   OK,權限分值的這其中一個算法就是這樣的,能夠說是簡單高效。也不知你們明白沒有,不明白也不要緊,記住例子就好了。前提就是作好權限值的分佈,即那個一、二、四、八、16….(這裏還有個順序問題,越高級的權限就要越高的權限值,好比上面的例子所演示的刪除權限)。有了權限分佈表就能夠肯定給某我的什麼權限了,你簡單的理解成要哪一個權限就加上相應的權限值吧。
047   這個方法很好用的,缺點就是若是權限分佈得細的話,那麼權限值會愈來愈大,你本身想一想,2的幾回方、若是全部的權限都要則是所有相加。不過對於通常的權限來講這個已經足夠了。
048  
049 下面是些簡單應用舉例
050  
051 (1) 判斷int型變量a是奇數仍是偶數
052  
053 a&1 = 0 偶數
054  
055 a&1 = 1 奇數
056  
057 (2) 取int型變量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1
058  
059 (3) 將int型變量a的第k位清0,即a=a&~(1<
060  
061 <>
062  
063 (4) 將int型變量a的第k位置1, 即a=a|(1<
064  
065 <>
066  
067 (5) int型變量循環左移k次,即a=a<>16-k (設sizeof(int)=16)
068  
069 (6) int型變量a循環右移k次,即a=a>>k|a<<16-k (設sizeof(int)=16)
070  
071 (7)整數的平均值
072  
073 對於兩個整數x,y,若是用 (x+y)/2 求平均值,會產生溢出,由於 x+y 可能會大於INT_MAX,可是咱們知道它們的平均值是確定不會溢出的,咱們用以下算法:
074  
075 int average(int x, int y) //返回X,Y 的平均值
076  
077 {
078  
079 return (x&y)+((x^y)>>1);
080  
081 }
082  
083 (8)判斷一個整數是否是2的冪,對於一個數 x >= 0,判斷他是否是2的冪
084  
085 boolean power2(int x)
086  
087 {
088  
089 return ((x&(x-1))==0)&&(x!=0);
090  
091 }
092  
093 (9)不用temp交換兩個整數
094  
095 void swap(int x , int y)
096  
097 {
098  
099 x ^= y;
100  
101 y ^= x;
102  
103 x ^= y;
104  
105 }
106  
107 (10)計算絕對值
108  
109 int abs( int x )
110  
111 {
112  
113 int y ;
114  
115 y = x >> 31 ;
116  
117 return (x^y)-y ; //or: (x+y)^y
118  
119 }
120  
121 (11)取模運算轉化成位運算 (在不產生溢出的狀況下)
122  
123 a % (2^n) 等價於 a & (2^n – 1)
124  
125 (12)乘法運算轉化成位運算 (在不產生溢出的狀況下)
126  
127 a * (2^n) 等價於 a<< n
128  
129 (13)除法運算轉化成位運算 (在不產生溢出的狀況下)
130  
131 a / (2^n) 等價於 a>> n
132  
133 例: 12/8 == 12>>3
134  
135 (14) a % 2 等價於 a & 1
136  
137 (15) if (x == a) x= b;
138  
139    else x= a;
140  
141    等價於 x= a ^ b ^ x;
142  
143 (16) x 的 相反數 表示爲 (~x+1)
144  
145 在32位系統上不要右移超過32位,不要在結果可能超過 32 位的狀況下左移
相關文章
相關標籤/搜索