Giới thiệu
Bản chất máy tính chỉ hiểu được mã nhị phân dưới dạng dãy số 0 và 1. Mỗi con số như vậy được gọi là một bit. Ngôn ngữ lập trình có cung cấp cho chúng ta những toán tử để chúng ta có thể thao tác trên bit như các phép cơ bản and, or, not, xor, dịch trái, dịch phải. Trong bài viết này tôi sẽ cùng các bạn làm quen cũng như thực hành với những toán tử thao tác trên bit hay còn được gọi là bitwise.
Các toán thử thao tác trên bit (bitwise)
Dữ liệu lưu trữ trong máy tính dưới dạng nhị phân 0 1. Tôi có ví dụ như sau:
1 |
unsigned char a = 12; |
Thì lưu trữ dưới bộ nhớ sẽ là:
Tương tự
1 |
unsigned int b = 95; |
Lưu trữ b dưới bộ nhớ:
Không gian lưu trữ kiểu unsigned int lớn hơn unsigned char do unsigned int dùng 4bytes = 32bits để biểu diễn còn unsigned char dùng 1byte = 8bit để biểu diễn.
Các toán tử thao tác trên bit
Các phép thao tác trên bit | Kí hiệu |
Phép AND | & |
Phép OR | | |
Phép phủ định NOT | ~ |
Phép XOR | ^ |
Phép dịch trái | << |
Phép dịch phải | >> |
Phép AND
Kí hiệu: &
Bảng chân trị
A | B | A & B |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Phép AND chỉ có giá trị 1 nếu cả hai toán hạng đều có giá trị 1.
Ví dụ:
Phép OR
Kí hiệu: |
Bảng chân trị
A | B | A | B |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Phép OR chỉ có giá trị 0 nếu cả hai toán hạng đều có giá trị 0.
Ví dụ
Phép phủ định NOT
Kí hiệu: ~
Bảng chân trị
A | ~A |
0 | 1 |
1 | 0 |
Phép NOT đảo bit 1 thành 0 và ngược lại.
Ví dụ
Phép XOR
Kí hiệu: ^
Bảng chân trị
A | B | A ^ B |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Phép XOR chỉ có giá trị 0 nếu cả hai toán hạng có cùng giá trị, cùng là giá trị 1, hay cùng là giá trị 0.
Ví dụ
Phép dịch trái <<
Kí hiệu: <<
Phép dịch trái n bit tương đương với phép nhân cho 2n.
Ví dụ
Lúc này B có giá trị là 4 * 22 = 16.
Phép dịch phải >>
Kí hiệu: >>
Phép dịch trái n bit tương đương với phép chia cho 2n.
Ví dụ
Lúc này giá trị của B là: 4 / 22 = 1
Các ví dụ thao tác cơ bản trên bit
AND
1 2 3 4 |
//AND unsigned char a = 5; //00000101(5) unsigned char b = 6; //00000110(6) unsigned char c = a & b; //00000100(4) |
OR
1 2 3 4 |
//OR unsigned char a = 5; //00000101(5) unsigned char b = 6; //00000110(6) unsigned char c = a | b; //00000111(7) |
NOT
1 2 3 |
//NOT unsigned char a = 5; //00000101(5) unsigned char b = ~a; //11111010(250) |
XOR
1 2 3 4 |
//XOR unsigned char a = 5; //00000101(5) unsigned char b = 6; //00000110(6) int c = a ^ b; //00000011(3) |
Dịch trái <<
1 2 3 |
//Shift Left << unsigned char a = 5; //00000101(5) unsigned char b = a << 4; //01010000(80) 5 * 2^4 |
Dịch phải >>
1 2 3 |
//Shift Right >> unsigned char a = 5; //00000101(5) unsigned char b = a >> 1; //00000010(2) 5 / 2^1 |