演算法筆記:位運算
計算機中的資料都是以二進位制的形式儲存在裝置中,雖然十進位制比二進位制所需要的儲存空間少,但二進位制在硬體實現上要簡單很多,而且在數模轉換上也更加容易,因為只需要兩種狀態,所以計算機的底層運算都採用二進位制。位運算就是對二進位制資料進行的運算。使用合理的位運算可以提高程式碼在機器上的執行效率,本文將介紹常見的位運算以及Python中的位運算。
目錄位運算子
常見位操作符如下表:
運算子 | 含義 | Python示例 |
---|---|---|
& | AND 與 | x & y |
| | OR 或 | x | y |
~ | NOT 非 | ~x |
^ | XOR 異或 | x ^ y |
<< | 左移 | x << 1(相當於x*2) |
>> | 右移 | x >> 1(相當於x/2) |
>>> | 無符號右移 | Python沒有符號位,Java中可以使用此符號 |
上表列出的位運算子也可以進行復合賦值運算:
運算子 | Python示例 | 等價於 |
---|---|---|
& | x &= y | x = x & y |
| | x |= y | x = x | y |
^ | x ^= y | x = x ^ y |
<< | x <<= 1 | x = x << 1 |
>> | x >>= 1 | x = x >> 1 |
>>> | x >>>= 1 | / |
注意與邏輯運算子的區別,邏輯與&&
和邏輯或||
具有短路求值特性,比如x && y
運算,如果x為false,則不會計算y;x || y
運算中,如果x為true,則不會運算y。
下面介紹這些位運算子的使用方法。
Python位運算
與 - &
按位與操作符就是按二進位制位進行"與"運算,兩位同時為1,結果為1,否則為0
>>> x = 6 >>> y = 12 >>> x & y 4 >>> bin(x) '0b110' >>> bin(y) '0b1100' >>> bin(x & y) '0b100'
或 - |
或操作符進行按位或,只要其中一個為1,結果為1。
>>> x = 6
>>> y = 12
>>> x | y
14
>>> bin(x)
'0b110'
>>> bin(y)
'0b1100'
>>> bin(x | y)
'0b1110'
非 - ~
非操作符就是取反操作:~x = -(x+1)
>>> x = 6
>>> ~6
-7
異或 - ^
異或也就是相同為0,不同為1:
>>> x = 6
>>> y = 12
>>> x ^ y
10
>>> bin(x)
'0b110'
>>> bin(y)
'0b1100'
>>> bin(x ^ y)
'0b1010'
異或操作的一些特點:
1、x ^ 0 = x
>>> x = 6
>>> x ^ 0
6
2、x ^ (-1) = ~x
>>> x = 6
>>> x ^ -1
-7
>>> ~x
-7
3、x ^ (~x) = -1
>>> x = 6
>>> x ^ (~x)
-1
4、x ^ x = 0
>>> x = 6
>>> x ^ x
0
5、交換兩個數
>>> x = 6
>>> y = 12
>>> z = x ^ y
>>> x ^ z
12
>>> y ^ z
6
6、結合律
x ^ y ^ z = x ^ (y ^ z) = (x ^ y) ^z
左移 - <<
按位左移操作符(<<)將其第一位向左移,在右邊補零。對於左移操作相當於將數字乘以2的n次冪:x << n = x * 2^n
。
>>> x = 6
>>> x << 1
12
>>> x << 2
24
>>> x << 3
48
注意在Python程式設計中,沒有必要使用移位操作來提高執行效率,因為Python編譯器已經優化了,使用移位操作反而降低了程式碼的可讀性。
右移 - >>
按位右移操作符(>>)和左移相反,它是向右移動,左邊補0。右移等價於:x >> n = floor(x / 2^n)
>>> x = 10
>>> x >> 1
5
>>> x >> 2
2
>>> x // 4
2
位運算其它應用
指定位置的位運算
- 將x 最右邊的n 位清零:x& (~0 << n)
- 獲取x 的第n 位值(0 或者1):(x >> n) & 1
- 獲取x 的第n 位的冪值:x& (1 <<n)
- 僅將第n 位置為1:x | (1 << n)
- 第n位取反:x ^ (1 << n)
- 僅將第n 位置為0:x & (~ (1 << n))
- 將x 最高位至第n 位(含)清零:x& ((1 << n) -1)
判斷奇偶
x % 2 == 1 —> (x & 1) == 1
x % 2 == 0 —> (x & 1) == 0
>>> x = 10
>>> x & 1
0
>>> x= 11
>>> x & 1
1
將最低位的1清零
>>> x = 10
>>> bin(x)
'0b1010'
>>> x & (x - 1)
8
>>> bin(8)
'0b1000'
>>>
得到最低位的1
>>> x = 10
>>> bin(x)
'0b1010'
>>> x & -x
2
清0
>>> x = 10
>>> x & ~x
0
如果x和y是集合,Python中,位運算子可用於集合的運算,詳見演算法筆記:雜湊表、對映和集合。
歡迎關注公眾號:「測試開發小記」及時接收最新技術文章!