# Python的位元運算
首先要聲明三點
1. 如果只是要考APCS,使用Python其實**不太需要位元運算**
2. 如果要轉C++的必須要學,原因我不多說
3. 位元運算在更高階的比賽**一定要會**
所謂位元運算,就是對二進制作運算,我們可以從當中得到一些有趣的特性
## AND(&)
在位元運算的and跟一般運算很相似,但是它是針對每一個二進位的數字做and運算
比如我有兩個二進位數字,只要兩個都為 1 就是 1
1111
0101
我們要同時看上跟下的數字,比如第一行,上為 1 下為 0 ,那 1 and 0 就是 0
後面以此類推,最後得到答案就是0101,用十進位表示就是 5
```python=
b = 15 # 1111
c = 5 # 0101 用成四位是因為比較好觀察
# b & c 0101 == 答案 == 5
print(b & c) # 0101
```
## OR(|)
or跟前面的and一樣,都是用相同方式,但是**只要有一個為 1** 答案就是 1
```python=
b = 15 # 1111
c = 5 # 0101 用成四位是因為比較好觀察
# b | c 1111 == 答案 == 15
print(b | c) # 1111
```
## XOR(^)
這個比較少見,或者根本沒見過,其實它就是**只能有一個為 1**
比如說 1 xor 1 就是 0 ,因為有兩個 1 , 0 跟 0 也是一樣
```python=
b = 15 # 1111
c = 5 # 0101 用成四位是因為比較好觀察
# b ^ c 1010 == 答案 == 10
print(b ^ c) # 1010
```
## not(~)
這個比較難理解,有興趣的可以去查二補數
比如15 (二進位1111),我們可以看成 01111,然後再做not運算
not運算就跟一般的not一樣, 1 變成 0 , 0 變成 1
那麼01111 -> 10000 (-16)
```python=
c = 15 # 01111 用成五位
# ~c 10000 == 答案 == -16
print(~c) # 10000
```
## 左移(<<)
這個比較有意思,就是把二進式從右邊多補n個0
比如15(1111),多加一個0會變成30(11110)
在正整數的時候相當於 × 2^n^
```python=
c = 15 # 1111
# c<<1 11110 == 答案 == 30
print(c<<1) # 11110
```
## 右移(<<)
這個跟剛剛一樣,但是是把二進式從右邊移除n個數
比如15(1111),移除一個數會變成7(111)
在正整數的python=時候相當於 // 2^n^
```python=
c = 15 # 1111
# c>>1 111 == 答案 == 7
print(c>>1) # 111
```
## 實用的性質
介紹完剛剛的運算方式,我們可以得到幾個比較有用的性質
### 判斷奇數偶數
用and運算可以快速判斷,只要跟 1 做and位元運算
那麼只要看最右邊的數字是 1 還是 0 就知道奇數偶數
### A變成-A
用not運算可以快速轉換正負,只要~A+1就會等於-A
### A × 2 或 A // 2
在二分搜的時候常常用到,用左右移就可以達成
```python=
a >>= 1 # // 2
a <<= 1 # × 2
```
### A B 對調數字
在python當中用 a,b = b,a 就好
如果是C++等比較不方便的語言,通常都是用多一個變數tmp去協助
但是用xor運算能夠省去tmp的運用
```python=
a = a^b
b = a^b
a = a^b
```
如果把它換成二進制就不難理解了
比如下面這個例子
1111 a
0101 b
先做一次 xor 運算
1010 a
0101 b
再做一次 xor 運算
1010 a
1111 b
會發現此時b已經變成a了
最後再做一次位元運算
0101 a
1111 b
a b 就對調了,如果想要徹底理解的話,我有在下面證明,不想看的可以自動忽略
證明 :
首先要知道,xor有五個性質
1. A xor B == B xor A (交換律)
2. A xor B xor C == A xor (B xor C) (結合律)
3. A xor A == 0
4. if A xor B == C -> A xor C == B
5. A xor 0 == A
那麼之前對調的例子就知道
t = a ^ b
b = t ^ b == a ^ b ^ b == a ^ ( b ^ b ) == a ^ 0 == a
a = t ^ b == a ^ b ^ a == ( a ^ a ) ^ b == 0 ^ b == b
所以可以對調
## 練習題
[a621. 1. Powers of Two](https://zerojudge.tw/ShowProblem?problemid=a621)
二進位的運用也就是位元運算的運用
___
本篇到此結束~