​在实际应用中可以做用户权限的应用​


​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&4、7&2、7&1都是真的,而如果7&8则是假的​


​012​

​&、| 不熟悉的就要去查查手册,看看是怎么用的了​


​013​

​下面来看例子吧:​


​014​

​// 赋予权限值-->删除:8、上传:4、写入:2、只读: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,权限分值的这其中一个算法就是这样的,可以说是简单高效。也不知大家明白没有,不明白也没关系,记住例子就行了。前提就是做好权限值的分布,即那个1、2、4、8、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 位的情况下左移​