шестнадцатеричная арифметика в c ++ - PullRequest
0 голосов
/ 26 ноября 2018

Я хочу сделать основную арифметику (сложение, вычитание и сравнение) с шестнадцатеричными 64-значными числами, представленными в виде строк.например

"ffffa"+"2" == "ffffc"

Поскольку двоичное представление такого числа требует 256 бит, я не могу преобразовать строку в базовые целочисленные типы.одно из решений - использовать gmp или boost/xint, но они слишком велики для этой простой функции.

Есть ли более легкое решение, которое может мне помочь?

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Просто напишите библиотеку, которая будет обрабатывать строки с преобразованием между hex и int и добавлять по одному символу за раз, заботясь о переполнении.Для реализации такого алгоритма потребовались минуты:

#include <cstdio>
#include <sstream>
#include <iostream>

using namespace std;

namespace hexstr {
    char int_to_hexchar(int v) {
        if (0 <= v && v <= 9) {
            return v + '0';
        } else {
            return v - 10 + 'a';
        }
    }
    int hexchar_to_int(char c) {
        if ('0' <= c && c <= '9') {
            return c - '0';
        } else {
            return c - 'a' + 10;
        }
    }
    int add_digit(char a, char b) {
        return hexchar_to_int(a) + hexchar_to_int(b);
    }
    void reverseStr(string& str) { 
        int n = str.length(); 
        for (int i = 0; i < n / 2; i++) 
            swap(str[i], str[n - i - 1]); 
    }
    void _add_val_to_string(string& s, int& val) {
        s.push_back(int_to_hexchar(val % 16));
        val /= 16;
    }
    string add(string a, string b)
    {
        auto ita = a.end();
        auto itb = b.end();
        int tmp = 0;
        string ret;

        while (ita != a.begin() && itb != b.begin()) {
            tmp += add_digit(*--ita, *--itb);
            _add_val_to_string(ret, tmp);
        }
        while (ita != a.begin()) {
            tmp += hexchar_to_int(*--ita);
            _add_val_to_string(ret, tmp);
        }
        while (itb != b.begin()) {
            tmp += hexchar_to_int(*--itb);
            _add_val_to_string(ret, tmp);
        }
        while (tmp) {
            _add_val_to_string(ret, tmp);
        }

        reverseStr(ret);

        return ret;
    }
}

int main()
{
    std::cout 
        << "1bd5adead01230ffffc" << endl
        << hexstr::add(
                std::string() + "dead0000" + "00000" + "ffffa", 
                std::string() + "deaddead" + "01230" + "00002"
        ) << endl;
    return 0;
}

Это можно оптимизировать, строку реверсирования можно пропустить, а некоторые циклы ЦП и распределение памяти сэкономили.Также отсутствует обработка ошибок.Он будет работать только на реализациях, которые используют таблицу ASCII в качестве набора символов и т. Д. Но это так просто.Я полагаю, что эта небольшая библиотека может обрабатывать любые шестнадцатеричные строки длиной более 64 цифр, в зависимости только от памяти хоста.

0 голосов
/ 26 ноября 2018

Самостоятельно реализовать сложение, вычитание и сравнение на числовых строках с фиксированной базой должно быть довольно просто.

Например, для сложения и вычитания просто сделайте это, как в статье: начните с правой стороныконец обеих строк, парсинг char s, вычисление результата, затем перенос и т. д. Сравнение еще проще, и вы идете слева направо.

Конечно, все это предполагает, что выпроизводительность не нужна (в противном случае вы должны использовать правильную библиотеку).

...