основыкнигиwin/dos*nixготовоелирикагостиФОРУМПОИСК
Б.В. Керниган, Д.М. Ричи -- Язык C

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

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


       &        побитовое AND
      \!      побитовое включающее OR
      ^        побитовое исключающее OR
      <<      сдвиг влево
      >>      сдвиг вправо
      \^      дополнение (унарная операция)
      "\"    иммитирует вертикальную черту


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

    C = N & 0177

передает в 'с' семь младших битов 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, оставляя другие биты неизмененными.

ПРЕДЫДУЩАЯ ЧАСТЬ
2.8. Операции увеличения и уменьшения
СОДЕРЖАНИЕ СЛЕДУЮЩАЯ ЧАСТЬ
2.10. Операции и выражения присваивания