只要根據最未位是0還是1來決定,為0就是偶數,為1就是奇數。因此可以用if ((a & 1) == 0)代替if (a % 2 == 0)來判斷a是不是偶數。
可以用位操作來實現交換兩數而不用第三方變數:
void swap(int &a, int &b)
}
第一步 a^=b 即a=(a^b);
第二步 b^=a 即b=b^(a^b),由於^運算滿足交換律,b^(a^b)=b^b^a。由於乙個數和自己異或的結果為0並且任何數與0異或都會不變的,所以此時b被賦上了a的值。
第三步 a^=b 就是a=a^b,由於前面二步可知a=(a^b),b=a,所以a=a^b即a=(a^b)^a。故a會被賦上b的值。
再來個例項說明下以加深印象。int a = 13, b = 6;
a的二進位制為 13=8+4+1=1101(二進位制)
b的二進位制為 6=4+2=110(二進位制)
第一步 a^=b a = 1101 ^ 110 = 1011;
第二步 b^=a b = 110 ^ 1011 = 1101;即b=13
第三步 a^=b a = 1011 ^ 1101 = 110;即a=6
變換符號就是正數變成負數,負數變成正數。
如對於-11和11,可以通過下面的變換方法將-11變成11
1111 0101(二進位制) –取反-> 0000 1010(二進位制) –加1-> 0000 1011(二進位制)
同樣可以這樣的將11變成-11
0000 1011(二進位制) –取反-> 0000 0100(二進位制) –加1-> 1111 0101(二進位制)
位操作也可以用來求絕對值,對於負數可以通過對其取反後加1來得到正數。對-6可以這樣:
1111 1010(二進位制) –取反->0000 0101(二進位制) -加1-> 0000 0110(二進位制)
來得到6。
因此先移位來取符號位,int i = a >> 31;要注意如果a為正數,i等於0,為負數,i等於-1。然後對i進行判斷——如果i等於0,直接返回。否之,返回~a+1。
int my_abs(int a)
現在再分析下。對於任何數,與0異或都會保持不變,與-1即0xffffffff異或就相當於取反。因此,a與i異或後再減i(因為i為0或-1,所以減i即是要麼加0要麼加1)也可以得到絕對值。所以可以對上面**優化下:
int my_abs(int a)
給出乙個16位的無符號整數。稱這個二進位制數的前8位為「高位」,後8位為「低位」。現在寫一程式將它的高低位交換。例如,數34520用二進位制表示為:
10000110
11011000
將它的高低位進行交換,我們得到了乙個新的二進位制數:
11011000
10000110
它即是十進位制的55430。
這個問題用位操作解決起來非常方便,設x=34520=10000110
11011000(二進位制) 由於x為無符號數,右移時會執行邏輯右移即高位補0,因此x右移8位將得到00000000
10000110。而x左移8位將得到11011000
00000000。可以發現只要將x>>8與x<<8這兩個數相或就可以得到11011000
10000110。
很多成對出現數字儲存在磁碟檔案中,注意成對的數字不一定是相鄰的,如2, 3, 4, 3, 4, 2……,由於意外有乙個數字消失了,如何盡快的找到是哪個數字消失了?
由於有乙個數字消失了,那必定有乙個數隻出現一次而且其它數字都出現了偶數次。用搜尋來做就沒必要了,利用異或運算的兩個特性——1.自己與自己異或結果為0,2.異或滿足交換律。因此我們將這些數字全異或一遍,結果就一定是那個僅出現乙個的那個數。
位運算技巧
1.lowbit x 實現 int lowbit int x 這個函式用來求數中二進位制位中最低位的1 完整求法 log2 lowbit x 需要注意的是,答案的範圍是0 30,因為31位是符號位,求出來的值為負數,原因如下 設x 0x8000 0000,那麼設res lowbit x 0x8000...
位運算技巧
數字和1相與 判斷奇偶 x 1 1 奇數 x 1 0 偶數 不用其他空間交換兩值 a a b b a b a a b 或a a b b a b a a b a 0 a a a 0 不用其他空間找陣列中唯一成對的那個數 int b 0 for int i 1 i 10 i int a 10 for i...
位運算技巧
1.或 符號 比較兩個數的每一位,只要有乙個數在這一位上為1,所得的新數在這一位上就為1,否則為0。2.與符號 比較兩個數的每一位,只有兩數這一位同時為1時所得新數為1,否則為0。3.異或 符號 比較兩數的每一位,如果一樣所得新數這一位就是0,不一樣就是1。4.取反 符號 0變1,1變0。5.移位 ...