#include <iostream>
#include <locale>
#include <iomanip>
using namespace std;

// Ìàññèâ ñèìâîëîâ äëÿ hex
const char hex_chars[] = "0123456789ABCDEF";

// Ôóíêöèÿ äëÿ ïðåîáðàçîâàíèÿ äàííûõ â áàéòû
const uint8_t* to_bytes(const void* data) {
    return reinterpret_cast<const uint8_t*>(data);
}

// Ôóíêöèÿ äëÿ ïðåîáðàçîâàíèÿ ïîëóáàéòà â hex ñèìâîë
char half_byte_to_hex(uint8_t i) {
    return hex_chars[i & 0xf];
}

// Ôóíêöèÿ äëÿ ïå÷àòè áàéòà â hex ôîðìàòå
void print_hex(uint8_t byte) {
    cout << half_byte_to_hex(byte >> 4)
         << half_byte_to_hex(byte & 0xf);
}

// Ôóíêöèÿ äëÿ ïå÷àòè äàííûõ â hex ôîðìàòå
void print_hex(const void* data, size_t size) {
    const uint8_t *bytes = to_bytes(data);
    for (size_t i = 0; i < size; i++) {
        print_hex(bytes[i]);
        if ((i + 1) % 16 == 0) {
            cout << '\n';
        } else {
            cout << ' ';
        }
    }
}

// Ôóíêöèÿ äëÿ ïîëó÷åíèÿ áèòà èç áàéòà
char get_bit(uint8_t byte, uint8_t bit) {
    return (byte & (0x1 << bit)) ? '1' : '0';
}

// Ôóíêöèÿ äëÿ ïå÷àòè áàéòà â binary ôîðìàòå
void print_binary(uint8_t byte) {
    for (int bit = 7; bit >= 0; bit--) {
        cout << get_bit(byte, bit);
    }
}

// Ôóíêöèÿ äëÿ ïå÷àòè äàííûõ â binary ôîðìàòå
void print_binary(const void* data, size_t size) {
    const uint8_t *bytes = to_bytes(data);
    for (size_t i = 0; i < size; i++) {
        print_binary(bytes[i]);
        if ((i + 1) % 4 == 0) {
            cout << '\n';
        } else {
            cout << ' ';
        }
    }
}

// Ôóíêöèÿ äëÿ âûâîäà ðåçóëüòàòîâ â âèäå òàáëè÷êè
void print_results_table(uint16_t num1, uint16_t num2, uint16_t result, const char* operation) {
    cout << "| Îïåðàíä 1 (HEX) | Îïåðàíä 2 (HEX) | Ðåçóëüòàò (HEX) |\n";
    cout << "|-----------------|-----------------|-----------------|\n";
    cout << "| ";
    print_hex(&num1, sizeof(uint16_t));
    cout << " | ";
    print_hex(&num2, sizeof(uint16_t));
    cout << " | ";
    print_hex(&result, sizeof(uint16_t));
    cout << " |\n\n";

    cout << "| Îïåðàíä 1 (BIN) | Îïåðàíä 2 (BIN) | Ðåçóëüòàò (BIN) |\n";
    cout << "|-----------------|-----------------|-----------------|\n";
    cout << "| ";
    print_binary(&num1, sizeof(uint16_t));
    cout << " | ";
    print_binary(&num2, sizeof(uint16_t));
    cout << " | ";
    print_binary(&result, sizeof(uint16_t));
    cout << " |\n";
}

int main() {
    setlocale(LC_ALL, "Russian");
    uint16_t num1, num2, result = 0;
    char operation[8];
    bool is_calculated = false;

    cout << "Ââåäèòå âûðàæåíèå: ";
    cin >> num1 >> operation >> num2;

    switch (operation[0]) {
    case '&':
        result = num1 & num2;
        is_calculated = true;
        break;
    case '|':
        result = num1 | num2;
        is_calculated = true;
        break;
    case '^':
        result = num1 ^ num2;
        is_calculated = true;
        break;
    default:
        cout << "Íåèçâåñòíàÿ îïåðàöèÿ\n";
        break;
    }

    if (is_calculated) {
        print_results_table(num1, num2, result, operation);
    }

    cin >> result;
    return 0;
}