Логические операции с числами

Автор: | 12.03.2024

Рассмотрим выполнение логических операций И, ИЛИ, Исключающее ИЛИ и НЕ над многоразрядными числами.

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

О переводе многоразрядных чисел в различные системы счисления подробно описано в этой статье.

Выполнение бинарной логической операции (то есть операции над двумя числами) осуществляется в следующем порядке:

  • Представить каждое число в 16-ричной системе счисления
  • Выровнять два числа по правому краю, поскольку побитовая операция будет осуществляться начиная с младшей 16-ричной цифры
  • Выполнить поразрядную логическую операцию над цифрами двух чисел
  • Сохранить цифру результата
  • Перейти к следующей цифре, двигаясь к началу пока не будут обработаны все цифры наиболее длинного числа
  • При необходимости перевести результат в десятичную систему счисления

Для выполнения унарной логической операции (в частности, логическое отрицание — НЕ) мы представляем обрабатываемое число в 16-ричной системе счисления и инвертируем каждую цифру числа. При необходимости переводим результат в десятичную систему счисления.

Реализация на C++

#include
using namespace std; // Перевод цифры в символ
// Перевод цифры от 0 до F в символьное представление
char digittochar( int num)
<
switch (num)
<
case 0: return ‘0’ ;
case 1: return ‘1’ ;
case 2: return ‘2’ ;
case 3: return ‘3’ ;
case 4: return ‘4’ ;
case 5: return ‘5’ ;
case 6: return ‘6’ ;
case 7: return ‘7’ ;
case 8: return ‘8’ ;
case 9: return ‘9’ ;
case 10: return ‘A’ ;
case 11: return ‘B’ ;
case 12: return ‘C’ ;
case 13: return ‘D’ ;
case 14: return ‘E’ ;
case 15: return ‘F’ ;
>
>
// Перевод символа от ‘0’ до ‘F’ в цифру
int digittoint( char num)
<
switch (num)
<
case ‘0’ : return 0;
case ‘1’ : return 1;
case ‘2’ : return 2;
case ‘3’ : return 3;
case ‘4’ : return 4;
case ‘5’ : return 5;
case ‘6’ : return 6;
case ‘7’ : return 7;
case ‘8’ : return 8;
case ‘9’ : return 9;
case ‘A’ : return 10;
case ‘B’ : return 11;
case ‘C’ : return 12;
case ‘D’ : return 13;
case ‘E’ : return 14;
case ‘F’ : return 15;
>
>
int dectox( char *a, int q, int p, char *c)
<
int rest = 0; // остаток от деления
char *s; // символьное десятичное представление частного a/p
int lena = strlen(a);
s = new char [lena];
int flag = 0; // проверка на нулевой результат в частном
for ( int i = 0; i int dig = a[i] > 0 ? digittoint(a[i]) : 0;
int num = rest*q + dig; // делимое на текущем шаге
s[i] = digittochar(num / p); // следующий разряд частного
rest = num % p; // остаток от деления
if (s[i] != ‘0’ ) flag = 1; // в случае ненулевого результата установить флаг
>
if (flag == 0) // частное равно 0, базовый случай рекурсии
<
c[0] = digittochar(rest); return 1; // запись старшего разряда результата
>
s[lena] = ‘’ ; // заканчиваем полученную строку результата
int k = dectox(s, q, p, c); // рекурсивный вызов для следующего разряда
c[k++] = digittochar(rest); // заполнение текущего разряда результата
return k;
>
// Функция ИЛИ
char * or ( char *a, char *b) <
int lena = strlen(a); // количество разрядов первого числа
int lenb = strlen(b); // количество разрядов второго числа
char *c;
int k = lena > lenb ? lena : lenb; // количество разрядов результата
c = new char [k + 1];
c[k] = ‘’ ; // завершающий нуль-символ результата
k—;
for ( int i = lena — 1, j = lenb — 1; i >= 0 || j >= 0; i—, j—) <
char dig1 = i // если разряд отсутствует, взять 0
char dig2 = j // иначе преобразовать символ в цифру
char dig = dig1 | dig2; // операция побитового ИЛИ над цифрами разрядов
c[k] = digittochar(dig);
k—; // перейти к следующему разряду
>
return c;
>

Читайте также  Краска водно дисперсионная фасовка

// Функция И
char * and( char *a, char *b)
<
int lena = strlen(a); // количество разрядов первого числа
int lenb = strlen(b); // количество разрядов второго числа
char *c;
int k = lena > lenb ? lena : lenb; // количество разрядов результата
c = new char [k + 1];
c[k] = ‘’ ; // завершающий нуль-символ результата
k—;
for ( int i = lena — 1, j = lenb — 1; i >= 0 || j >= 0; i—, j—)
<
char dig1 = i // если разряд отсутствует, взять 0
char dig2 = j // иначе преобразовать символ в цифру
char dig = dig1 & dig2; // операция побитового И над цифрами разрядов
c[k] = digittochar(dig);
k—; // перейти к следующему разряду
>
return c;
>
// Функция Исключающее ИЛИ
char * xor( char *a, char *b)
<
int lena = strlen(a); // количество разрядов первого числа
int lenb = strlen(b); // количество разрядов второго числа
char *c;
int k = lena > lenb ? lena : lenb; // количество разрядов результата
c = new char [k + 1];
c[k] = ‘’ ; // завершающий нуль-символ результата
k—;
for ( int i = lena — 1, j = lenb — 1; i >= 0 || j >= 0; i—, j—)
<
char dig1 = i // если разряд отсутствует, взять 0
char dig2 = j // иначе преобразовать символ в цифру
char dig = dig1 ^ dig2; // операция побитового исключающего ИЛИ над цифрами разрядов
c[k] = digittochar(dig);
k—; // перейти к следующему разряду
>
return c;
>
// Функция НЕ
char * not( char *a)
<
int lena = strlen(a); // количество разрядов первого числа
char *c;
int k = lena; // количество разрядов результата
c = new char [k + 1];
c[k] = ‘’ ; // завершающий нуль-символ результата
k—;
for ( int i = lena — 1; i >= 0; i—)
<
char dig1 = i // если разряд отсутствует, взять 0
char dig = (

Читайте также  Кран шаровый giacomini 1 2 цена

dig1) & 0x0F; // операция побитового НЕ над цифрами разрядов
c[k] = digittochar(dig);
k—; // перейти к следующему разряду
>
return c;
>
int main()
<
char a[1000] = < 0 >;
char b[1000] = < 0 >;
char ahex[1000] = < 0 >;
char bhex[1000] = < 0 >;
char *rhex;
char r[1000] = < 0 >;
cout "a = " ;
cin.getline(a, 1000);
cout "b = " ;
cin.getline(b, 1000);
dectox(a, 10, 16, ahex);
dectox(b, 10, 16, bhex);
cout "ahex = " ahex "h" endl;
cout "bhex = " bhex "h" endl;
rhex = and (ahex, bhex);
dectox(rhex, 16, 10, r);
cout a " & " b " = " rhex "h = " r endl;
rhex = or (ahex, bhex);
dectox(rhex, 16, 10, r);
cout a " | " b " = " rhex "h = " r endl;
rhex = xor (ahex, bhex);
dectox(rhex, 16, 10, r);
cout a " ^ " b " = " rhex "h = " r endl;
rhex = not (ahex);
dectox(rhex, 16, 10, r);
cout "

" ahex "h = " rhex "h = " r endl;
cin.get();
return 0;
>

Результат выполнения
2016 05 18 09 25 36 Домострой

В основу работы ЭВМ положены арифметические и логические операции с двоичными числами.

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

Таблица 3 – Арифметические действия над двоичными числами

Сложение Вычитание Умножение
0 + 0 = 0 0 – 0 = 0 0 ´ 0 = 0
0 + 1 = 1 1 – 0 = 1 0 ´ 1 = 0
1 + 0 = 1 1 – 1 = 0 1 ´ 0 = 0
1 + 1 = 10 10 – 1 = 1 1 ´ 1 = 1

Правила арифметики во всех позиционных системах счисления аналогичны. В двоичной системе арифметическое сложение происходит так же, как в десятичной системе с учетом переноса единицы в старший разряд.

Пример 1. Выполнить операцию арифметического сложения (см. рисунок 1.1) в двоичной системе счисления. Точками показаны переносы.

image001 Домострой

Рисунок 1.1. Пример выполнения сложения в 10-ной и 2-ной системах счисления.

Следует заметить, что в реальных ЭВМ чаще всего используются 16-, 32-, 64-разрядные сетки (машинные слова). Однако для учебных целей рассматривается простой вариант выполнения операции сложения

Поскольку для построения цифровых устройств (ЭВМ) была выбрана двоичная система счисления, то основой для построения элементов компьютерной системы и для разработки алгоритмов программ является аппарат алгебры логики или булевой алгебры.

Логические функции «И», «ИЛИ», «НЕ» представляют собой функционально полную систему, с их помощью можно получить любое сложное высказывание из простых.

В сложных выражениях, сначала выполняется операция (отрицание «НЕ»), затем image002 Домострой(конъюнкция «И») и в последнюю очередь image003 Домострой(дизъюнкция «ИЛИ»). На основе этих логических функций и соответствующих электронных элементов выполняются более сложные функциональные узлы.

Отрицание можно представить с помощью следующей таблицы истинности (см. таблицу 4):

Таблица 4 – Логическая функция «отрицание»

image004 Домострой image005 Домострой

Конъюнкцию можно представить с помощью следующей таблицы истинности (см. таблицу 5):

Таблица 5 – Логическая функция «конъюнкция»

image006 Домострой image007 Домострой image008 Домострой

Поскольку результат конъюнкции похож на результат обычного умножения чисел 0 и 1, эту операцию часто называют логическим умножением.

Дизъюнкцию можно представить с помощью следующей таблицы истинности (см. таблицу 6):

Таблица 6 – Логическая функция «дизъюнкция»

image009 Домострой image010 Домострой image011 Домострой

Дизъюнкцию иногда называют логическим сложением, но здесь аналогия "портится" четвертой строчкой.

Не нашли то, что искали? Воспользуйтесь поиском:

Выполнить логические побитовые операции "И", "ИЛИ" и др. над числами 5 и 6. Выполнить над числом 5 побитовый сдвиг вправо и влево на два знака. Объяснить полученный результат.

Обычно в языках программирования предусмотрены так называемые логические побитовые операции. Они выполняются не над самими числами, а над их двоичным представлением. Например, число 5 в двоичной системе счисления выражается как 101, а число 6 — как 110. Выполняя логическую побитовую операцию "И" получим число 4, т.к. в младшим разряде числа 5 стоит 1, а числа 6 — 0. Выражение "1 и 0" возвращает 0. Продолжая поразрядно выполнять логическое "И" в среднем разряде получим 0, а в старшем 1. Можно записать так:
101

100
Двоичное число 100 — это десятичное число 4.

Выполним операцию побитового логического "ИЛИ":
101

111 — это число 7.

"Исключающее ИЛИ":
101

011 — это число 3.

При сдвиге биты просто сдвигаются на указанное количество ячеек в освободившиеся ячейки дописываются нули или единицы (это зависит от ряда причин):
110 > 2 = 001 (число 1).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *