Обзор библиотек для работы с большими числами в C++
Порой в C++ нужно работать с большими числами. Для этой цели существуют разные библиотеки. Но так ли они удобны и можно ли найти альтернативу?
При работе с криптографией или с адресами IPv6 часто возникает потребность в арифметике с очень большими числами. В этой статье рассмотрим, как разные библиотеки C/C++ выполняют эту функцию на примере перемножения двух больших чисел и расскажем о ещё одном предложении рабочей группы.
Российская рабочая группа по стандартизации C++ разрабатывает предложения по улучшению работы с языком и выносит их на обсуждении Международного комитета по стандартизации. Уже шесть внесенных рабочей группой предложений приняты и будут внесены в стандарт, ещё 12 находятся на рассмотрении.
OpenSSL
В OpenSSL есть встроенный механизм работы с большими числами. Возвести большое число в квадрат можно так:
Это скорее код на C, а не на C++. От этого работать с ним в среде с исключениями — небезопасно, и грозит утечками памяти.
Gcrypt
Библиотека libgcrypt родилась из проекта GnuPG и предоставляет базовые функции для работы с шифрованием, а в том числе и с большими числами. С этой библиотекой наш пример выглядел бы вот так:
Проблемы всё те же — мы получаем код на C, в котором самому нужно следить за ресурсами.
GMP
Предыдущие две библиотеки были заточены на использование в криптографии. GMP — специализированная библиотека, работающая только с числами. С её помощью возведение в квадрат можно было бы сделать так:
Выглядит уже лучше и понятнее, но это всё ещё код на C.
Boost.Multiprecision
Эта библиотека не реализует арифметику с большими числами сама, а лишь предоставляет удобный C++ интерфейс для работы с ними, используя сторонние библиотеки в качестве backend для вычислений. Насколько интерфейс удобен — судите сами:
Предложение в стандарт
Использовать сторонние библиотеки для такой часто возникающей задачи затратно как по памяти, так и по производительности. Российские разработчики из Национальной рабочей группы по стандартизации C++ считают так же, поэтому они составили предложение по включению целочисленных типов произвольной ширины в стандартную библиотеку. В нашем случае пример выглядел бы так:
Хотите работать с числами, занимающими мегабайт памяти? Не проблема, вот так например можно подсчитать 100! :
Возможно, мы увидим это предложение в стандартной библиотеке уже в C++23. Прототип доступен по этой ссылке , а самые любопытные могут всегда прочесть самый свежий текст предложения здесь.
Игорь Клевенец, разработчик Яндекса
Антон Полухин, разработчик Яндекс.Такси