Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
л_4_Операции_и_выражения.doc
Скачиваний:
11
Добавлен:
05.11.2018
Размер:
660.99 Кб
Скачать

Поразрядные логические операции

Обратите внимание, на специфические операции, определенные в C++ только для целочисленных типов и для выражений, приводимых к целому типу, – поразрядные логические операции. Их распространенное применение – обработка информации в регистрах, области системных данных компьютера, от различных его устройств, когда в силу ограниченности пропускной способности каналов информация упаковывается в байт, слово и т.д., а также – кодируется некоторым образом.

Результат поразрядной логической операции – целое число. Биты результата формируются из битов операндов поразрядно по тем же правилам, что и для логических операций. Только операндами и результатами вместо true является 1, а вместо false – 0. Операции выполняются слева направо, кроме операции поразрядного отрицания.

Таблица6.2. Значения поразрядных логических операций

A

B

результат поразрядных операций

~ A

&

|

^

0

0

1

0

0

0

0

1

1

0

1

1

1

0

0

0

1

1

1

1

0

1

1

0

операция

содержание

~

поразрядное отрицание (поразрядная инверсия, дополнение до 1)

& и

1 во всех разрядах, где у операндов 1

| или

1 во всех разрядах, где один или второй операнды имеют 1

^ исключающее или

1 во всех разрядах, где операнды имеют разные двоичные значения

Примеры выполнения поразрядных логических операций:

Пример 1.

12 & 22 = 4, так как:

1210 = С16 = 000011002 (для типа char)

(поразрядное умножение - &) *

2210 =1616 = 000101102

__________

000001002 = 410

Пример 2.

char i, j, k; …… i=5; j=3; k= i & j;

k==1, т.к. в двоичной системе имеем: 00000101(i) & 00000011(j) = 00000001 (k).

Пример 3.

12 | 22 = 30, так как:

1210 = С16 = 000011002 (для типа char)

(поразрядное сложение - or) +

2210 =1616 = 000101102

__________

000111102 = 1* 24 +1*23+ 1*22+ 1* 21 =3010;

Пример 4.

12 ^ 22 = 26, так как:

1210 = С16 = 000011002 (для типа char)

(операция ^)

2210 =1616 = 000101102

__________

000110102 = 1* 24 +1*23+ 1* 21 =2610;

Пример 5.

Операция Y = X & 15 или ее аналог Y = X & $F – выделяет 4 младших разряда переменной Х (типа char), т.к. $F = 15 = 00001111. Старшие разряды обнуляются независимо от их значения, младшие – сохраняются.

Пример 6.

От прибора в ЭВМ поступает 16-разрядный код (справа налево номера от 0 до 15). Допустим, в разрядах 0-4 находится информация от первого датчика, 5-11 – от датчика 2, с 12 по 14 – от датчика 3. Рассмотрим алгоритм выделения информации от каждого из датчиков:

int Х, XX, x1, x2, x3; {ХX – исходная интегрированная информация} {x1, x2, x3 – выделенная информация от датчиков} . . . . . X = XX; x1 = X & 31; {выделяются разряды с 0 по 4 –- 31 =0000 0000 0001 1111}

X = X / 32; {происходит сдвиг Х на 5 разрядов вправо, }

{ аналог – команда Х >> 5}

x2 = X & 127; {выделяются очередные 7 разрядов, бывшие разряды 5-11}

{127 = $7F = 0000 0000 0111 1111}

X = X / 128; {производится сдвиг вправо очередных 7-и разрядов}

x3 =X & 7; {выделяются младшие 3 разряда, бывшие 12 - 14}

Пример 7.

Состояние 3-х кнопок мыши возвращается в переменной Button (тип char) в такой последовательности: левая, правая, средняя в разряды 0 –2. Тогда для анализа состояния кнопок мыши можно использовать операторы:

LeftButton = (Button & 1) == 1;

RightButton = (Button & 2) == 2;

LeftRightButton = (Button & 3) == 3;

MiddleButton = (Button & 4) == 4;

LeftMiddleButton = (Button & 5) == 5;

Пример 8.

С помощью поразрядной логической операции & легко найти остаток от деления операндов типа unsigned int на значения, кратные двум.

Например, определение остатка от деления операнда D типа unsigned int на 2, 4, 8, 16 и т.д. требует поразрядной логической операции & делимого D соответственно с масками 0х01, 0х03, 0х07, 0х0f, 0x1f и т.д. Другими словами, выделяются младшие биты числа, а остальные устанавливаются в 0. Это наиболее быстрый способ выделения остатка.

unsigned D, mask = 0x01; //(при делении на 2); 0x03 (на 4); 0x07 (на 8); 0x0f (на 16); 0x1f (на 32);

D =7;

D & mask; //- значение разряда, который «уходит» при делении на 2 последний раз

00000111 - это 7

00000001 - для 2-х

------------

00000001 - это 1 (остаток от деления 7 на 2, результат операции 7 & 2)

00000111 - это 7

00000011 - для 4-х

------------

00000011 - это 3 (остаток от деления 7 на 4, результат операции 7 & 4)

Пример 9.

С помощью поразрядной логической операции & можно проверить наличие единицы в любом разряде:

проверить наличие единицы в бите №4 переменной х типа char поможет логическое выражение: (х & 16) == 16;

проверить наличие единицы в битах №4, №2, №1 переменной х типа char поможет логическое выражение: (х & 22) == 22;

Пример 10.

С помощью поразрядной логической операции & можно «выключить» значение любого бита:

выключить бит №2 переменной х типа char (при неизменном значении других битов) поможет логическое выражение: х & 251 (255 – это единицы во всех разрядах, логическое выражение (х & 255) – оставит без изменения значения всех битов, бит 2 имеет значение 4, х & (255-4) – обнулит только бит номер 2;

Пример 11.

С помощью поразрядной логической операции | можно «включить» значение любого бита:

включить бит №2 переменной х типа char (при неизменном значении других битов) поможет логическое выражение: х | 4;

включить биты №4, №2, №1, №0 переменной х типа char (при неизменном значении других битов) поможет логическое выражение: х | 23;

Что напечатает программа:

#define PRINT(int) printf(“int=%d\n”, int)

int x, y, z);

x=03; y=02; z=01;

PRINT(x | y & z);

(0011 | (0010 & 0001))=(0011|0000)=0011=3

PRINT(x | y & ~z);

(0011 | (0010 & 1110))=(0011|0010)=0011=3

PRINT(x ^ y & ~z);

(0011^(0010 & 1110))=(0011^0010)=0001=1

PRINT(x & y && z);

((0011&0010)&&0001=(0010&&0001)=истина