Python 位操作(Bitwise Operation) 詳解
什麼是位操作
計算機中的數字都是用二進位形式表示的,在python裡面,給數字加上前綴 0b 表示是二進位數字,如下示例,左邊是二進位,右邊是
0b1 => 1n0b10 => 2n0b1111 => 15n
類似的,python當中的十六進位和八進位數字的前綴分別為 0x 和 0,下面的例子中右邊是十進位
# 十六進位n0x10 => 16n0xff => 255n# 八進位n010 => 8n017 => 15n
二進位數字有自己的特殊運算,是對每一位數字分別進行的操作,所以叫做位操作,Python共有以下幾種位操作符:
x >> y # 返回 x 向右移 y 位得到的結果nx << y # 返回 x 向左移 y 位得到的結果nx & y # 且操作,返回結果的每一位是 x 和 y 中對應位做 and 運算的結果,只有 1 and 1 = 1,其他情況位0nx | y # 或操作,返回結果的每一位是 x 和 y 中對應位做 or 運算的結果,只有 0 or 0 = 0,其他情況位1n~x # 反轉操作,對 x 求的每一位求補,只需記住結果是 -x - 1nx ^ y # 或非運算,如果 y 對應位是0,那麼結果位取 x 的對應位,如果 y 對應位是1,取 x 對應位的補n
位操作詳解
左移和右移操作
顧名思義,左移和右移的意思就是把位數整體向左或者向右移動若干位。比如1111向右移一位就變成了0111,原來沒有的位自動填0,超出範圍的位捨棄掉。下面再看幾個例子:
0b1111 >> 1 = 0b111 = 7n0b1010 << 2 = 0b101000 = 40n0b111111 >> 3 = 0b111 = 7n0b1 << 4 = 0b10000 = 16n
向右移1位可以看成除以2,向左移一位可以看成乘以2。移動n位可以看成乘以或者除以2的n次方。
8 >> 2 <=> 8 / 2 / 2 <=> 0b1000 >> 2 = 0b10 = 2n8 << 2 <=> 8 * 2 * 2 <=> 0b1000 << 2 = 0b100000 = 32 n
且操作 &
對於單個位的且操作
1 & 1 = 1
1 & 0 = 0 & 1 = 0 & 0 = 0
兩個數字的且操作就是對每一位進行且操作取結果
0b1 & 0b0 = 0n0b1111 & 0b1010 = 0b1010 = 10n0b1010 & 0b1100 = 0b1000 = 8n
或操作 |
對於單個位的或操作
1 | 0 = 0 | 1 = 1 | 1 = 1
0 | 0 = 0
兩個數字的或操作就是對每一位進行或操作取結果
0b1 | 0b0 = 0b1 =1n0b1000 | 0b0111 = 0b1111 = 15n0b1010 | 0b1100 = 0b1110 = 14n
反轉操作 ~
python的反轉操作只接受一個參數n,n必須是整數,效果是對n的內部表示的每一位求補,運算結果位
~8 = -9n
一些同學可能會疑惑,~8不應該是 ~0b1000 = 0b0001 = 1 才對嗎。事情是這樣的,計算機在內部表示負整數的時候用的是正數的補,比如 0b0001 是1,它的補是 0b1110,這個時候0b1110 在計算機內部不是7,而是-1。 這樣一來,可以推導出來~n的結果是 。不過你自己寫的0b1111在這個語境下並不是一個負數,所以結果仍是15。
或非操作 ^
對於 x ^ y,如果y的位是0,那麼取x的原始值,如果y的位是1,那麼取x此位的補,例如
0b1111 ^ 0b0101 = 0b1010n0b1111 ^ 0b1 = 0b1110 # 自動填0n
推薦閱讀:
※通關這12個遊戲,你就是編程大神,我不是開玩笑!
※你用過印象筆記嗎?一個奇葩需求的另類玩法
※github菜鳥初體驗(1)——下載/提交代碼