# python 位運算
## 進位制基礎
在 Python 中,**`0b`** 是用來表示**二進制數字**的前綴。任何以 `0b` 開頭的數字字串,Python 都會認為是二進制格式,並將其轉換為十進制數進行存儲。
---
### **`0b` 的含義**
- **`0b`** 是二進制數的標誌,告訴 Python 該數字是用 **2 進制** 表示的。
- **二進制數**(Binary Numbers):僅由 0 和 1 組成。
例如:
- `0b101` 表示二進制數字,等於十進制的 `5`。
- `0b1111` 表示二進制數字,等於十進制的 `15`。
---
### **如何使用 `0b`**
#### 1. **直接使用二進制數字**
你可以用 `0b` 前綴來定義一個二進制數字:
```python
x = 0b1010 # 二進制 1010 表示十進制的 10
y = 0b1111 # 二進制 1111 表示十進制的 15
print(x) # 輸出 10
print(y) # 輸出 15
```
#### 2. **將二進制字串轉換為整數**
使用 `int()` 函數,將帶有 `0b` 的二進制字串轉換為十進制整數:
```python
binary_string = "0b1101" # 二進制字串
number = int(binary_string, 2) # 指定基數為 2
print(number) # 輸出 13
```
不帶有 `0b` 的二進制字串也可以用同樣方法轉換為十進位制整數:
```python
binary_string = "1101" # 二進制字串
number = int(binary_string, 2) # 指定基數為 2
print(number) # 輸出 13
```
#### 3. **將整數轉換為二進制表示**
使用內建的 `bin()` 函數將整數轉換為二進制字串:
```python
num = 13
binary_representation = bin(num) # 輸出 '0b1101'
print(binary_representation)
```
---
### **`0b` 的運算特性**
#### 1. **支持位運算**
以 `0b` 表示的數字完全可以參與位運算,例如:
```python
a = 0b1010 # 10
b = 0b1100 # 12
# 位與
print(bin(a & b)) # '0b1000',即十進制 8
# 位或
print(bin(a | b)) # '0b1110',即十進制 14
# 位異或
print(bin(a ^ b)) # '0b0110',即十進制 6
```
#### 2. **與十進制數混合運算**
`0b` 表示的二進制數等價於普通整數,可以與其他數字進行普通數學運算:
```python
a = 0b101 # 5
b = 2
print(a + b) # 7
print(a * b) # 10
```
---
### **常見應用場景**
#### 1. **處理二進制數據**
例如,處理位元標誌或硬體相關數據(如設定開關):
```python
flags = 0b1010 # 假設這是一組二進制標誌
if flags & 0b1000: # 檢查第三個位是否為 1
print("第三個位是開啟的")
```
#### 2. **進制轉換**
配合 `int()`、`bin()`、`oct()`、`hex()`,可以方便地在不同進制間轉換:
```python
num = 0b1011 # 二進制
print(oct(num)) # 八進制,輸出 '0o13'
print(hex(num)) # 十六進制,輸出 '0xb'
```
#### 3. **表示大數**
二進制可用來表示非常大的數,例如:
```python
large_binary = 0b1010101010101010101010101010
print(large_binary) # 輸出十進制的數字 2863311530
```
---
### **注意事項**
1. **`0b` 只是表示二進制數的前綴**:
- 在輸出格式中,`0b` 並非二進制內容的一部分。
- 若需僅獲取數值部分,可以用切片去掉:
```python
print(bin(10)[2:]) # 輸出 '1010'
```
2. **不能對非整數使用 `0b`**:
- 小數或浮點數不支持 `0b` 前綴。
3. **二進制運算可能需要手動補零**:
- 若需處理固定長度的二進制數,可用 `zfill()` 方法:
```python
binary = bin(5)[2:] # '101'
print(binary.zfill(8)) # '00000101'
```
---
### **總結**
- **`0b` 是 Python 表示二進制數字的前綴**。
- 它與 `bin()`、位運算等功能配合,可以方便地進行二進制數據處理。
## 位運算
位運算(Bitwise Operations)是處理二進制數字的一種操作,對應於電腦中數字的二進制表示。以下是 Python 中常見的位運算及其應用教學:
---
### 1. **常見的位運算符**
| 運算符 | 名稱 | 說明 |
|--------|------------------|------------------------------|
| `&` | 位與(AND) | 對應位都為 1 時,結果為 1 |
| `\|` | 位或(OR) | 對應位有一個為 1,結果為 1 |
| `^` | 位異或(XOR) | 對應位不同,結果為 1 |
| `~` | 位非(NOT) | 對應位取反 |
| `<<` | 左移 | 位元向左移動,低位補 0 |
| `>>` | 右移 | 位元向右移動,高位補 0 或符號位 |
---
### 2. **詳細說明與範例**
#### (1)位與 `&`
每個位元相對應地進行邏輯與運算:
```python
a = 0b1101 # 13
b = 0b1011 # 11
result = a & b
print(bin(result)) # 輸出:0b1001 (9)
```
#### (2)位或 `|`
每個位元相對應地進行邏輯或運算:
```python
a = 0b1101 # 13
b = 0b1011 # 11
result = a | b
print(bin(result)) # 輸出:0b1111 (15)
```
#### (3)位異或 `^`
每個位元相對應地進行邏輯異或運算(相同為 0,不同為 1):
```python
a = 0b1101 # 13
b = 0b1011 # 11
result = a ^ b
print(bin(result)) # 輸出:0b0110 (6)
```
#### (4)位非 `~`
將所有位元取反:
```python
a = 0b1101 # 13
result = ~a
print(bin(result)) # 輸出:-0b1110 (-14, 注意是補數表示法)
```
#### (5)左移 `<<`
將所有位元向左移動(相當於乘以 2 的次方):
```python
a = 0b0011 # 3
result = a << 2
print(bin(result)) # 輸出:0b1100 (12)
```
#### (6)右移 `>>`
將所有位元向右移動(相當於整除 2 的次方):
```python
a = 0b1100 # 12
result = a >> 2
print(bin(result)) # 輸出:0b0011 (3)
```
---
### 3. **位運算應用**
#### (1)檢查位是否為 1
檢查某個特定位是否為 1:
```python
a = 0b1011 # 11
bit_position = 2 # 從右往左數,索引從 0 開始
is_one = (a & (1 << bit_position)) != 0
print(is_one) # 輸出:True
```
#### (2)設置某一位為 1
將某個特定位設置為 1:
```python
a = 0b1011 # 11
bit_position = 1
result = a | (1 << bit_position)
print(bin(result)) # 輸出:0b1011 (不變)
```
#### (3)清除某一位為 0
將某個特定位設置為 0:
```python
a = 0b1011 # 11
bit_position = 3
result = a & ~(1 << bit_position)
print(bin(result)) # 輸出:0b0011 (3)
```
#### (4)切換某一位的值
將某個特定位從 1 切換為 0 或從 0 切換為 1:
```python
a = 0b1011 # 11
bit_position = 1
result = a ^ (1 << bit_position)
print(bin(result)) # 輸出:0b1001 (9)
```
---
### 應用:交換兩個變數的值
位運算可以用 **異或(XOR)運算** 在不使用第三個變數的情況下交換兩個變數的值。這是因為異或運算具有可逆性,且自反性讓相同的位操作可以還原數值。
以下是具體實現方式:
---
### 原理
假設有兩個變數 `a` 和 `b`:
1. `a = a ^ b`
2. `b = a ^ b`
3. `a = a ^ b`
**分析:**
- 第一步:`a` 保存了 `a ^ b`。
- 第二步:`b` 等於 `(a ^ b) ^ b`,由於 `b ^ b = 0`,所以 `b` 等於 `a`。
- 第三步:`a` 等於 `(a ^ b) ^ a`,由於 `a ^ a = 0`,所以 `a` 等於 `b`。
---
### 實作範例
```python
# 初始值
a = 5 # 0b0101
b = 3 # 0b0011
# 使用異或運算交換
a = a ^ b # a = 0b0101 ^ 0b0011 = 0b0110 (6)
b = a ^ b # b = 0b0110 ^ 0b0011 = 0b0101 (5)
a = a ^ b # a = 0b0110 ^ 0b0101 = 0b0011 (3)
print("a =", a) # 輸出:a = 3
print("b =", b) # 輸出:b = 5
```
---
### 適用條件
1. `a` 和 `b` 必須是可用位運算表示的類型(例如整數)。
2. 這種方法不適用於浮點數或非標準的數據類型。
---
### 應用場合
- 節省額外變數(尤其在嵌入式系統中)。
- 展示位運算的強大功能和靈活性。
### 4. **練習題**
1. 寫一個函數,計算兩數的位元相同位的 1 的數量。
2. 給定一個整數,將其所有位的值反轉。
3. 寫一個函數,計算某數的二進制表示中有多少個 1。