本文 AI 產出,尚未審核
Python 課程 – 運算子(Operators)
主題:位元運算子(& | ^ << >> ~)
簡介
在日常的 Python 程式開發中,位元運算子 常被用來處理底層資料、效能敏感的演算或是與硬體、網路協定直接互動的情境。雖然它們的語法看起來簡潔,但背後涉及的二進位概念卻是許多新手容易忽略的關鍵。掌握 &、|、^、<<、>>、~ 這六種運算子,不僅可以讓你在 資料壓縮、加密、圖形處理 等領域寫出更高效的程式,也能幫助你在除錯時快速定位錯誤的位元配置。
本篇文章將以 淺顯易懂 的方式說明每個位元運算子的作用、使用時機與常見陷阱,並提供實務範例,讓你從「只會算」變成「會用」的 Python 開發者。
核心概念
1. 基本概念:什麼是位元?
- 位元(bit) 是電腦最小的資訊單位,值只能是
0或1。 - 位元運算 直接在二進位層面上操作,速度往往比算術運算快。
- 在 Python 中,整數(
int)會自動以二進位形式儲存,無需額外宣告。
小提醒:Python 的整數是 無限制長度(big‑int),所以位元運算不會因為超出 32/64 位元而溢位,但會受到記憶體限制。
2. 位元運算子一覽
| 運算子 | 名稱 | 功能說明 |
|---|---|---|
& |
位元 AND | 兩個位元皆為 1 時結果才為 1 |
| ` | ` | 位元 OR |
^ |
位元 XOR | 兩個位元不同時結果為 1(相同則為 0) |
~ |
位元 NOT | 逐位元取反(補數表示法) |
<< |
左移 | 數值左移 n 位,相當於乘以 2ⁿ |
>> |
右移 | 數值右移 n 位,相當於除以 2ⁿ(向下取整) |
3. 程式碼範例
以下範例皆以 Python 3 為基礎,使用 ````python` 標記區塊。
3.1 位元 AND (&) – 檢查特定位元
# 假設我們想檢查一個數字的第 3 個位元(從右往左,0 為最右)
value = 0b101101 # 二進位 45
mask = 0b001000 # 只保留第 3 位元
result = value & mask
print(f"第 3 位元是否為 1?{'是' if result else '否'}")
# 輸出: 第 3 位元是否為 1?是
說明:
mask只在第 3 位元為1,&會把其他位元清零,結果非零即代表該位元被設定。
3.2 位元 OR (|) – 設定特定位元
# 將第 0 位元(最低位)設為 1
value = 0b110100 # 52
mask = 0b000001 # 第 0 位元
new_value = value | mask
print(bin(new_value)) # 0b110101
3.3 位元 XOR (^) – 翻轉特定位元
# 翻轉第 2 位元
value = 0b100110 # 38
mask = 0b000100 # 第 2 位元
flipped = value ^ mask
print(bin(flipped)) # 0b100010
3.4 位元 NOT (~) – 取反與補數
# ~ 在 Python 中回傳的是「二的補數」形式
a = 0b001011 # 11
not_a = ~a
print(not_a) # -12
print(bin(not_a & 0b111111)) # 只看 6 位元時的結果:0b110100
小技巧:若只想保留固定寬度的位元,可再用
&取掩碼(如上例的& 0b111111)。
3.5 左移 (<<) – 快速乘以 2 的次方
# 計算 7 * 2^3
value = 7
shifted = value << 3 # 等於 7 * 8
print(shifted) # 56
3.6 右移 (>>) – 快速除以 2 的次方
# 計算 200 // 2^4
value = 200
shifted = value >> 4 # 等於 200 // 16
print(shifted) # 12
常見陷阱與最佳實踐
| 陷阱 | 說明 | 建議的最佳實踐 |
|---|---|---|
| 負數位元運算的結果與預期不符 | Python 使用 無限長度的二的補數,直接 ~ 負數會得到負值。 |
若需要限定寬度(如 8 位元),先使用掩碼 & 0xFF 再取反。 |
| 左移超過位元寬度 | 左移過度會產生非常大的整數,可能導致記憶體浪費。 | 在硬體相關程式中,先確認目標位寬(如 32 位),再使用 & ((1 << width) - 1) 截斷。 |
| 混用位元與布林運算子 | and、or 會先把值轉為布林,可能造成意外的短路行為。 |
使用 &、` |
| 忘記掩碼導致溢位 | 位元合併(` | `)時若未限制寬度,可能把舊資料的高位保留下來。 |
| 右移負數 | 右移負數在 Python 會保持符號位(算術右移),結果可能與預期不同。 | 若需要邏輯右移(填 0),先把負數轉為無符號形式:(value % (1 << width)) >> n。 |
實際應用場景
旗標(Flag)設計
- 常見於設定檔、API 回傳或硬體控制,使用位元 AND/OR 快速檢查或切換功能。
READ = 0b0001 WRITE = 0b0010 EXEC = 0b0100 permission = READ | WRITE # 同時具有讀寫權限 if permission & EXEC: print("可執行")位元壓縮
- 將多個布林值壓縮成單一整數,節省記憶體或網路傳輸量。
# 把 8 個布林值壓縮成 1 個 byte bits = [True, False, True, True, False, False, True, False] byte = sum((1 << i) if b else 0 for i, b in enumerate(bits))密碼雜湊與簡易加密
- XOR 常被用於「一次性密碼」或簡易混淆。
def xor_cipher(data: bytes, key: int) -> bytes: return bytes(b ^ key for b in data)圖形與影像處理
- 透過位元遮罩(mask)快速抽取或修改 RGB 通道。
# 把 24 位元顏色的紅色通道設為 0 color = 0xFF3366 # R=255, G=51, B=102 mask = 0x00FFFF # 保留低 16 位 (G,B) new_color = color & mask網路協定與位元欄位
- 解析 IPv4、TCP 標頭時,需要使用位元移位與遮罩來取得欄位值。
總結
位元運算子看似簡單,卻是 底層效能優化、資料壓縮、硬體介面 等領域不可或缺的工具。掌握 &、|、^、<<、>>、~ 的語意與正確使用方式,你可以:
- 用 AND 快速檢查特定位元
- 用 OR 設定或合併旗標
- 用 XOR 實作簡易加解密或翻轉位元
- 用 左/右移 取代乘除 2 的次方,提高執行效能
- 用 NOT 產生補數,搭配掩碼完成固定寬度的取反
在實務開發時,務必留意 負數、位寬與掩碼 這幾個常見陷阱,並遵守「先掩碼、後運算」的最佳實踐。未來不論是開發嵌入式系統、網路工具或是大型資料處理程式,位元運算都能為你的程式碼帶來 更高的可讀性與效能。
祝你在 Python 的位元世界裡玩得開心,寫出更「位」的程式! 🚀