Опубликован: 05.07.2006 | Доступ: свободный | Студентов: 4680 / 885 | Оценка: 4.12 / 3.74 | Длительность: 18:59:00
Лекция 3:

Типы, операции и выражения

2.9. Побитовые логические операции

В языке предусмотрен ряд операций для работы с битами; эти операции нельзя применять к переменным типа float или double.

Таблица 2.2.
& Побитовое AND
| Побитовое включающее OR
^ побитовое исключающее OR
<< сдвиг влево
>> сдвиг вправо
~ дополнение (унарная операция)

" | " имитирует вертикальную черту.

Побитовая операция and часто используется для маскирования некоторого множества битов; например, оператор

c = n & 007f

передает в 'с' семь младших битов n, полагая остальные равными нулю. Операция '|' побитового or используется для включения битов:

c = x | mask

устанавливает на единицу те биты в х, которые равны единице в mask.

Следует быть внимательным и отличать побитовые операции & и | от логических связок && и ||, которые подразумевают вычисление значения истинности слева направо. Например, если х=1, а y=2, то значение х&y равно нулю, в то время как значение x&&y равно единице.

Операции сдвига << и >> осуществляют соответственно сдвиг влево и вправо своего левого операнда на число битовых позиций, задаваемых правым операндом. Таким образом, х<<2 сдвигает х влево на две позиции, заполняя освобождающиеся биты нулями, что эквивалентно умножению на 4. Сдвиг вправо величины без знака заполняет освобождающиеся биты на некоторых машинах, таких как PDP-11, заполняются содержанием знакового бита "арифметический сдвиг", а на других - нулем "логический сдвиг".

Унарная операция ~ дает дополнение к целому; это означает, что каждый бит со значением 1 получает значение 0 и наоборот. Эта операция обычно оказывается полезной в выражениях типа

x & ~077

где последние шесть битов х маскируются нулем. Подчеркнем, что выражение x&!077 не зависит от длины слова и поэтому предпочтительнее, чем, например, x&0177700, где предполагается, что х занимает 16 битов. Такая переносимая форма не требует никаких дополнительных затрат, поскольку ~077 является константным выражением и, следовательно, обрабатывается во время компиляции.

Чтобы проиллюстрировать использование некоторых операций с битами, рассмотрим функцию getbits(x,p,n), которая возвращает /сдвинутыми к правому краю/ начинающиеся с позиции р поле переменной х длиной n битов. Мы предполагаем, что крайний правый бит имеет номер 0, и что n и р - разумно заданные положительные числа. Например, getbits(х,4,3) возвращает сдвинутыми к правому краю биты, занимающие позиции 4, 3 и 2.

getbits(x,p,n)  /* get n bits from position p */
 unsigned x, p, n;
  {
    return((x >> (p+1-n)) & ~(~0 << n));
  }

Операция x >> (p+1-n ) сдвигает желаемое поле в правый конец слова. описание аргумента x как unsigned гарантирует, что при сдвиге вправо освобождающиеся биты будут заполняться нулями, а не содержимым знакового бита, независимо от того, на какой машине пропускается программа. Все биты константного выражения ~0 равны 1 ; сдвиг его на n позиций влево с помощью операции ~0<<n создает маску с нулями в n крайних правых битах и единицами в остальных; дополнение ~ создает маску с единицами в n крайних правых битах.

Упражнение 2-5

Переделайте getbits таким образом, чтобы биты отсчитывались слева направо.

Упражнение 2-6

Напишите программу для функции wordlength(), вычисляющей длину слова используемой машины, т.е. Число битов в переменной типа int. функция должна быть переносимой, т.е. Одна и та же исходная программа должна правильно работать на любой машине.

Упражнение 2-7

Напишите программу для функции rightrot(n,b), сдвигающей циклически целое n вправо на b битовых позиций.

Упражнение 2-8

Напишите программу для функции invert(x,p,n), которая инвертирует (т.е. заменяет 1 на 0 и наоборот) n битов x, начинающихся с позиции p, оставляя другие биты неизмененными.