Побитовые логические операции
В языке предусмотрен ряд операций для работы с битами; эти операции нельзя применять к переменным типа 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, оставляя другие биты неизмененными.