Таблица 9.1. Двоичные и шестнадцатеричные числа
| Десятичное значение | Двоичное значение | Шестнадцатеричное значение |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 2 | 0010 | 2 |
| 3 | 0011 | 3 |
| 4 | 0100 | 4 |
| 5 | 0101 | 5 |
| 6 | 0110 | 6 |
| 7 | 0111 | 7 |
| 8 | 1000 | 8 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 11 | 1011 | B |
| 12 | 1100 | C |
| 13 | 1101 | D |
| 14 | 1110 | E |
| 15 | 1111 | F |
Шестнадцатеричные константы, как и двоичные, имеют специальную форму записи:
int x = 0x0003; // 3
int y = 0x010F; // 271 (256 + 15)
Эту форму записи используют не только в программном коде на C, но и в документации, чтобы показать, что число является шестнадцатеричным, а не десятичным.
Маскирование битов
Нередко при приеме данных от периферийных устройств, независимо от вида связи, данные поступают упакованными в байты, в которых часть битов может нести служебную информацию. Создатели периферийных устройств часто стараются втолкнуть как можно больше информации в минимальное число бит, чтобы добиться максимальной скорости передачи, но это усложняет программирование взаимодействий с такими устройствами.
Операция маскирования битов позволяет игнорировать некоторую часть данных в байте или в большой структуре данных. На рис. 9.1 показано, как выполнить маскирование байта, содержащего разнородные данные, и получить число, определяемое тремя младшими битами.
Рис. 9.1. Маскирование битов
В описаниях двоичных чисел вы обязательно столкнетесь со словосочетаниями «самый младший» и «самый старший». В двоичных числах, записанных с соблюдением правил, принятых в математике, самым старшим битом является крайний левый бит, а младшим значащим — крайний правый. Крайний правый бит может иметь ценность только 1 или 0. Вам также встретятся термины самый старший бит (Most Significant Bit, MSB) и самый младший бит (Least Significant Bit, LSB). Самый младший бит иногда называют также нулевым битом (бит 0), первый бит (бит 1) — следующий по старшинству и т.д.
В примере, изображенном на рис. 9.1, байт включает несколько значений, но нас интересуют только три младших бита, которые нужно извлечь как число. Для этого можно выполнить поразрядную операцию И (AND) данных с маской, в которой три младших бита имеют значение 1. Поразрядная операция И (AND) для двух байт в свою очередь выполняет операцию И (AND) для каждой пары соответствующих битов и конструирует общий результат. Операция И (AND) для двух битов вернет 1, только если оба бита имеют значение 1.
Далее показана реализация этого примера на Arduino C с использованием оператора &. Обратите внимание на то, что поразрядная операция И (AND) обозначается единственным символом &, а логическая операция И (AND) — двумя: &&.
byte data = 0b01100101;
byte result = (data & 0b00000111);
Переменная result в данном случае получит десятичное значение 5.
Сдвиг битов
Часто необходимые биты в принимаемых данных могут занимать не самые младшие разряды в байте. Например, если из данных, изображенных на рис. 9.1, потребуется извлечь число, определяемое битами с 5-го по 3-й (рис. 9.2), то вам придется сначала применить маску, чтобы оставить интересующие биты, как в предыдущем примере, а затем сдвинуть биты на три позиции вправо.