Python 中的位元運算(Bitwise Operations)詳解:新手指南

更新日期: 2024 年 9 月 23 日

在 Python 編程中,位元運算是一種直接對二進位數位(bits)進行操作的技巧。

雖然在高階語言中不常見,但位元運算在許多領域,如系統編程、加密、網路編程和性能優化中,扮演著關鍵角色。

對於剛開始學習 Python 的新手來說,理解位元運算的概念和用法,將大大拓展你的編程技能。

本文將深入介紹 Python 中的位元運算,並提供豐富的示例,幫助你在實際開發中靈活運用。


什麼是位元運算?

位元運算是對整數的二進位表示形式,進行操作的運算。

在計算機系統中,數據以二進位的形式存儲和處理,位元運算允許我們直接操縱這些二進位數位,從而達到高效的計算和控制。


位元運算的基本概念

在進入實際操作之前,讓我們先了解一些基本概念。

二進位表示

整數在內部以二進位形式存儲。例如:

  • 5 的二進位表示為 0000 0101
  • 3 的二進位表示為 0000 0011

位元位置

  • 最高有效位(Most Significant Bit, MSB):最左邊的位元,表示數值的符號位(在有符號整數中)。
  • 最低有效位(Least Significant Bit, LSB):最右邊的位元,表示數值的最小單位。

位元運算符的詳細解釋

位元與(&)

規則: 對應位都為 1,結果為 1;否則為 0。

示例:

a = 5       # 二進位:0000 0101
b = 3       # 二進位:0000 0011

result = a & b
print(result)  # 輸出:1

解釋:

   0000 0101 (5)
&  0000 0011 (3)
--------------
   0000 0001 (1)

位元或(|)

規則: 對應位只要有一個為 1,結果為 1。

示例:

a = 5       # 二進位:0000 0101
b = 3       # 二進位:0000 0011

result = a | b
print(result)  # 輸出:7

解釋:

   0000 0101 (5)
|  0000 0011 (3)
--------------
   0000 0111 (7)

位元異或(^)

規則: 對應位不同,結果為 1;相同為 0

示例:

a = 5       # 二進位:0000 0101
b = 3       # 二進位:0000 0011

result = a ^ b
print(result)  # 輸出:6

解釋:

   0000 0101 (5)
^  0000 0011 (3)
--------------
   0000 0110 (6)

位元取反(~)

規則: 將位元取反,0 變 1,1 變 0。

注意: 在 Python 中,整數是有符號的,因此取反操作會影響符號位。

示例:

a = 5       # 二進位:0000 0101

result = ~a
print(result)  # 輸出:-6

解釋:

  • 取反後的二進位為 1111 1010,這是以二補數形式表示的 -6。

位元左移(<<)

規則: 將位元向左移動指定的位數,右側補 0。

示例:

a = 5       # 二進位:0000 0101

result = a << 1
print(result)  # 輸出:10

解釋:

原始位元: 0000 0101 (5)
左移一位: 0000 1010 (10)

位元右移(>>)

規則: 將位元向右移動指定的位數,左側根據符號位補 0 或 1(Python 中為數學右移,總是補 0)。

示例:

a = 5       # 二進位:0000 0101

result = a >> 1
print(result)  # 輸出:2

解釋:

原始位元: 0000 0101 (5)
右移一位: 0000 0010 (2)

位元運算符統整

Python 提供了以下幾種位元運算符:

運算符名稱說明
&位元與對應位都為 1,結果為 1
|位元或對應位只要有一個為 1,結果為 1
^位元異或對應位不相同,結果為 1
~位元取反對位元取反
<<位元左移將位元向左移動指定的位數
>>位元右移將位元向右移動指定的位數

位元運算的實際應用

設置、清除和切換位元

設置特定位元為 1

def set_bit(value, bit):
    return value | (1 << bit)

a = 0       # 二進位:0000 0000
a = set_bit(a, 2)
print(a)    # 輸出:4

清除特定位元為 0

def clear_bit(value, bit):
    return value & ~(1 << bit)

a = 7       # 二進位:0000 0111
a = clear_bit(a, 1)
print(a)    # 輸出:5

切換特定位元

def toggle_bit(value, bit):
    return value ^ (1 << bit)

a = 5       # 二進位:0000 0101
a = toggle_bit(a, 0)
print(a)    # 輸出:4

檢查特定位元

def check_bit(value, bit):
    return (value & (1 << bit)) != 0

a = 5       # 二進位:0000 0101
print(check_bit(a, 0))  # 輸出:True
print(check_bit(a, 1))  # 輸出:False

位元遮罩(Bitmask)

位元遮罩常用於從數據中提取特定位元的值。

示例:

value = 0b10101100  # 二進位:1010 1100

# 提取中間的 4 位(位元 2 到 5)
mask = 0b00111100
result = (value & mask) >> 2
print(bin(result))  # 輸出:0b1011

數據壓縮與解壓

通過位元運算,可以將多個小的數據壓縮到一個整數中,或從中提取。

示例:

# 將兩個 4 位的數字壓縮到一個 8 位的整數中
def compress(n1, n2):
    return (n1 << 4) | n2

def decompress(value):
    n1 = (value >> 4) & 0xF
    n2 = value & 0xF
    return n1, n2

compressed = compress(0b1010, 0b1100)
print(bin(compressed))  # 輸出:0b10101100

n1, n2 = decompress(compressed)
print(bin(n1), bin(n2))  # 輸出:0b1010 0b1100

位元運算與布林代數

位元運算與布林代數密切相關,可以用於實現邏輯電路的模擬。

真值表

ABA & BA | BA ^ B
00000
01011
10011
11110

例子:模擬簡單的邏輯閘

# AND 閘
def AND(a, b):
    return a & b

# OR 閘
def OR(a, b):
    return a | b

# XOR 閘
def XOR(a, b):
    return a ^ b

print(AND(1, 0))  # 輸出:0
print(OR(1, 0))   # 輸出:1
print(XOR(1, 0))  # 輸出:1

位元運算的注意事項

符號位與補數

  • 正數 的二進位表示與其絕對值相同。
  • 負數 在 Python 中以二補數形式表示,需要注意取反和移位操作的結果。

優先級

位元運算符的優先級較低,建議使用括號明確計算順序。

  • 優先級從高到低:
  ~
  <<
  >>
  &
  ^
  |

示例:

a = 5 | 3 & 2
# 實際計算為:
# 5 | (3 & 2)

位元運算與其他資料型態的轉換

將整數轉換為二進位字串

num = 10
binary_str = bin(num)
print(binary_str)  # 輸出:0b1010

將二進位字串轉換為整數

binary_str = '0b1010'
num = int(binary_str, 2)
print(num)  # 輸出:10

實際應用案例

權限控制

在系統中,常用位元來表示權限標誌。

示例:

# 定義權限
READ = 0b001
WRITE = 0b010
EXECUTE = 0b100

# 賦予權限
permission = READ | WRITE

# 檢查權限
def has_permission(perms, perm):
    return (perms & perm) == perm

print(has_permission(permission, READ))     # 輸出:True
print(has_permission(permission, EXECUTE))  # 輸出:False

效能優化

在需要高效計算的情況下,位元運算可以提供更快的速度。

示例:

# 檢查一個數是否為 2 的冪
def is_power_of_two(n):
    return n > 0 and (n & (n - 1)) == 0

print(is_power_of_two(8))   # 輸出:True
print(is_power_of_two(10))  # 輸出:False

結論

位元運算在 Python 中雖然不如其他高階特性常用,但在特定領域中扮演著不可或缺的角色。

透過理解和掌握位元運算,你將能夠在系統編程、性能優化和底層算法中運用自如。

建議新手多加練習,嘗試在實際項目中應用位元運算,加深理解。


延伸閱讀

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *