logo search
Подбельский Фомин_Программирование на языке СИ_

Выражения с поразрядными операциями.

Выражения с поразрядными операциями. Поразрядные операции позволяют конструировать выражения, в которых обработка операндов выполняется на битовом уровне (поразрядно). Рассмотрим возможности операций над битами:

~ - поразрядное отрицание (дополнение или инвертирование битов) (ранг 2);

>> - сдвиг вправо последовательности битов (ранг 5);

<< - сдвиг влево последовательности битов (ранг 5);

^ - поразрядное исключающее ИЛИ (ранг 9);

| - поразрядное ИЛИ (поразрядная дизъюнкция) (ранг 10);

& - поразрядное И (поразрядная конъюнкция) (ранг 8).

Операция поразрядного отрицания (дополнения или инвертирования битов) обозначается символом "~" и является унарной (одноместной), т.е. действует на один операнд, который должен быть целого типа. Значение операнда в виде внутреннего битового представления обрабатывается таким образом, что формируется значение той же длины (того же типа), что и операнд. В битовом представлении результата содержатся 1 во всех разрядах, где у операнда 0, и 0 в тех разрядах, где у операнда 1. Например:

Значением F будет восьмеричный код '\076' символа '>' (см. Приложение 1). Действительно, битовые представления значений Е и F можно изобразить так:

11000001 -для значения переменной Е, т.е. для '\0301'

00111110 - для значения переменной F, т.е. для '\076'

За исключением дополнения, все остальные поразрядные операции бинарные (двухместные).

Операции сдвигов >> (вправо) и << (влево) должны иметь целочисленные операнды. Над битовым представлением значения левого операнда выполняется действие - сдвиг. Правый операнд определяет величину поразрядного сдвига. Например:

5 << 2 будет равно 20

5>> 2 будет равно 1

Битовые представления тех же операций сдвига можно изобразить так:

101 << 2 равно 10100, т.е. 20;

101>> 2 равно 001, т.е. 1.

При сдвиге влево на N позиций двоичное представление левого операнда сдвигается, а освобождающиеся слева разряды заполняются нулями. Такой сдвиг эквивалентен умножению значения операнда на 2N .

Сдвиг вправо на N позиций несколько сложнее. Тут следует отметить две особенности. Первое - это исчезновение младших разрядов, выходящих за разрядную сетку. Вторая особенность - отсутствие стандарта на правило заполнения освобождающихся левых разрядов. В стандарте языка сказано, что когда левый операнд есть целое значение с отрицательным знаком, то при сдвиге вправо заполнение освобождающихся левых разрядов определяется реализацией. Здесь возможны два варианта: освобождающиеся разряды заполняются значениями знакового разряда (арифметический сдвиг вправо) или освобождающиеся слева разряды заполняются нулями (логический сдвиг вправо).

При положительном левом операнде сдвиг вправо на N позиций эквивалентен уменьшению значения левого операнда в 2N раз с отбрасыванием дробной части результата. (Поэтому 5»2 равно 1.)

Операция "поразрядное исключающее ИЛИ". Эта операция имеет очень интересные возможности. Она применима к целым операндам. Результат формируется при поразрядной обработке битовых кодов операндов. В тех разрядах, где оба операнда имеют одинаковые двоичные значения (1 и 1 или 0 и 0), результат принимает значение 1. В тех разрядах, где биты операндов не совпадают, результат равен 0. Пример использования:

Переменные а и z "обменялись" значениями без использования вспомогательной переменной!

Поразрядная дизъюнкция (поразрядное ИЛИ) применима к целочисленным операндам. В соответствии с названием она позволяет получить 1 в тех разрядах результата, где не одновременно равны 0 биты обоих операндов. Например:

5|6 равно 7 (для 5-код 101, для 6-код 110);

10 | 8 равно 10 (для 10 - код 1010, для 8 - код 1000).

Поразрядная конъюнкция (поразрядное И) применима к целочисленным операндам. В битовом представлении результата только те биты равны 1, которым соответствуют единичные биты обоих операндов. Примеры:

5&6 равно 4 (для 5 - код 101, для 6 - код 110);

10&8 равно 8 (для 10 - код 1010, для 8 - код 1000).