Tổng quan về bitwise¶
Khái quát¶
Thao tác bitwise (1) là thuật ngữ để chỉ chung tập hợp các phép toán xử lý trực tiếp trên chuỗi nhị phân.
- wise là tiếp vĩ ngữ có nghĩa là "theo" hoặc "liên quan đến". Bitwise nghĩa là "xét riêng từng bit".
Trong C++, thao tác ở cấp độ bit giúp:
- Tiết kiệm dung lượng lưu trữ.
- Có thể đạt được tốc độ xử lý tối ưu.
Một số toán tử trên bit¶
| Toán tử | Tên gọi | Ý nghĩa |
|---|---|---|
& |
AND | Chỉ trả về bit 1 khi hai bit ở vị trí tương ứng đều là bit 1. |
| |
OR | Chỉ trả về bit 1 khi ít nhất một trong hai bit ở vị trí tương ứng là bit 1. |
^ |
XOR | Chỉ trả về bit 1 khi hai bit ở vị trí tương ứng là khác nhau. |
~ |
NOT | Đảo ngược các bit: 0 thành 1, 1 thành 0. |
<< |
Dịch trái (left shift) | Dịch các bit sang trái p vị trí. Điền các vị trí trống ở bên phải bằng bit 0. |
>> |
Dịch phải (right shift) | Dịch các bit sang phải p vị trí. Loại bỏ các bit ở bên phải. Đối với các bit bên trái thì thì cần xét thêm. |
Tạo chuỗi bit¶
Tạo chuỗi gồm toàn bit 0 hoặc gồm toàn bit 1.
Output:
OR¶
Với phép toán OR |:
- Để bảo toàn bit
bbất kỳ, ta dùng bit0. - Để bật/đặt bit
bbất kỳ thành bit1, ta dùng bit1.
Output:
AND¶
Với phép toán AND &:
- Để bảo toàn bit
bbất kỳ, ta dùng bit1. - Để tắt/xóa bỏ bit
bbất kỳ, ta dùng bit0.
Output:
Dịch trái¶
Dịch các bit của một số nguyên x sang trái một vị trí tương đương với nhân x với 2.
Tương tự, để tính \(2^p\), thay vì dùng vòng lặp for để nhân 2 nhiều lần, ta chỉ cần dịch bit 1 (ở hàng đơn vị) sang trái p vị trí. Độ phức tạp chỉ là \(O(1)\).
Output:
Tạo mặt nạ trái¶
Mặt nạ trái là chuỗi gồm p bit thấp (nằm bên phải) đều là bit 0 và các bit cao còn lại (nằm bên trái) đều là bit 1.
Cách tạo:
- Đảo ngược toàn bộ chuỗi bit
0thành toàn bit1. - Dịch các bit
1này sang tráipvị trí.
Output:
Tạo mặt nạ phải¶
Mặt nạ phải là chuỗi gồm p bit thấp (nằm bên phải) đều là bit 1 và các bit cao còn lại (nằm bên trái) đều là bit 0.
Cách tạo:
- Số 1 có duy nhất bit
1. Dịch bit1này sang tráipvị trí. - Đem kết quả trừ đi 1 để lật toàn bộ
pbit bên phải thành các bit1.
Giải thích:
1U << p = 0000 0001 << 3
= 0000 1000
(1U << p) - 1 = 0000 1000 - 1
= 0000 1000 - 0000 0001
= 0000 0111
Output:
\(2^p - 1\)
\(2^p - 1\) luôn là một chuỗi gồm đúng p bit 1.
Mã nguồn¶
Code đầy đủ được đặt tại GitHub.