ACM位運算技巧

                                            ACM位運算技巧

位運算應用口位運算應用口訣位運算應用口訣 
清零取反要用與,某位置一可用或 
若要取反和交換,輕輕鬆鬆用異或 
移位運算 
要點 1 它們都是雙目運算符,兩個運算份量都是整形,結果也是整形。 
    2 " >"右移:右邊的位被擠掉。對於左邊移出的空位,若是是正數則空位補0,若爲負數,可能補0或補1,這取決於所用的計算機系統。 
    4 ">>>"運算符,右邊的位被擠掉,對於左邊移出的空位一律補上0。 
位運算符的應用 (源操做數s 掩碼mask) 
(1) 按位與-- & 
1 清零特定位 (mask中特定位置0,其它位爲1,s=s&mask) 
2 取某數中指定位 (mask中特定位置1,其它位爲0,s=s&mask) 
(2) 按位或-- ¦ 
    經常使用來將源操做數某些位置1,其它位不變。 (mask中特定位置1,其它位爲0 s=s ¦mask) 
(3) 位異或-- ^ 
1 使特定位的值取反 (mask中特定位置1,其它位爲0 s=s^mask) 
2 不引入第三變量,交換兩個變量的值 (設 a=a1,b=b1) 
    目 標          操 做              操做後狀態 
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 >k&1 
(3) 將int型變量a的第k位清0,即a=a&~(1 >16-k  (設sizeof(int)=16) 
(6) int型變量a循環右移k次,即a=a>>k ¦a >1); 

(8)判斷一個整數是否是2的冪,對於一個數 x >= 0,判斷他是否是2的冪 
boolean power2(int x) 

    return ((x&(x-1))==0)&&(x!=0); 

(9)不用temp交換兩個整數 
void swap(int x , int y) 

    x ^= y; 
    y ^= x; 
    x ^= y; 

(10)計算絕對值 
int abs( int x ) 

int y ; 
y = x >> 31 ; 
return (x^y)-y ;        //or: (x+y)^y 

(11)取模運算轉化成位運算 (在不產生溢出的狀況下) 
        a % (2^n) 等價於 a & (2^n - 1) 
(12)乘法運算轉化成位運算 (在不產生溢出的狀況下) 
        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 的 相反數 表示爲 (~x+1) 

實例 
    功能              ¦          示例            ¦    位運算 
----------------------+---------------------------+-------------------- 
去掉最後一位          ¦ (101101->10110)          ¦ x >> 1 
在最後加一個0        ¦ (101101->1011010)        ¦ x 1011011)        ¦ x 101101)          ¦ x ¦ 1 
把最後一位變成0      ¦ (101101->101100)          ¦ x ¦ 1-1 
最後一位取反          ¦ (101101->101100)          ¦ x ^ 1 
把右數第k位變成1      ¦ (101001->101101,k=3)      ¦ x ¦ (1 101001,k=3)      ¦ x & ~ (1 101101,k=3)      ¦ x ^ (1 101)            ¦ x & 7 
取末k位              ¦ (1101101->1101,k=5)      ¦ x & ((1 
取右數第k位          ¦ (1101101->1,k=4)          ¦ x >> (k-1) & 1 
把末k位變成1          ¦ (101001->101111,k=4)      ¦ x ¦ (1 100110,k=4)      ¦ x ^ (1 100100000)    ¦ x & (x+1) 
把右起第一個0變成1    ¦ (100101111->100111111)    ¦ x ¦ (x+1) 
把右邊連續的0變成1    ¦ (11011000->11011111)      ¦ x ¦ (x-1) 
取右邊連續的1        ¦ (100101111->1111)        ¦ (x ^ (x+1)) >> 1 
去掉右起第一個1的左邊 ¦ (100101000->1000)        ¦ x & (x ^ (x-1)) 
判斷奇數      (x&1)==1 
判斷偶數 (x&1)==0        
例如求從x位(高)到y位(低)間共有多少個1 
public static int FindChessNum(int x, int y, ushort k) 
        { 
            int re = 0; 
            for (int i = y; i > (i - 1)) & 1); 
            } 
            return re; 
        } 

相關文章
相關標籤/搜索