Я ищу хорошую математическую библиотеку произвольной точности на C или C ++. Не могли бы вы дать мне несколько советов или предложений?
Основные требования:
Он должен обрабатывать сколь угодно большие целые числа - меня больше всего интересуют целые числа. В случае, если вы не знаете, что означает слово «произвольно большой», представьте себе что-то вроде 100000! (факториал 100000).
Точность не требуется указывать во время инициализации библиотеки или создания объекта. Точность должна только быть ограничена имеющимися ресурсами системы.
Он должен использовать всю мощь платформы и изначально обрабатывать «небольшие» числа. Это означает, что на 64-битной платформе при вычислении (2 ^ 33 + 2 ^ 32) должны использоваться доступные 64-битные инструкции ЦП. Библиотека не должна рассчитывать это так же, как с (2 ^ 66 + 2 ^ 65) на той же платформе.
Он должен эффективно обрабатывать сложение (
+
), вычитание (-
), умножение (*
), целочисленное деление (/
), остаток (%
), мощность (**
), приращение (++
), декремент (--
), НОД, факториал и другие общие целочисленные арифметические вычисления. Возможность обрабатывать такие функции, как квадратный корень и логарифм, которые не дают целочисленных результатов, является плюсом. Способность обрабатывать символьные вычисления еще лучше.
Вот что я нашел на данный момент:
Java «s BigInteger и BigDecimal класс: Я использую это до сих пор. Я прочитал исходный код, но не понимаю математики под ним. Возможно, это основано на теориях и алгоритмах, которым я никогда не учился.
Встроенный целочисленный тип или основные библиотеки bc , Python , Ruby , Haskell , Lisp , Erlang , OCaml , PHP , некоторых других языков: я использовал некоторые из них, но не знаю, какую библиотеку они используют, или какую реализацию они используют.
Что я уже знал:
Используется
char
для десятичных цифр иchar*
для десятичных строк, а вычисления цифрfor
выполняются с помощью -loop.Использование
int
(илиlong int
, илиlong long
) в качестве базовой «единицы» и массива этого типа в качестве произвольного длинного целого числа и выполнение вычислений с элементами с использованиемfor
-loop.Использование целочисленного типа для хранения десятичной цифры (или нескольких цифр) как BCD (десятичное число с двоичным кодом) .
Чего я не знаю:
- Печать упомянутого выше двоичного массива в десятичном виде без использования наивных методов. Пример наивного метода: (1) сложить биты от младшего к старшему: 1, 2, 4, 8, 16, 32,… (2) использовать
char*
-строку, упомянутую выше, для хранения промежуточных десятичных результатов).
Что я ценю:
Хорошие сравнения GMP , MPFR , decNumber (или других, на ваш взгляд, хороших библиотек).
Хорошие предложения по книгам и статьям, которые я должен прочитать. Например, иллюстрация с фигурами в то, как не-наивные преобразованиях алгоритма работа двоичных к-десятичном будет хорошо. Статья Дугласа У. Джонса « Преобразование двоичного числа в десятичное с ограниченной точностью » является примером хорошей статьи.
Любая помощь в целом.
Пожалуйста , не отвечайте на этот вопрос, если считаете, что с помощью double
(или long double
, или long long double
) можно легко решить эту проблему. Если вы так думаете, значит, вы не понимаете, о чем идет речь.
источник
Ответы:
GMP - популярный выбор. В Squeak Smalltalk есть очень хорошая библиотека, но она написана на Smalltalk.
Вы просили соответствующие книги или статьи. Сложная часть bignum - деление в столбик. Я рекомендую статью Пера Бринча Хансена « Возвращение к разделу множественной длины: обзор минного поля» .
источник
char *
(каждаяchar
представляет собой десятичную цифру) или кint *
строке BCD ( каждаяint
представляет 4/8/16 цифр BCD). Однако мне интересно, имитируют ли библиотеки реального уровня производства "метод бумаги и карандаша", поскольку он слишком медленный.100,000,000,000,000,000 / 333,333,333,333
: Первый шаг - сравнить100,000,000,000
с333,333,333,333
. Поскольку первое меньше второго, расчет просто переходит к следующей цифре. Второй шаг - найти частное от1,000,000,000,000 / 333,333,333,333
, это включает либо умножение333,333,333,333 * 1
(и* 2
,* 3
и* 4
) методом проб и ошибок , либо последовательное вычитание в цикле. Вы видите, насколько он медленный? Я считаю, что существуют более эффективные алгоритмы.В целом, GMP является самой быстрой универсальной библиотекой произвольной точности . Если вы хотите работать со значениями с плавающей запятой, посмотрите библиотеку MPFR . MPFR основан на GMP.
Что касается встроенной поддержки произвольной точности на других языках, Python использует свою собственную реализацию из-за лицензии, размера кода и переносимости кода. Модуль GMPY позволяет Python получить доступ к библиотеке GMP.
источник
См. TTMath , небольшую шаблонную библиотеку только для заголовков, бесплатную для личного и коммерческого использования.
источник
Я сам не сравнивал между собой арифметические библиотеки произвольной точности, но люди, которые, похоже, более или менее единообразно придерживаются GMP. Как бы то ни было, целые числа произвольной точности в GHC Haskell и GNU Guile Scheme реализованы с использованием GMP, а самая быстрая реализация теста pidigits для языковой выборки основана на GMP.
источник
А что насчет Пари ? Он построен на основе GMP и предоставляет все другие полезные свойства операций с теорией чисел, которые вам когда-либо понадобятся (и многие вещи для символических вычислений).
источник