日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當前位置:首頁 > php開源 > php教程 > php移位運算、移位操作學(xué)習(xí)筆記

php移位運算、移位操作學(xué)習(xí)筆記

來源:程序員人生   發(fā)布時間:2013-12-24 01:02:58 閱讀次數(shù):3905次

位運算應(yīng)用口訣

清零取位要用與,某位置一可用或

若要取反和交換,輕輕松松用異或

移位運算

要點

1 它們都是雙目運算符,兩個運算分量都是整形,結(jié)果也是整形。

2 "<<" 左移:右邊空出的位上補0,左邊的位將從字頭擠掉,其值相當于乘2。

3 ">>"右移:右邊的位被擠掉。對于左邊移出的空位,如果是正數(shù)則空位補0,若為負數(shù),可能補0或補1,這取決于所用的計算機系統(tǒng)。

4 ">>>"運算符,右邊的位被擠掉,對于左邊移出的空位一概補上0。

位運算符的應(yīng)用 (源操作數(shù)s 掩碼mask)

(1) 按位與-- &

1 清零特定位 (mask中特定位置0,其它位為1,s=s&mask)

2 取某數(shù)中指定位 (mask中特定位置1,其它位為0,s=s&mask)

(2) 按位或-- |

常用來將源操作數(shù)某些位置1,其它位不變。 (mask中特定位置1,其它位為0 s=s|mask)

(3) 位異或-- ^

1 使特定位的值取反 (mask中特定位置1,其它位為0 s=s^mask)

2 不引入第三變量,交換兩個變量的值 (設(shè) a=a1,b=b1)

目 標           操 作              操作后狀態(tài)

a=a1^b1         a=a^b              a=a1^b1,b=b1

b=a1^b1^b1      b=a^b              a=a1^b1,b=a1

a=b1^a1^a1      a=a^b              a=b1,b=a1

二進制補碼運算公式:

-x = ~x + 1 = ~(x-1)

~x = -x-1

-(~x) = x+1

~(-x) = x-1

x+y = x - ~y - 1 = (x|y)+(x&y)

x-y = x + ~y + 1 = (x|~y)-(~x&y)

x^y = (x|y)-(x&y)

x|y = (x&~y)+y

x&y = (~x|y)-~x

x==y:    ~(x-y|y-x)

x!=y:    x-y|y-x

x< y:    (x-y)^((x^y)&((x-y)^x))

x<=y:    (x|~y)&((x^y)|~(y-x))

x< y:    (~x&y)|((~x|y)&(x-y))//無符號x,y比較

x<=y:    (~x|y)&((x^y)|~(y-x))//無符號x,y比較

應(yīng)用舉例

(1) 判斷int型變量a是奇數(shù)還是偶數(shù)          

a&1   = 0 偶數(shù)

a&1 =   1 奇數(shù)

(2) 取int型變量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1

(3) 將int型變量a的第k位清0,即a=a&~(1<<k)

(4) 將int型變量a的第k位置1, 即a=a|(1<<k)

(5) int型變量循環(huán)左移k次,即a=a<<k|a>>16-k   (設(shè)sizeof(int)=16)

(6) int型變量a循環(huán)右移k次,即a=a>>k|a<<16-k   (設(shè)sizeof(int)=16)

(7)整數(shù)的平均值

對于兩個整數(shù)x,y,如果用 (x+y)/2 求平均值,會產(chǎn)生溢出,因為 x+y 可能會大于INT_MAX,但是我們知道它們的平均值是肯定不會溢出的,我們用如下算法:

  1. int average(int x, int y)   //返回X,Y 的平均值 
  2. {   
  3.      return (x&y)+((x^y)>>1); 

(8)判斷一個整數(shù)是不是2的冪,對于一個數(shù) x >= 0,判斷他是不是2的冪

  1. boolean power2(int x) 
  2.     return ((x&(x-1))==0)&&(x!=0); 

(9)不用temp交換兩個整數(shù)

  1. void swap(int x , int y) 
  2.     x ^= y; 
  3.     y ^= x; 
  4.     x ^= y; 

(10)計算絕對值

  1. int abs( int x ) 
  2. int y ; 
  3. y = x >> 31 ; 
  4. return (x^y)-y ;        //or: (x+y)^y 

(11)取模運算轉(zhuǎn)化成位運算 (在不產(chǎn)生溢出的情況下)

a % (2^n) 等價于 a & (2^n - 1)

(12)乘法運算轉(zhuǎn)化成位運算 (在不產(chǎn)生溢出的情況下)

a * (2^n) 等價于 a<< n

(13)除法運算轉(zhuǎn)化成位運算 (在不產(chǎn)生溢出的情況下)

a / (2^n) 等價于 a>> n  例: 12/8 == 12>>3

(14) a % 2 等價于 a & 1

(15) if (x == a) x= b;

else x= a;等價于 x= a ^ b ^ x;

(16) x 的 相反數(shù) 表示為 (~x+1)

最后補充一些關(guān)于二進制位移操作

PHP主要是設(shè)計于文本操作的,其實PHP不適合做數(shù)學(xué)運算,效率也不高,不過因為這次的項目中有個東西必須使用到二進制位移操作,在PHP上面遇到了一些麻煩。

因為PHP只有32位有符號整數(shù),沒有64位長整型,也沒有無符號整數(shù)。其整型的范圍是-231-1~231,超出這個范圍的,將被解釋為浮點數(shù)。因此,0xFFFFFFFF,直接打印,顯示的是4294967295,及232:

>> 0xFFFFFFFFF

4294967295

>>  gettype(0xFFFFFFFF)

'double'

而在32位有符號整型中,0xFFFFFFFF應(yīng)表示-1:

>> (int)0xFFFFFFFFF

-1

而PHP不支持浮點數(shù)的二進制位移操作,如果要進行,會先轉(zhuǎn)換為整型,最后的結(jié)果,也將按照整型來返回:

  1. >> 1 << 31 
  2. -2147483648 
  3. >> 1 << 30 
  4. 1073741824 
  5. >> 1 << 32 
  6. >> 0xFFFFFFFF >> 1 
  7. -1 

同時PHP的向右位移操作,高位會填充符號位,而且PHP沒有提供類似Java的>>>來強制填充0:

  1. >> 1 << 32 
  2. >> 0xFFFFFFFF >> 1 
  3. -1 
  4. >> 0xFFFFFFFF >> 2 
  5. -1 
  6. >> 0xFFFFFFFF >> 3 
  7. -1 
  8. >> 0xFFFFFFFF >> 31 
  9. -1 

如何解決這個問題呢,我考慮過使用BCMath數(shù)學(xué)函數(shù)庫,直接處理字符串表示的整數(shù),或者是GMP/BigInt擴展等。不過我想既然使用字符串,那么我可以字符串地徹底一些,把數(shù)字轉(zhuǎn)換成32個二進制的字符串,再手工填充0,最后轉(zhuǎn)換回來。

不知道哪位有更好的方法,請告訴我,另外,其實代碼可以擴展為任意位2進制的位移操作,這里我沒有做,PHP代碼如下:

  1. <?php 
  2. /** 
  3.  * 無符號32位右移 
  4.  * @param mixed $x 要進行操作的數(shù)字,如果是字符串,必須是十進制形式 
  5.  * @param string $bits 右移位數(shù) 
  6.  * @return mixed 結(jié)果,如果超出整型范圍將返回浮點數(shù) 
  7.  */ 
  8. function shr32($x$bits){ 
  9.     // 位移量超出范圍的兩種情況 
  10.     if($bits <= 0){ 
  11.         return $x
  12.     } 
  13.     if($bits >= 32){ 
  14.         return 0; 
  15.     } 
  16.     //轉(zhuǎn)換成代表二進制數(shù)字的字符串 
  17.     $bin = decbin($x); 
  18.     $l = strlen($bin); 
  19.     //字符串長度超出則截取底32位,長度不夠,則填充高位為0到32位 
  20.     if($l > 32){ 
  21.         $bin = substr($bin$l - 32, 32); 
  22.     }elseif($l < 32){ 
  23.         $bin = str_pad($bin, 32, '0', STR_PAD_LEFT); 
  24.     } 
  25.     //取出要移動的位數(shù),并在左邊填充0 
  26.     return bindec(str_pad(substr($bin, 0, 32 - $bits), 32, '0', STR_PAD_LEFT)); 
  27. /** 
  28.  * 無符號32位左移 
  29.  * @param mixed $x 要進行操作的數(shù)字,如果是字符串,必須是十進制形式 
  30.  * @param string $bits 左移位數(shù) 
  31.  * @return mixed 結(jié)果,如果超出整型范圍將返回浮點數(shù) 
  32.  */  
  33. function shl32 ($x$bits){ 
  34.     // 位移量超出范圍的兩種情況 
  35.     if($bits <= 0){ 
  36.         return $x;  
  37.     } 
  38.     if($bits >= 32){ 
  39.         return 0;  
  40.     } 
  41.     //轉(zhuǎn)換成代表二進制數(shù)字的字符串 
  42.     $bin = decbin($x); 
  43.     $l = strlen($bin); 
  44.     //字符串長度超出則截取底32位,長度不夠,則填充高位為0到32位 
  45.     if($l > 32){ 
  46.         $bin = substr($bin$l - 32, 32); 
  47.     }elseif($l < 32){ 
  48.         $bin = str_pad($bin, 32, '0', STR_PAD_LEFT); 
  49.     } 
  50.     //取出要移動的位數(shù),并在右邊填充0 
  51.     return bindec(str_pad(substr($bin$bits), 32, '0', STR_PAD_RIGHT)); 
  52. ?> 
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 九九热久久久99国产盗摄蜜臀 | 言情恋老小说言情网 | 黄网站在线观看 | 国产精品美女久久久久aⅴ国产馆 | 欧美 日韩 视频 | 九九视频在线 | 17c一起操 | 俄罗斯精品一区二区三区 | 精品久久9 | www.亚洲一区| 狠狠的日 | 欧美日韩国产免费 | 国产中文字幕一区 | 国产99在线播放 | 国产精品久久久久免费视频 | av在线播放网站 | 狠狠777| 国产精品久久久久婷婷二区次 | 91精品久久久久 | 精品福利一区二区三区 | 久久aa| 九九热视频在线 | 亚洲国产成人精品女人久久久 | 亚洲乱码视频 | 亚洲成人一区在线观看 | 久久国产精品电影 | 日韩在线精品视频 | 欧美视频一区二区 | 亚洲一区二区精品在线 | 亚洲欧美日韩在线 | 一区二区三区精品在线 | 亚洲综合在线一区二区 | 真人一级毛片视频 | 国产欧美日韩综合精品一区二区 | 黄色网址在线免费观看 | 国产一二三区免费观看 | 亚洲精品久久久一区二区三区 | 亚洲一区二区三区欧美 | 岛国av免费观看 | 国产一区日韩 | 国产精品三级久久久久久电影 |