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

Алгоритмизация / Логические операции над многоразрядными числами

Рассмотрим выполнение логических операций И, ИЛИ, Исключающее ИЛИ и НЕ над многоразрядными числами.
Основная особенность выполнения побитовых логических операций над такими числами состоит в том, что каждое из них предварительно необходимо перевести в систему счисления с основанием, кратным 2, и только после этого выполнять логические операции. При необходимости результат можно снова перевести в десятичную систему счисления.
О переводе многоразрядных чисел в различные системы счисления подробно описано в этой статье.
Выполнение бинарной логической операции (то есть операции над двумя числами) осуществляется в следующем порядке:

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

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

#include <iostream>
using namespace std;// Перевод цифры в символ
char digittochar(int num) { КОД }// Перевод символа в цифру
int digittoint(char num) { КОД }// Функция перевода q-ичного числа в систему счисления с основанием p
int dectox(char *a, int q, int p, char *c) { КОД }
// Функция ИЛИ
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] = '\0'; // завершающий нуль-символ результата
  k--;
  for (int i = lena - 1, j = lenb - 1; i >= 0 || j >= 0; i--, j--) {
    char dig1 = i < 0 ? 0 : digittoint(a[i]); // если разряд отсутствует, взять 0
    char dig2 = j < 0 ? 0 : digittoint(b[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] = '\0'; // завершающий нуль-символ результата 
  k--;
  for (int i = lena - 1, j = lenb - 1; i >= 0 || j >= 0; i--, j--) {
    char dig1 = i < 0 ? 0 : digittoint(a[i]); // если разряд отсутствует, взять 0
    char dig2 = j < 0 ? 0 : digittoint(b[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] = '\0'; // завершающий нуль-символ результата
  k--;
  for (int i = lena - 1, j = lenb - 1; i >= 0 || j >= 0; i--, j--) {
    char dig1 = i < 0 ? 0 : digittoint(a[i]); // если разряд отсутствует, взять 0
    char dig2 = j < 0 ? 0 : digittoint(b[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] = '\0'; // завершающий нуль-символ результата
  k--;
  for (int i = lena - 1; i >= 0; i--) {
    char dig1 = i < 0 ? 0 : digittoint(a[i]); // если разряд отсутствует, взять 0
    char dig = (~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 << "~" << a << " = ~" << ahex << "h = " << rhex << "h = " << r << endl;
  cin.get();
  return 0;
}

Результат выполнения

Результат логических операций над многоразрядными числами

Назад

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

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