Российский государственный гуманитарный университет
Опубликован: 13.07.2022 | Доступ: свободный | Студентов: 263 / 9 | Длительность: 11:54:00
Специальности: Программист
Лекция 4:

Логические основы компьютера

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >

Битовые операции

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

Битовыми называют операции над цепочками битов. Основными битовыми операциями являются побитовые операции и битовые сдвиги.

Побитовые операции

Побитовые операции - это операции, которые применяются к каждому биту из цепочки битов. Основными побитовыми операциями являются побитовое отрицание bitNot, побитовая конъюнкция bitAnd, побитовая дизъюнкция bitOr и побитовая строгая дизъюнкция bitXor.

Для того, чтобы найти результат побитовой операции, следует представить числа в двоичном виде и затем применить операцию к цифрам, стоящим в одинаковых разрядах.

Побитовая операция отрицания соответствует побитовому применению функции inv(x) = 1 - x, для x \in \{0, 1\}.

Пример 22. Пусть для хранения чисел используется 4 байта. Тогда bitNot(2^{32} - 1) = 0. Соответственно, bitNot(0) = 2^{32} - 1 = 4294967295.

Найдем результат побитовой операции отрицания, примененной к числу 275. Имеем: 275 = 100010011_2, или в 4 байтах,

00000000 00000000 00000001 00010011.

Применив к каждому биту функцию inv(x) = 1 - x, получим:

11111111 11111111 11111110 11101100.

Таким образом, bitNot(275) = 4294967020.

Побитовые операции конъюнкции, дизъюнкции и строгой дизъюнкции соответствуют побитовому применению функций

f(x, y) = min(x, y), g(x, y) = max(x, y), h(x, y) = (x + y) mod 2,

соответственно, где x, y \in \{0, 1\}.

Пример 23. Найдем результаты применения побитовых бинарных операций к числам 14 и 26. Имеем: 14 = 1110_2, 26 = 11010_2. Поэтому


Следовательно,

bitAnd(14, 26) = 10; bitOr(14, 26) = 30; bitXor(14, 26) = 20.

Обозначим через Deg(x) множество показателей степеней 2 в разложении числа x по степеням 2. Тогда

Deg(bitAnd(x, y)) = Deg(x) \cap Deg(y);\\
Deg(bitOr(x, y)) = Deg(x) \cup Deg(y);\\
Deg(bitXor(x, y)) = Deg(x) \Delta Deg(y),

где символами \cap, \cup и \Delta обозначены операции пересечения, объединения и симметрической разности множеств, соответственно.

Пример 24. Пусть x = 15, y = 28. Тогда

15 = 2^3 + 2^2 + 2 + 1;\\
28 = 2^4 + 2^3 + 2^2.

Поэтому Deg(15) = {0, 1, 2, 3}, Deg(28) = {2, 3, 4}. Имеем:

\{0, 1, 2, 3\} \cap \{2, 3, 4\} = \{2, 3\};\\
\{0, 1, 2, 3\} \cup \{2, 3, 4\} = \{0, 1, 2, 3, 4\}.\\
\{0, 1, 2, 3\} \Delta \{2, 3, 4\} = \{0, 1, 4\}.

Следовательно,

bitAnd(15, 28) = 2^2 + 2^3 = 12;\\
bitOr(15, 28) = 1 + 2 + 2^2 + 2^3 + 2^4 = 31;\\
bitXor(15, 28) = 1 + 2 + 24 = 19.

Ясно, что операции объединения, пересечения и симметрической разности могут применяться к самим степеням 2. В данном случае имеем:

\{1, 2, 2^2, 2^3\} \cap \{2^2, 2^3, 2^4\} = \{2^2, 2^3\};\\
\{1, 2, 2^2, 2^3\} \cup \{2^2, 2^3, 2^4\} = \{1, 2, 2^2, 2^3, 2^4\}.\\
\{1, 2, 2^2, 2^3\} \Delta \{2^2, 2^3, 2^4\} = \{1, 2, 2^4\}.

Свойства операции bitXor рассматриваются также в п. 5.1.

Битовые сдвиги

Битовые сдвиги разделяют на арифметические и логические. Первые зависят, а вторые не зависят от числа разрядов, которые используются для представления числа. В языках программирования реализуются логические сдвиги.

Пусть двоичное представление целого неотрицательного числа x имеет вид: x = b_0b_1 \dots b_{n - 1}b_n. Тогда операции арифметических битовых сдвигов определяются следующим образом:

b_0b_1 \dots b_{n - 1}bn \to b_0b_1 \dots b_{n - 1}b_n0 - арифметический сдвиг влево;

b_0b_1 \dots b_{n - 1}b_n \to b_0b_1 \dots b_{n - 1} - арифметический сдвиг вправо.

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

b_0b_1 \dots b_{n - 1}b_n \to b_1 \dots b_{n - 1}b_n0 - логический сдвиг влево;

b0b1 \dots b_{n - 1}b_n \to 0b_0b_1 \dots b_{n - 1} - логический сдвиг вправо.

Обозначим через bitShiftLeft и bitShiftRight - операции арифметических сдвигов влево и вправо, соответственно, а через bitLeft и bitRight - операции логических сдвигов соответственно влево и вправо.

Нетрудно заметить, что

bitShiftLeft(x) = 2x; bitShiftRight(x) = bitRight(x) = x div 2

(см. п. 1.1). Таким образом, арифметический сдвиг влево соответствует удвоению числа. Кроме того, заметим, что если число x - четное, а в этом случае его младший разряд равен 0, то в результате сдвига вправо получится число, ровно в 2 раза меньшее исходного. Если же младший разряд числа равен 1, то получится целая часть частного от деления на 2.

В типах данных число разрядов фиксировано, поэтому при логическом сдвиге влево теряется старший разряд. Найдем число, которое получается при логическом сдвиге числа x влево на 1 разряд, если число разрядов в типе данных равно n + 1.

Имеем:  x=b_0 2^n+b_1 2^{n-1}+\dots+b_{n-1}*2+b_n. Поэтому

 bitLeft(x)=b_1 2^n+b_2 2^{n-1}+\dots+b_n*2+0=\\ 
 =2(b_0 2^n+b_1 2^{n-1}+\dots+b_n )-b_0 2^{n+1}=2x-b_0 2^{n+1}.

Таким образом, если старший разряд числа x равен 0, то логический сдвиг влево приведет к удвоению числа. Далее, старший разряд числа x, для x<2^{n + 1}, равен 1, если x \ge 2^n. Пусть x = 2^n + y, где 0 \le y \le 2^n. Тогда bitLeft(2^n + y) = 2(2^n + y) - 2^{n + 1} = 2y. Следовательно, если старший разряд числа равен 1, то в результате его логического сдвига влево получится его удвоенный остаток от деления на 2^n.

Пример 24. Пусть тип данных содержит 4 байта.

Для числа 23 имеем:

bitShiftLeft(23) = bitLeft(23) = 46; 
 bitShiftRight(23) = bitRight(23) = 11,

что легко получить из определения операций, так как 23 = 10111_2.

Найдем сдвиг влево для максимального числа. Имеем:

bitLeft(2^{32} - 1) = 2(2^{32} - 1) - 2^{32} = 2^{32} - 2.

Таким образом, bitLeft(4294967295) = 4294967294.

В общем случае, пусть число разрядов равно n + 1 и 0 < z \le 2^n. Тогда 2^{n + 1} - z \ge 2^n. Поэтому

bitLeft(2^{n + 1} - z) = 2(2^{n + 1} - z) - 2^{n + 1} = 2^{n + 1} - 2z.

В частности, если тип данных содержит 4 байта, то bitLeft(2^{31}) = 0, а для арифметического сдвига имеем: bitShiftLeft(2^{31}) = 2^{32}.

Рассмотрим битовые сдвиги на k разрядов, где k \ge 0. Покажем, что арифметический сдвиг влево на k разрядов числа x соответствует умножению x на 2^k. Арифметический сдвиг вправо на k разрядов числа x приводит к целой части частного от деления x на 2^k.

Пусть опять представление целого неотрицательного числа x в двоичном виде имеет вид: x = b0b1 \dots bn - 1bn. Тогда арифметический битовый сдвиг на k разрядов влево определяется следующим образом:

 bitShiftLeft(x,k)=b_0 b_1\dotsb_{n-1} b_n\underbrace{0\dots0}

Ясно, что bitShiftLeft(x, k) = x * 2^k.

Пример 25. Для числа 5 имеем:

bitShiftLeft(5, 1) = 10; 		bitShiftLeft(5, 2) = 20; 
bitShiftLeft(5, 3) = 40;		bitShiftLeft(5, 4) = 80.

Соответственно,

101_2 = 5;\\
1010_2 = 10;\\
10100_2 = 20;\\
101000_2 = 40;\\
1010000_2 = 80.

Арифметический и логический битовые сдвиги на k разрядов вправо совпадают и определяются следующим образом:

bitShiftRight(x,k)=bitRight(x,k)=\begin{cases}
b_ob_1\dots b_{n-k}, k \le n,\\
0, k >n
\end{cases}

Пусть k \le n. Имеем:

bitRight(x,k)=b_02^{n-k}+b_12^{n-k-1}+\dots +b_{n-k}=\\
=\frac{1}{2^k}(b_02^n+b_12^{n-1} \dots +b_{n-k}2^k+b_{n-k-1}2^{n-k}+\dots +b_n)-\\
-\frac{1}{2^k}(b_{n-k-1}2^{n-k}+\dots+b_n)=\frac{x}{2^k}-\frac{b_{n-k-1}2^{n-k}+\dots+b_n}{2^k}

Следовательно, bitRight(x, k) = x div 2^k.

Пример 26. bitRight(100, 5) = 100 \;\div\; 2^5 = 3.

Пусть тип данных содержит n + 1 разряд. Определение логического сдвига влево на k разрядов имеет вид:

 bitLeft(x,k)=\begin{cases}
b_k b_{k+1}\dots b_n \underbrace{0\dots0}_k, k \le n\\
0, k > n
\end{cases}

Пусть k \le n. Тогда

bitLeft(x,k)=b_k 2^n+b_{k+1} 2^{n-1}+\dots+b_n 2^k= \\
 =2^k (b_0 2^n+\dots+b_{k-1} 2^{n-k+1}+b_k 2^{n-k}+b_{k+1} 2^{n-k-1}+\dots+b_n )-\\
 -(b_0 2^{n+k}+\dots+b_{k-1} 2^{n+1} )=2^k x-2^{n+1} (b_0 2^{k-1}+\dots+b_{k-1} ).

Пример 27. Рассмотрим битовые сдвиги числа 14 на 2 разряда влево и вправо. Имеем: 14 = 1110_2, n = 3, k = 2.

Арифметический сдвиг влево на 2 разряда: 111000_2 = 56 = 14 * 2^2.

Логический сдвиг вправо на 2 разряда:

0011_2 = 3 = 14 \div 4 =\frac{14}{2^2}-\frac{2}{2^2}

Логический сдвиг влево на 2 разряда:

1000_2 = 8 = 2^2 * 14 - 2^4 * 3 = 56 - 48.

Пример 28. Пусть тип данных содержит 4 байта. Рассмотрим логический сдвиг максимального числа влево на k разрядов, для k \le 32. Имеем:

bitLeft(2^{32} - 1, k) = 2^k(2^{32} - 1) - 2^{32}(2^k - 1) = 2^{32} - 2^k.

Например,

bitLeft(2^{32} - 1, 31)  = 2^{32} - 2^{31} = 2^{31} = 2147483648.

В компьютерной программе двоичное представление числа можно преобразовать в десятичное представление с помощью битовых сдвигов единицы влево и побитовой дизъюнкции, которая обобщается на произвольное число аргументов.

Пример 29. Для числа 10010101_2 имеем:

10010101_2= bitOr(bitLeft(1, 7), bitLeft(1, 4), bitLeft(1, 2), 1) = 
= 2^7 + 2^4 + 2^2 + 1 = 149.

Пример 30. Вычислим bitOr(bitShiftLeft(5, 2), bitShiftLeft(3, 1)).

Имеем:


bitShiftLeft(5, 2) = bitShiftLeft(101_2, 2) = 10100_2;\\
bitShiftLeft(3, 1) = bitShiftLeft(11_2, 1) = 110_2.

Поэтому bitOr(10100_2, 00110_2) = 10110_2 = 22.

Упражнения

  1. Определите, является ли высказыванием предложение

    a) "Проверьте напряжение в электросети";

    b) "Что посеешь, то и пожнешь";

    c) "Земля вращается вокруг Солнца";

    d) "Это предложение ложное".

  2. Составьте из высказываний A: "Идет дождь" и B: "Мы сидим дома" высказывание

    a) A & B;

    b) A \vee B;

    c) A \to B;

    d) \neg B \to A;

    e) A \leftrightarrow B;

    f) A \oplus B;

    g) A \mid B;

    h) A \downarrow B.

  3. Составьте из высказываний A: "Идет дождь" и B: "Мы сидим дома" сложное высказывание, которое является

    a) тавтологией;

    b) противоречием.

  4. Определите, является ли тавтологией высказывание

    a)  (А \& \neg А) \vee \neg А;

    b) А \vee \neg В \vee \neg А;

    c)  (А \& \neg А) \vee B;

    d)  (А \vee \neg В) \vee А.

  5. Составьте таблицу истинности для высказывания

    a) (A \mid B) \leftrightarrow (A \downarrow B);

    b) A \oplus B \oplus C.

  6. Упростите выражение

    a)ab \vee \bar a \vee \bar b;

    b) ab \bar c \vee \bar a b \bar c \vee bc;

    c) \bar a \bar b \bar c \vee \bar a b \bar c \vee a \vee c;

    d) \overline{ab| \overline{a \vee b} \vee ab(a \vee b).

  7. Покажите, что в произвольной булевой алгебре верно равенство

    a)a \bar b\vee \bar a b =(a \vee b)(\bar a \vee \bar b);

    b) a\vee b \vee c=a\bar b\vee b\bar c\vee c \bar a\vee abc.

  8. Используя свойства логических операций, решите задачу.

    Сестры Маша, Даша и Глаша испекли пирог. Одна из них месила тесто, другая готовила начинку, а третья выпекала пирог. Известно, что каждое из следующих высказываний истинно:

    1. если Глаша месила тесто, то Даша готовила начинку;
    2. если Маша выпекала пирог, то месила тесто Даша;
    3. если Глаша готовила начинку, то Маша выпекала пирог;
    4. если Даша месила тесто, то Маша готовила начинку;
    5. если Глаша выпекала пирог, то Маша месила тесто.

    Кто из них месил тесто, кто готовил начинку, а кто выпекал пирог?

  9. Составьте для логической функции таблицу истинности и постройте по ней 1) СДНФ; 2) СКНФ, если функция на множестве {0, 1} определяется следующим образом:

    a)f(x,y,z)=\begin{cases}
1, x+y+z > 1,\\
0, x+y+z \le1
\end{cases}

    b)f(x,y,z)=\begin{cases}
1,x < y+z,\\
0, xge y+z
\end{cases}

  10. Постройте электронную логическую схему для функции

    a) f(a,b,c)=\overline{z \vee \bar b}\vee \bar c

    b) f(a,b,c)=(a\mid b)(a \downarrow c).

  11. Составьте таблицу истинности и постройте электронную логическую схему для одноразрядного полусумматора (см. пример 21).
  12. Постройте электронные логические схемы для логической операции 1) конъюнкции; 2) дизъюнкции; 3) отрицания; 4) строгой дизъюнкции; 5) эквиваленции, используя только

    a) схему И-НЕ;

    b) схему ИЛИ-НЕ.

  13. Постройте электронные логические схемы для функций из упр. 4.9.
  14. Постройте логическую функцию по электронной логической схеме

    a) рис. 4.14 (a); b) рис. 4.14 (b).
     Электронные логические схемы

    Рис. 4.14. Электронные логические схемы
  15. Вычислите результат побитовой операции отрицания, если тип данных использует для хранения чисел 4 байта, для числа

    a) 33;

    b) 2^{32} - 7.

  16. Вычислите результат побитовой операции:

    a) bitAnd(7, 8);

    b) bitOr(16, 1);

    c) bitXor(9, 9);

    d) bitAnd(17, 23);

    e) bitOr(17, 23);

    f) bitXor(17, 23);

    g) bitAnd(100, 10);

    h) bitOr(25, 5);

    i) bitXor(0, 10).

  17. Вычислите результат арифметического битового сдвига

    a) bitShiftLeft(33);

    b) bitShiftRight(19, 2).

  18. Вычислите результат логического битового сдвига числа x на k разрядов влево для типа данных с 32 разрядами:

    a) x = 2^{31} + 15, k = 1;

    b) x = 2^{32} - 20, k = 1;

    c) x = 70, k = 5;

    d) x = 2^{30} + 10, k = 2.

  19. Вычислите bitOr(bitLeft(6, 3), bitLeft(10, 2), bitLeft(7, 1)).
  20. Вычислите bitAnd(bitRight(26, 3), bitRight(17, 4)).
< Лекция 3 || Лекция 4: 12345 || Лекция 5 >