本文 AI 產出,尚未審核

Python 課程 – 運算子(Operators)

主題:位元運算子(& | ^ << >> ~)


簡介

在日常的 Python 程式開發中,位元運算子 常被用來處理底層資料、效能敏感的演算或是與硬體、網路協定直接互動的情境。雖然它們的語法看起來簡潔,但背後涉及的二進位概念卻是許多新手容易忽略的關鍵。掌握 &、|、^、<<、>>、~ 這六種運算子,不僅可以讓你在 資料壓縮、加密、圖形處理 等領域寫出更高效的程式,也能幫助你在除錯時快速定位錯誤的位元配置。

本篇文章將以 淺顯易懂 的方式說明每個位元運算子的作用、使用時機與常見陷阱,並提供實務範例,讓你從「只會算」變成「會用」的 Python 開發者。


核心概念

1. 基本概念:什麼是位元?

  • 位元(bit) 是電腦最小的資訊單位,值只能是 01
  • 位元運算 直接在二進位層面上操作,速度往往比算術運算快。
  • 在 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) 截斷。
混用位元與布林運算子 andor 會先把值轉為布林,可能造成意外的短路行為。 使用 &、`
忘記掩碼導致溢位 位元合併(` `)時若未限制寬度,可能把舊資料的高位保留下來。
右移負數 右移負數在 Python 會保持符號位(算術右移),結果可能與預期不同。 若需要邏輯右移(填 0),先把負數轉為無符號形式:(value % (1 << width)) >> n

實際應用場景

  1. 旗標(Flag)設計

    • 常見於設定檔、API 回傳或硬體控制,使用位元 AND/OR 快速檢查或切換功能。
    READ   = 0b0001
    WRITE  = 0b0010
    EXEC   = 0b0100
    
    permission = READ | WRITE   # 同時具有讀寫權限
    if permission & EXEC:
        print("可執行")
    
  2. 位元壓縮

    • 將多個布林值壓縮成單一整數,節省記憶體或網路傳輸量。
    # 把 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))
    
  3. 密碼雜湊與簡易加密

    • XOR 常被用於「一次性密碼」或簡易混淆。
    def xor_cipher(data: bytes, key: int) -> bytes:
        return bytes(b ^ key for b in data)
    
  4. 圖形與影像處理

    • 透過位元遮罩(mask)快速抽取或修改 RGB 通道。
    # 把 24 位元顏色的紅色通道設為 0
    color = 0xFF3366   # R=255, G=51, B=102
    mask  = 0x00FFFF   # 保留低 16 位 (G,B)
    new_color = color & mask
    
  5. 網路協定與位元欄位

    • 解析 IPv4、TCP 標頭時,需要使用位元移位與遮罩來取得欄位值。

總結

位元運算子看似簡單,卻是 底層效能優化資料壓縮硬體介面 等領域不可或缺的工具。掌握 &、|、^、<<、>>、~ 的語意與正確使用方式,你可以:

  • AND 快速檢查特定位元
  • OR 設定或合併旗標
  • XOR 實作簡易加解密或翻轉位元
  • 左/右移 取代乘除 2 的次方,提高執行效能
  • NOT 產生補數,搭配掩碼完成固定寬度的取反

在實務開發時,務必留意 負數、位寬與掩碼 這幾個常見陷阱,並遵守「先掩碼、後運算」的最佳實踐。未來不論是開發嵌入式系統、網路工具或是大型資料處理程式,位元運算都能為你的程式碼帶來 更高的可讀性與效能

祝你在 Python 的位元世界裡玩得開心,寫出更「位」的程式! 🚀