Шестнадцатеричная система исчисления.
Представим, что необходимо просмотреть содержимое некоторых байтов в памяти
Требуется определить содержимое четырех последовательных байтов (двух слов), которые имеют двоичные значения. Для более краткого представления таких длинных чисел был разработан специальный метод представления двоичных данных, по которому каждый байт делится пополам и, каждые полбайта выражаются соответствующим значением. Рассмотрим следующие четыре байта:
Двоичное представление: 0101 1001 0011 0101 1011 1001 1100 1110 Десятичное представление: 5 9 3 5 11 9 12 14 |
Так как здесь для представления некоторых чисел требуется две цифры, то расширим систему исчисления так, чтобы
10=А, 11=B, 12=C, 13=D, 14=E, 15=F |
Таким образом, получим более сокращенную форму, которая представляет содержимое вышеуказанных байтов:
59 35 B9 CE |
Такая система исчисления включает "цифры" от 0 до F, и, так как таких цифр 16, она называется шестнадцатеричным представлением. В таблице ниже мы привели двоичные, десятичные и шестнадцатеричные значения чисел от 0 до 15.
Рассмотрим несколько простых примеров шестнадцатеричной арифметики. Следует помнить, что после шестнадцатеричного числа F следует шестнадцатеричное 10, что равно десятичному числу 16:
6+4=A 5+8=D F+1=10 F+F=1E 10+10=20 FF+1=100 |
Битовые операции
Только что мы с Вами разобрались с общей теорией, теперь пообщаемся с битовой арифметикой с точки зрения языка С.
В языке C++ существует ряд операций, выполняющихся над разрядами. Они носят название битовые операции:
унарная операция:
инверсия битов (~);
бинарные операции:
битовое "И" (&);
битовое "ИЛИ" (|);
битовое исключающее "ИЛИ" (^);
сдвиг влево (<<);
сдвиг вправо (>>);
Остановимся на данных операциях более подробно.
1. Инверсия битов (поразрядное отрицание, дополнение до единицы) инвертирует биты, т.е. каждый бит со значением 1 получает значение 0 и наоборот.
2.Битовое "И" сравнивает последовательно разряд за разрядом два операнда. Для каждого разряда результат равен 1, тогда и только тогда, когда оба соответствующих разряда операндов равны 1. Так, например,
10010011 & 00111101 = 00010001 |
потому что только нулевой и четвертый разряды обоих операндов содержат 1.
3. Битовое "ИЛИ" сравнивает последовательно разряд за разрядом два своих операнда. Для каждого разряда результат равен 1 тогда и только тогда, когда любой из соответствующих разрядов операндов равны 1. Так, например,
10010011 | 00111101 = 10111111 |
потому что все разряды (кроме шестого) в одном из двух операндов имеют значение 1.
4. Битовое исключающее "ИЛИ" сравнивает последовательно разряд за разрядом два своих операнда. Для каждого разряда результат равен 1, если один из двух (но не оба) соответствующих разрядов операндов равен 1. Так, например,
10010011 ^ 00111101 = 10101110 |
Заметим, что, поскольку нулевой разряд в обоих операндах имеет значение 1, нулевой разряд результата имеет значение 0.
Описанные выше операции часто используются для установки некоторых битов, причем другие биты остаются неизменными. Они удобны для фильтрации или маскирования битов.
5. Сдвиг влево сдвигает разряды левого операнда влево на число позиций, указанное правым операндом. Освобождающиеся позиции заполняются нулями, а разряды, сдвигаемые за левый предел левого операнда, теряются. Поэтому, например,
10001010 << 2 = 00101000 , (каждый разряд сдвинулся на две позиции влево). |
Таким образом, х<<2 сдвигает х влево на 2 позиции, заполняя освобождающиеся позиции нулями (эквивалентно умножению на 4).
Для значений без знака имеем
10001010 >> 2 = 00100010 , (каждый разряд сдвинулся на две позиции). |
Эти две операции выполняют сдвиг, а также эффективное умножение и деление на степени числа 2.
