位操作基礎知識了解一下
在刷題和完成實驗室給的作業中,有關位操作的問題還是挺多的,所以在這裏再寫一遍加深學習記憶233
位操作是基於二進制進行運算的,所以本文所有描述均基於二進制
一,基礎操作符:
"&"(與):同1則1
eg:0000 0010 & 0000 0011 = 0000 0010 (2&3=2)
"|"(或):同0則0
eg:0000 0010 | 0000 0011 = 0000 0011 (2|3=3)
"^"(異或):相同為0,相異為1
eg:0000 0010 ^ 0000 0011 = 0000 0001 (2^3=1)
"~"(取反):0變1,1變0 <六個操作符中唯一一個單目操作符>
eg: ~ 0000 0010 = 1111 1101 (~2=-3)
"<<"(左移):全部左移若幹位,高位舍去,低位補0 <左移一位相當於乘2>
eg:0000 1111 << 1 = 0001 1110(15<<1=30)
">>"(右移):全部右移若幹位,對無符號數,高位補0,有符號數,各編譯器處理方法不一樣
****位操作的對象是整型數****
****位操作的運算優先級較低,所以最好使用括號****
二,位操作常用小技巧:
1>.判斷奇偶:
對二進制數來說,奇偶的區別在於最末一位是0還是1:
1 for i in range (100): 2 if i&1 ==0: 3 print ("%d是偶數"%i) 4 else: 5 print ("%d是奇數"%i)
這裏還有個常用小技巧--判斷某數是否為2的冪(Leetcode231):
設該數為n,如果n 位與(n-1)的結果為0,則為2的冪
2>.交換兩個數:
使用位操作交換兩個數的方便之處是不需要使用第三方變量,但是位操作只能交換整型數據:
1 def swap(a,b): #a=0000 0011,b=0000 0100,第一步:a=a^b=0000 0111;2 if a!=b: #第二步:b=b^a=0000 0100^0000 0111=0000 0011(此時b=a) 3 a^=b #解釋:b=b^a => b=b^(a^b)因為異或運算滿足交換律,所以,b^(a^b)=b^b^a, 4 b^=a #一個數與其自身異或的結果為0,而0異或任何數都不變,所以此時b=a 5 a^=b #第三步:a=a^b=0000 0111^0000 0011=0000 0100(此時a=b) 6 print(a,b) #解釋:a=a^b => a=a^b^a=b(同第二步原理) 7 8 a,b=3,4 9 swap(a,b)
3>.變換符號
只需要對該數取反加一:
1 def function(num): 2 return ~num+1 3 n=5 4 print (function(n))
4>.求絕對值
先判斷該數的正負性,若為正數則直接返回,若為負數就改變符號
而判斷是否為負,可以通過二進制數右移31位直接判斷符號,0為正,1為負:
1 def function(num): 2 num>>31 3 if num==0: 4 return num 5 else : 6 return (~num+1) 7 print (function(-5))
對於任何數,與0異或都不變,所以與-1即0xFFFFFFFF異或就相當於取反。所以,a與a右移後的數(i)異或後再減i(因為i為0或-1,所以減i的結果
要麽加0要麽加1 )也可以得到絕對值,進行優化:
1 def function(num): 2 i=num>>31 3 return (num^i)-i 4 print (function(-5))
以上就是關於位操作簡單技巧的介紹,刷題過程中遇到我會繼續補充。
位操作還可以解決八皇後問題~還有其他的趣味應用~遇到的話再一一補充。
位操作基礎知識了解一下