Các phép toán với bit
Một số nguyên có thể biểu diễn bằng nhiều cách: sử dụng hệ nhị phân, hệ bát phân hoặc thập lục phân (hexa).
Ví dụ số 21
(thập phân) có thể biểu diễn trong hệ hexa là 15
, hệ bát phân là 25
và nhị phân là 10101
. Cách viết trong C như sau 0x15
hoặc 0X15
(hexa), 025
(bát phân) và 0b10101
(nhị phân).
Các phép toán với bit gồm có:
Toán tử | Giải thích |
---|---|
& | AND bit |
| | OR bit |
^ | XOR bit |
~ | NOT bit |
<< | SHIFT LEFT, dịch trái bit |
>> | SHIFT RIGHT, dịch phải bit |
Phép NOT bit là phép đảo bit, sẽ trả về bit 0 khi bit đầu vào là 1 (và ngược lại). Phép toán AND, OR bit tương tự như phép toán logic, phép toán XOR bit sẽ trả về bit 0 khi hai bit đầu vào là giống nhau, trả về 1 khi hai bit đầu vào là khác nhau. Cụ thể như sau:
Bit 1 | Bit 2 | AND | OR | XOR |
---|---|---|---|---|
1 | 1 | 1 | 1 | 0 |
0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 1 | 1 |
0 | 1 | 0 | 1 | 1 |
Ví dụ
|
|
Tính chất của phép toán trên bit
- Toán tử
&
,|
và^
có tính chất giao hoán. Ví dụa & b
vàb & a
luôn ra kết quả giống nhau. a & 0 = 0
,a | 0 = a
vàa ^ 0 = a
a & a = a
vàa | a = a
a ^ a = 0
- Nếu
a ^ b = c
thìa ^ c = b
vàb ^ c = a
- Phép toán dịch n bit trái tương đương với nhân với 2n
- Phép toán dịch n bit phải tương đương với chia cho 2n
Kiến thức nâng cao với bit
Biểu diễn số âm
Để đơn giản thì chúng ta xét trường hợp với kiểu char
chỉ có 8 bit biểu diễn các số từ -128
đến 127
. Câu hỏi đầu tiên là số -1
được biểu diễn như thế nào. Rất đơn giản, ta có -1
+ 1
= 0
, số 1
được biểu diễn trong hệ nhị phân là 00000001
nên số -1
sẽ là 11111111
. Vì 00000001
+ 11111111
= 00000000
(bit tràn quá 8 bit sẽ được bỏ qua). Phương pháp biểu diễn số âm kiểu này được gọi là lấy số bù 2.
Bảng sau liệt kê các số âm từ -1 đến -5 (các số nhị phân được phân cách bằng _
cho dễ nhìn).
Số dương | Số dương nhị phân | Số âm | Số âm nhị phân | Tổng nhị phân |
---|---|---|---|---|
1 | 0000_0001 | -1 | 1111_1111 | 0 |
2 | 0000_0010 | -2 | 1111_1110 | 0 |
3 | 0000_0011 | -3 | 1111_1101 | 0 |
4 | 0000_0100 | -4 | 1111_1100 | 0 |
5 | 0000_0101 | -5 | 1111_1011 | 0 |
127 | 0111_1111 | -127 | 1000_0001 | 0 |
Số -128
sẽ được biểu diễn là 1000_0000
. Để ý là bit đầu tiên của tám bit này nếu là số 1
thì sẽ là số âm, ngược lại sẽ là số dương.
Lấy phép NOT bit
Để ý khi đảo các bit của số 1
(nhị phân là 0000_0001
) thì được các bit 1111_1110
ứng với số -2
. Tương tự với các số khác. Sau đây là bảng NOT bit (phép toán ~
) các số từ 0
đến 4
với kiểu dữ liệu char
:
Số thập phân | Số nhị phân | NOT bit nhị phân | NOT bit thập phân |
---|---|---|---|
0 | 0000_0000 | 1111_1111 | -1 |
1 | 0000_0001 | 1111_1110 | -2 |
2 | 0000_0010 | 1111_1101 | -3 |
3 | 0000_0011 | 1111_1100 | -4 |
4 | 0000_0100 | 1111_1011 | -5 |
Công thức của chúng ta sẽ là ~a = -a - 1
. Vậy nên kết quả của ví dụ ở trên ~21
sẽ là -22
.
Lấy NOT bit với số nguyên không dấu
Với kiểu dữ liệu là số nguyên không dấu, cách thực hiện ở dạng nhị phân sẽ tương tự như trên, tuy nhiên hiển thị ở hệ thập phân lại khác.
Kiểu unsigned char
sẽ nhận các giá trị từ 0
đến 255
. Sau đây là bảng NOT bit các số từ 0
đến 4
:
Số thập phân | Số nhị phân | NOT bit nhị phân | NOT bit thập phân |
---|---|---|---|
0 | 0000_0000 | 1111_1111 | 255 |
1 | 0000_0001 | 1111_1110 | 254 |
2 | 0000_0010 | 1111_1101 | 253 |
3 | 0000_0011 | 1111_1100 | 252 |
4 | 0000_0100 | 1111_1011 | 251 |
Công thức cho trường hợp số nguyên không dấu sẽ là ~a = 255 - a
(với 255 là giá trị lớn nhất của kiểu char
).