Как добавить 2 целых числа произвольного размера в C ++?

Я хотел бы добавить 2 целых числа произвольного размера в C ++. Как я могу это сделать?

Вот пример, показывающий, как использовать реализацию OpenSSL bignum для арифметики произвольной точности. Мой пример делает 2 64 + 2 65 . Я использую Linux.

#include  #include  #include  int main(int argc, char *argv[]) { static const char num1[] = "18446744073709551616"; static const char num2[] = "36893488147419103232"; BIGNUM *bn1 = NULL; BIGNUM *bn2 = NULL; BN_CTX *ctx = BN_CTX_new(); BN_dec2bn(&bn1, num1); // convert the string to BIGNUM BN_dec2bn(&bn2, num2); BN_add(bn1, bn1, bn2); // bn1 = bn1 + bn2 char *result_str = BN_bn2dec(bn1); // convert the BIGNUM back to string printf("%s + %s = %s\n", num1, num2, result_str); OPENSSL_free(result_str); BN_free(bn1); BN_free(bn2); BN_CTX_free(ctx); return 0; } 

Он производит этот вывод:

 18446744073709551616 + 36893488147419103232 = 55340232221128654848 

Необходимо установить OpenSSL с библиотеками разработки. Если у вас Linux, установите библиотеку разработки из диспетчера пакетов и свяжите ее с libcrypto.so .

 g++ bignum.cpp -o bignum -lcrypto 

Или загрузите источник OpenSSL и создайте статическую библиотеку libcrypto.a и соединитесь с ней статически.

 g++ bignum.cpp -o bignum -I./openssl-1.0.0/include ./openssl-1.0.0/libcrypto.a 

В Windows вам необходимо установить из порта Windows OpenSSL.

Используя оператор + ?

Я хотел бы добавить 2 целых числа произвольного размера в C ++. Как я могу это сделать?

Если вы хотите выполнить многоточную математику самостоятельно, я предлагаю вам взглянуть на искусство программирования Дональда Кнута. Я считаю, что Том II, Семинумерные алгоритмы, Глава 4, Арифметика с несколькими точками – это то, что вас интересует. Кнут дает вам все детали.

Обработка больших чисел на C ++? также дает ссылку на интересную статью. Вероятно, вам следует прочитать его, если вы выполняете собственную реализацию. (Другие подобные вопросы не имеют ссылки. Благодаря @herohuyongtao для его предоставления).

Помимо ответа @indiv на использование OpenSSL в C, вы можете использовать Botan или Crypto ++ . Оба являются библиотеками C ++, и оба они примерно такие же старые, как OpenSSL. Я удивлен, что ответы не были предоставлены для них, учитывая, что ваш вопрос отмечен C ++.

Если у вас есть C ++ 11 или unique_ptr , вы можете использовать их для кода OpenSSL C. unique_ptr действительно подбирает вещи. Ниже приведен пример.


Ботан

Вот программа:

 $ cat test.cxx #include "botan/bigint.h" #include  int main() { using Botan::BigInt; BigInt num1("18446744073709551616"); BigInt num2("36893488147419103232"); std::cout << num1 + num2 << std::endl; std::cout << std::hex << "0x" << num1 + num2 << std::endl; return 0; } 

И построение из каталога библиотеки (целесообразность):

 $ g++ -I ./build/include test.cxx ./libbotan-2.a -o test.exe $ ./test.exe 55340232221128654848 0x30000000000000000 

Crypto ++

Вот программа:

 $ cat test.cxx #include "cryptlib.h" #include "integer.h" #include  int main() { using CryptoPP::Integer; Integer num1("18446744073709551616"); Integer num2("36893488147419103232"); std::cout << num1 + num2 << std::endl; std::cout << std::hex << "0x" << num1 + num2 << std::endl; return 0; } 

И построение из каталога библиотеки (целесообразность):

 $ g++ -I . test.cxx ./libcryptopp.a -o test.exe $ ./test.exe 55340232221128654848. 0x30000000000000000h 

OpenSSL

Вот программа для C ++ и OpenSSL. BN_obj "имеет" BIGNUM , и он использует unique_ptr для управления ресурсами.

 $ cat test.cxx #include "openssl/bn.h" #include "openssl/err.h" #include  #include  #include  #include  #include  class BN_obj { using BN_ptr = std::unique_ptr; using BN_CTX_ptr = std::unique_ptr; public: BN_obj() : m_bn(BN_Zero_Helper(), ::BN_free) {} BN_obj(const char* str) : m_bn(BN_Asciiz_Helper(str), ::BN_free) {} BN_obj(const BN_obj& obj) : m_bn(BN_Copy_Helper(obj.m_bn), ::BN_free) {} BN_obj& operator=(const BN_obj& obj) { if(this != &obj) m_bn.reset(BN_dup(obj.m_bn.get())); return *this; } BN_obj Plus(const BN_obj& obj) const { BN_obj result; if (BN_add(result.m_bn.get(), m_bn.get(), obj.m_bn.get()) != 1) { std::ostringstream msg; unsigned long err = ERR_get_error(); msg << "BN_add failed, error 0x" << std::hex << err; throw std::runtime_error(msg.str()); } return result; } BN_obj Minus(const BN_obj& obj) const { BN_obj result; if (BN_sub(result.m_bn.get(), m_bn.get(), obj.m_bn.get()) != 1) { std::ostringstream msg; unsigned long err = ERR_get_error(); msg << "BN_sub failed, error 0x" << std::hex << err; throw std::runtime_error(msg.str()); } return result; } BN_obj Times(const BN_obj& obj) const { BN_obj result; BN_CTX_ptr ctx(BN_CTX_new(), ::BN_CTX_free); if (BN_mul(result.m_bn.get(), m_bn.get(), obj.m_bn.get(), ctx.get()) != 1) { std::ostringstream msg; unsigned long err = ERR_get_error(); msg << "BN_sub failed, error 0x" << std::hex << err; throw std::runtime_error(msg.str()); } return result; } friend std::ostream& operator<<(std::ostream& out, const BN_obj& obj); protected: static BIGNUM* BN_Zero_Helper() { BIGNUM* z = BN_new(); BN_zero(z); return z; } static BIGNUM* BN_Asciiz_Helper(const char* str) { BIGNUM* t = BN_new(); if(!t) throw std::bad_alloc(); if(BN_dec2bn(&t, str) == 0) { std::ostringstream msg; unsigned long err = ERR_get_error(); msg << "BN_dec2bn failed, error 0x" << std::hex << err; throw std::runtime_error(msg.str()); } return t; } static BIGNUM* BN_Copy_Helper(const BN_ptr& obj) { return BN_dup(obj.get()); } private: BN_ptr m_bn; }; BN_obj operator+(const BN_obj& a, const BN_obj& b) { return a.Plus(b); } BN_obj operator-(const BN_obj& a, const BN_obj& b) { return a.Minus(b); } BN_obj operator*(const BN_obj& a, const BN_obj& b) { return a.Times(b); } std::ostream& operator<<(std::ostream& out, const BN_obj& obj) { const long f = out.flags() & std::ios::basefield; char* ptr = nullptr; if(f == std::ios::hex) { ptr = BN_bn2hex(obj.m_bn.get()); out << ptr; } else if(f == std::ios::dec) { ptr = BN_bn2dec(obj.m_bn.get()); out << ptr; } else throw std::runtime_error("Not implemented"); if(ptr) OPENSSL_free(ptr); return out; } int main() { const char z1[] = "18446744073709551616"; const char z2[] = "36893488147419103232"; BN_obj num1(z1); BN_obj num2(z2); std::cout << num1 + num2 << std::endl; std::cout << std::hex << "0x" << num1 + num2 << std::endl; return 0; } 

И построение из каталога библиотеки (целесообразность):

 $ g++ -I ./include test.cxx ./libcrypto.a -o test.exe -ldl -pthread $ ./test.exe 55340232221128654848 0x30000000000000000 
Давайте будем гением компьютера.