Bài viết này mình sẽ giới thiệu đến bạn về toán tử Bitwise trong Python, một khái niệm quan trọng trong lập trình. Chúng ta sẽ cùng tìm hiểu định nghĩa cơ bản về toán tử Bitwise và cách chúng hoạt động, đặc biệt là các thao tác logic như AND, OR, XOR, NOT trên các bit.
Toán tử Bitwise trong Python là gì?
Toán tử Bitwise (hay còn gọi là toán tử thao tác bit) trong Python thường được sử dụng để thực hiện các phép toán trên từng bit của các đối tượng kiểu số nguyên. Thay vì xem đối tượng như một số nguyên thông thường, Python sẽ xem nó như một chuỗi các bit (các số 0
hoặc 1
). Các phép toán sẽ được thực hiện trên từng bit trong chuỗi này.
Python có tổng cộng sáu toán tử Bitwise: &, |, ^, ~, <<
và >>
. Tất cả các toán tử này (ngoại trừ ~
) đều là toán tử hai ngôi, nghĩa là chúng hoạt động trên hai toán hạng. Mỗi toán hạng là một chữ số nhị phân (bit), có giá trị là 1
hoặc 0
.
Các toán tử Bitwise trong Python bao gồm:
- Toán tử AND Bitwise
- Toán tử OR Bitwise
- Toán tử XOR Bitwise
- Toán tử NOT Bitwise
- Toán tử dịch trái Bitwise
- Toán tử dịch phải Bitwise
Toán tử AND Bitwise trong Python
Toán tử AND Bitwise (&
) trong Python có phần tương tự như toán tử and logic. Toán tử này trả về True
(tương ứng với giá trị 1
) nếu cả hai toán hạng bit đều là 1
. Chúng ta có các kết quả như sau:
0 & 0 kết quả là 0
1 & 0 kết quả là 0
0 & 1 kết quả là 0
1 & 1 kết quả là 1
Khi sử dụng các số nguyên làm toán hạng, Python sẽ chuyển các số nguyên đó sang dạng nhị phân tương ứng, và sau đó thực hiện phép toán &
trên từng cặp bit tương ứng của hai số, bắt đầu từ bit có trọng số nhỏ nhất (ít quan trọng nhất) đến bit có trọng số lớn nhất.
Ví dụ về toán tử AND Bitwise trong Python
Chúng ta sẽ xét hai số nguyên, chẳng hạn 38
và 15
, gán chúng cho hai biến x
và y
tương ứng.
x = 38
y = 15
print ("x:", x, "y:", y, "x & y:", x & y)
Đoạn code trên sẽ cho kết quả:
x: 38 y: 15 x & y: 6
Để hiểu cách Python thực hiện phép toán, ta cần xem biểu diễn nhị phân của mỗi biến.
print ("x (nhị phân):", bin(x))
print ("y (nhị phân):", bin(y))
Đầu ra sẽ là:
x (nhị phân): 0b100110
y (nhị phân): 0b1111
Để dễ hình dung, chúng ta sẽ sử dụng định dạng 8-bit tiêu chuẩn cho mỗi số, nên x
sẽ là 00100110
và y
là 00001111
. Chúng ta sẽ thực hiện phép toán AND Bitwise trên từng cặp bit tương ứng:
0010 0110
& 0000 1111
———–
0000 0110
Giờ hãy chuyển kết quả nhị phân về dạng số nguyên. Chúng ta sẽ thu được số 6
, giống với kết quả đã thu được ở trên.
>>> int('00000110', 2)
6
Toán tử OR Bitwise trong Python
Ký hiệu |
(thường được gọi là “pipe”) là toán tử OR Bitwise
. Toán tử này thực hiện phép toán OR
trên từng bit của hai toán hạng. Nếu ít nhất một trong hai bit tương ứng của toán hạng là 1
, thì bit kết quả sẽ là 1
; ngược lại, bit kết quả sẽ là 0
.
Ta có thể tóm tắt hoạt động của toán tử OR Bitwise như sau:
0 | 0 kết quả là 0
0 | 1 kết quả là 1
1 | 0 kết quả là 1
1 | 1 kết quả là 1
Toán tử OR Bitwise hoạt động ở cấp độ bit, có nghĩa là các toán hạng trước khi thực hiện phép toán sẽ được biểu diễn ở dạng nhị phân (binary). Mỗi bit trong biểu diễn nhị phân của hai toán hạng sẽ được so sánh. Nếu bit nào là 1
, kết quả cuối cùng cho bit đó sẽ là 1
, và 0
trong các trường hợp còn lại
Ví dụ về toán tử OR Bitwise trong Python
Ví dụ với hai số a = 60
và b = 13
. Kết quả của phép toán OR Bitwise a | b
sẽ là 61
. Để hiểu rõ điều này, chúng ta cùng xem qua ví dụ dưới đây:
a = 60
b = 13
print ("a:", a, "b:", b, "a|b:", a | b)
print ("a:", bin(a))
print ("b:", bin(b))
Kết quả thực thi:
a: 60 b: 13 a|b: 61
a: 0b111100
b: 0b1101
Để thực hiện phép toán OR Bitwise một cách thủ công, chúng ta cần biểu diễn hai số ở dạng nhị phân với cùng số bit (ví dụ: 8 bit):
0011 1100 (60 ở dạng nhị phân 8 bit)
|
0000 1101 (13 ở dạng nhị phân 8 bit)
———–
0011 1101 (Kết quả phép OR Bitwise)
So sánh từng cặp bit tương ứng, ta thấy rằng:
- Ở các vị trí mà ít nhất một trong hai bit là
1
(ví dụ như vị trí thứ3, 4, 5, 6, 7
tính từ phải qua) thì kết quả bit là 1. - Ở các vị trí mà cả hai bit đều là
0
(ví dụ bit thứ0, 1
tính từ phải qua) thì kết quả bit là0
.
Chuyển số nhị phân 00111101
về dạng thập phân, ta có:
>>> int('00111101', 2)
61
Như vậy, kết quả của phép toán a | b (60 | 13)
là 61
, hoàn toàn trùng khớp với kết quả của chương trình Python.
Toán tử XOR Bitwise trong Python
XOR là viết tắt của “exclusive OR” (hoặc loại trừ) là kết quả của phép toán OR trên hai bit sẽ là 1
, nếu chỉ có một trong hai bit là 1
. Nếu cả hai bit đều là 0
, hoặc cả hai bit đều là 1
, kết quả sẽ là 0
. Cụ thể như sau:
0 ^ 0 kết quả là 0
0 ^ 1 kết quả là 1
1 ^ 0 kết quả là 1
1 ^ 1 kết quả là 0
Ví dụ về toán tử XOR Bitwise trong Python
Ví dụ sau sẽ cho bạn thấy cách toán tử XOR hoạt động trên hai số nguyên, sử dụng các giá trị a=42
và b=27
:
a = 42
b = 27
print ("a:", a, "b:", b, "a^b:", a^b)
Đoạn code trên sẽ in ra kết quả:
a: 42 b: 27 a^b: 19
Bây giờ chúng ta hãy xem chi tiết cách phép toán XOR hoạt động trên các bit nhị phân:
- Số 42 trong hệ nhị phân là 00101010
- Số 27 trong hệ nhị phân là 00011011
Thực hiện phép toán XOR theo từng bit:
0010 1010
^
0001 1011
-----------
0001 0001
Kết quả là:
00010011
Hàm int()
sẽ chuyển 00010011
từ dạng chuỗi biểu diễn nhị phân sang dạng số nguyên và cho kết quả là 19
.
print(int('00010011', 2))
Kết quả là:
19
Toán tử NOT Bitwise trong Python
Toán tử NOT Bitwise (~
) là một phép toán tương đương ở mức bit của toán tử NOT logic. Toán tử này đảo ngược từng bit của một số nguyên: bit 1
sẽ chuyển thành bit 0
, và bit 0
sẽ chuyển thành bit 1
. Kết quả trả về là số bù (complement) của số ban đầu. Python sử dụng phương pháp bù 2.
Đối với số nguyên dương, số bù được tính đơn giản bằng cách đảo ngược các bit. Với số âm -x
, số bù được biểu diễn bằng cách lấy mẫu bit của số (x - 1
) sau đó đảo ngược tất cả các bit (bit 1
thành bit 0
và bit 0
thành bit 1
). Vì thế (với biểu diễn 8
bit):
-1
là số bù của (1 - 1
) = số bù của0
= “11111111
“.-10
là số bù của (10 - 1
) = số bù của9
= số bù của “00001001
” = “11110110
“.
Lưu ý: Cách biểu diễn số âm bằng bù 2 là một khái niệm quan trọng trong cách máy tính lưu trữ và xử lý số nguyên. Tuy nhiên, bạn không cần phải đi sâu vào chi tiết quá phức tạp nếu mới bắt đầu học Python. Điều quan trọng là hiểu rằng toán tử ~ sẽ đảo ngược tất cả các bit của một số.
Ví dụ về toán tử NOT Bitwise trong Python
Ví dụ, với a = 60
, số bù của a sẽ là:
a = 60
print ("a:", a, "~a:", ~a)
Đoạn code trên sẽ cho kết quả như sau:
a: 60 ~a: -61
Toán tử dịch trái bit trong Python
Toán tử dịch trái bit (<<
) trong Python thực hiện việc dịch chuyển các bit trong biểu diễn nhị phân của một số sang trái một số lượng vị trí nhất định. Số lượng vị trí cần dịch chuyển được chỉ định ở phía bên phải của ký hiệu <<
. Vì vậy, biểu thức x << 2
có nghĩa là dịch chuyển toàn bộ các bit trong biểu diễn nhị phân của x
sang trái 2 vị trí.
Ví dụ về toán tử dịch trái bit
Dưới đây là một ví dụ về phép dịch trái bit trên số 60
:
a=60
print ("a:",a, "a<<2:", a<<2)
Đoạn code trên sẽ cho ra kết quả như sau:
a: 60 a<<2: 240
Hãy xem xét biểu diễn nhị phân của số 60
và thực hiện dịch trái 2 bit:
0011 1100 (biểu diễn nhị phân của 60)
<< 2 (dịch trái 2 bit)
—————-
1111 0000 (kết quả sau khi dịch)
Vậy, điều gì đã xảy ra? Để hiểu được kết quả này, ta sẽ cùng xem xét biểu diễn nhị phân của số 60
và thực hiện dịch trái 2 bit: Biểu diễn nhị phân của 60
là 0011 1100
Thực hiện dịch trái 2 bit:
0011 1100
<< 2
————-
1111 0000
Kết quả của việc dịch trái 2 bit là 1111 0000
. Chuyển biểu diễn nhị phân này sang dạng số nguyên, ta được kết quả là 240
. Chúng ta có thể sử dụng hàm int()
trong Python để kiểm tra kết quả này.
>>> int('11110000', 2)
240
Toán tử dịch phải bit trong Python
Toán tử dịch phải bit (>>
) trong Python thực hiện việc dịch các bit có trọng số nhỏ hơn về bên phải. Số bit dịch đi được xác định bởi số nằm bên phải của ký hiệu >>
. Vì vậy, khi viết x >> 2
, điều đó có nghĩa là ta đang dịch hai bit trong biểu diễn nhị phân của x về bên phải.
Ví dụ về toán tử dịch phải bit trong Python
Ví dụ dịch phải bit số 60
:
a = 60
print ("a:", a, "a>>2:", a>>2)
Đoạn code này khi chạy sẽ cho ra kết quả như sau:
a: 60 a>>2: 15
Quá trình dịch phải bit bằng tay với số 60
(trong hệ nhị phân là 00111100
) diễn ra như sau:
0011 1100 (Số 60 trong hệ nhị phân)
>> (Dịch phải)
2 (Số lượng bit cần dịch)
————-
0000 1111 (Kết quả sau khi dịch)
Hai bit ở bên phải của số nhị phân bị bỏ đi. Các bit còn lại được đẩy về bên phải. Ta dùng hàm int()
để chuyển số nhị phân vừa dịch sang số nguyên ở hệ thập phân, ta có kết quả như sau:
>>> int('00001111',2)
15
Vậy 60 >> 2
cho kết quả là 15
Toán tử dịch phải bit thường được sử dụng trong các tác vụ lập trình liên quan đến thao tác bit, như nén dữ liệu, mã hóa, và một số thuật toán liên quan đến tối ưu hiệu năng. Trong các ngữ cảnh thông thường, người mới học lập trình Python có thể chưa cần đến toán tử này, nhưng đây là một phần kiến thức cơ bản bạn cần biết đến.
Lời kết
Chúng ta vừa cùng nhau khám phá chi tiết về các toán tử Bitwise trong Python, từ AND, OR, XOR, NOT cho đến dịch trái và dịch phải bit. Hy vọng qua bài viết này, bạn đã hiểu rõ cách các toán tử này hoạt động, cách áp dụng chúng trong lập trình.