Які найкращі (портативні) міжплатформні математичні бібліотеки довільної точності? [зачинено]


81

Я шукаю хорошу математичну бібліотеку довільної точності на C або C ++. Не могли б ви дати мені кілька порад чи пропозицій?

Основні вимоги:

  1. Він повинен обробляти довільно великі цілі числа - мій головний інтерес - цілі числа. Якщо ви не знаєте, що означає слово довільно велике, уявіть щось на зразок 100000! (факторіал 100000).

  2. Не потрібно вказувати точність під час ініціалізації бібліотеки або створення об’єкта. Точність повинна тільки бути обмежена наявними ресурсами системи.

  3. Він повинен використовувати повну потужність платформи і повинен обробляти “малі” номери. Це означає, що на 64-бітній платформі для обчислення (2 ^ 33 + 2 ^ 32) слід використовувати доступні 64-бітні інструкції процесора. Бібліотека не повинна обчислювати це так само, як це робить з (2 ^ 66 + 2 ^ 65) на тій же платформі.

  4. Він повинен ефективно обробляти додавання ( +), віднімання ( -), множення ( *), ціле ділення ( /), залишок ( %), потужність ( **), приріст ( ++), зменшення ( --), GCD, факторіал та інші загальні цілі арифметичні розрахунки. Здатність обробляти такі функції, як квадратний корінь і логарифм, які не дають цілочисельних результатів, є плюсом. Здатність обробляти символічні обчислення ще краща.

Ось що я знайшов на даний момент:

  1. Java «s BigInteger і BigDecimal клас: Я використовую це до сих пір. Я прочитав вихідний код, але не розумію математику внизу. Він може базуватися на теоріях та алгоритмах, яких я ніколи не вивчав.

  2. Вбудований цілочисельний тип або в основні бібліотеки bc , Python , Ruby , Haskell , Lisp , Erlang , OCaml , PHP , деяких інших мов: я використовував деякі з них, але не знаю, яку бібліотеку вони використовують, або який вид реалізації вони використовують.

Що я вже знав:

  1. Використовуючи charдля десяткових цифр і char*для десяткових рядків, і робіть обчислення для цифр, використовуючи for-loop.

  2. Використовуючи int(або long int, або long long) як основну “одиницю”, а масив цього типу як довільне довге ціле число, та forобчислюйте елементи за допомогою -loop.

  3. Використання цілочисельного типу для зберігання десяткової цифри (або кількох цифр) як BCD (двійково кодований десятковий) .

  4. Алгоритм множення Бута .

Чого я не знаю:

  1. Друк двійкового масиву, згаданого вище, у десятковій таблиці без використання наївних методів. Приклад наївного методу: (1) додати біти від найнижчого до найвищого: 1, 2, 4, 8, 16, 32,… (2) використовувати char*-строку, згадану вище, для зберігання проміжних десяткових результатів).

Що я ціную:

  1. Хороші порівняння на GMP , MPFR , decNumber (або інших бібліотеках, які, на вашу думку, хороші).

  2. Хороші пропозиції щодо книг та статей, які я повинен прочитати. Наприклад, непоганою була б ілюстрація з малюнками про те, як працює неївний алгоритм перетворення двійкового в десяткове. Стаття “ Бінарне в десяткове перетворення з обмеженою точністю ” Дугласа В. Джонса є прикладом хорошої статті.

  3. Будь-яка допомога загалом.

Будь ласка , не відповідайте на це запитання, якщо ви вважаєте, що використання double(або long double, або long long double) може легко вирішити цю проблему. Якщо ви так думаєте, ви не розумієте суть питання.


3
Наскільки я бачу, GMP здається непоганою бібліотекою. Мені цікаво, чому існує необхідність у співавторах Python / Haskell / Erlang / etc перевинайти колесо. Якщо GMP настільки хороший, чому б не покладатися на нього? Ліцензія GPL / LGPL може бути однією з проблем, але, незважаючи на це (а також на проблему режиму округлення), чи існують інші недоліки GMP? Чи є вбудоване ціле число Python / Haskell / Erlang / будь-якої бібліотеки криптографії швидше, ніж GMP? Якщо так, я хотів би витягти та використати його, якщо дозволить ліцензія.
Siu Ching Pong -Asuka Kenji-

Я знайшов гарну статтю на cs.uiowa.edu/~jones/bcd/decimal.html Дугласа В. Джонса. У статті описаний метод перетворення 16-бітового цілого числа в десяткове подання з використанням лише 8-бітової цілочисельної арифметики. Ідея полягає в тому, щоб розбити 16-бітове число на 4 гризки, кожен з яких представляє "цифру" базової цифри 16. Отже, цифра-0 (n0) представляє x1, n1 => x16, n2 => x256, n3 => x4096. Тоді очевидно, що цифра-0 десяткового числа (d0) є цифрою-0 результату n0 * 1 + n1 * 6 + n2 * 6 + n3 * 6. Правильно обробляючи перенесення, d1 до d4 може також обчислюється.
Siu Ching Pong -Asuka Kenji-

Однак, наскільки я міг собі уявити, ідею Дугласа вище не можна було поширити на обробку довільно довгих двійкових цілих чисел. Це тому, що цифри 1 (16 ^ 0), 16 (16 ^ 1), 256 (16 ^ 2) та 4096 (16 ^ 3) попередньо обчислюються. Потім проблема стає, як представити 16 ^ n у десятковому для довільно великого n.
Siu Ching Pong -Asuka Kenji-

Відповіді:


24

GMP - популярний вибір. У Squeak Smalltalk є дуже приємна бібліотека, але вона написана на Smalltalk.

Ви попросили відповідні книги чи статті. Хитра частина бінгума - довгий поділ. Я рекомендую статтю Пер Брінча Хансена « Відділ багатометражності»: «Перегляд мінного поля» .


Дякуємо за посилання на статтю! Так, я погоджуюсь, що поділ - це найбільш хитра частина. Я давно знав, як робити поділ вручну за допомогою "методів паперу та олівця" :-), і, отже, той самий метод можна застосувати до десяткового рядка char *(кожен із яких charпредставляє десяткову цифру) або int *рядка BCD ( кожен intпредставляє 4/8/16 цифр BCD). Однак мені цікаво, чи бібліотеки реального виробництва імітують "метод паперу та олівця", оскільки це занадто повільно.
Siu Ching Pong -Asuka Kenji-

Щоб зрозуміти чому, давайте уявимо, як це працює 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), або послідовне віднімання у циклі. Ти бачиш, наскільки це повільно? Я вважаю, що існують більш ефективні алгоритми.
Siu Ching Pong -Asuka Kenji-

3
@Sui: Брінч Хенсон показує, як можна зменшити метод проб і помилок до максимум двох випробувань. Це справді дуже вражає.
Норман Ремзі,

Гаразд, дозвольте мені детальніше розглянути папір. Дякую!
Siu Ching Pong -Asuka Kenji-

1
Я не впевнений, де ви в результаті знайшли своє рішення, а також який формат ви використовували для зберігання цифр, але формат COMP-3 COBOL nybble набагато приємніший, оскільки він більш компактний, кожен 4 біт зберігає 0-9 значення І, вам не потрібно віднімати шістнадцяткове значення 30 від значення символу ASCII, щоб отримати придатну цифру.

13

Загалом, найшвидшою бібліотекою довільної точності загального призначення є GMP . Якщо ви хочете працювати зі значеннями з плаваючою комою, перегляньте бібліотеку MPFR . MPFR базується на GMP.

Щодо підтримки рідної довільної точності іншими мовами, Python використовує власну реалізацію через ліцензію, розмір коду та причини перенесення коду. Модуль GMPY дозволяє Python отримувати доступ до бібліотеки GMP.


Спасибі за вашу відповідь! Ви згадали про "переносимість коду". Не могли б ви пояснити, в чому проблема? Я думав, що GMP є портативним і підтримується на основних платформах ...
Сіу Чінг Понг -Асука Кендзі-

2
"переносимість коду" не те саме, що "підтримується на основних платформах". Python використовує просту реалізацію, яка робить дуже мало припущень про поведінку компілятора C, тому той самий код може компілювати майже на будь-якому компіляторі C. GMP використовує більше коду (C та високоналагоджена збірка), що робить GMP швидшим, але також робить більше припущень про поведінку компілятора та асемблера C. Наприклад, GMP погано підтримується компіляторами Microsoft Visual Studio. Існує форк GMP під назвою MPIR (www.mpir.org), який підтримує компілятори Microsoft.
casevh

Розумію. Це означає, що реалізація Python більше схожа на ANSI C, тоді як реалізація GMP використовує __asm-трюки ... Дякуємо за пояснення.
Siu Ching Pong -Asuka Kenji-

8

Дивіться TTMath , невелику шаблонну бібліотеку лише для заголовків, безкоштовну для особистого та комерційного використання.


Гей! Це проста у використанні бібліотека, і, схоже, вона використовує потужність центрального процесора і використовує деяку магію шаблону C ++ для завершення роботи. Чудова бібліотека! +1 для вас!
Siu Ching Pong -Asuka Kenji-

Так, і він має дозвільну ліцензію BSD, яка не має копілелів.
plasmacel

Зі сторінки вище: "Наскільки великими можуть бути значення, встановлюється під час компіляції." - отже, це не відповідає вимогам.
osxdirk

7

Я сам не порівнював арифметичні бібліотеки довільної точності між собою, але люди, які, здається, більш-менш рівномірно зупинились на GMP. Наскільки це варте, цілі числа довільної точності в GHC Haskell та GNU Guile Scheme реалізовані за допомогою GMP, і найшвидша реалізація тесту pidigits на мовній перестрілці базується на GMP.


Дякую! ^ ___ ^ Приємна інформація!
Siu Ching Pong -Asuka Kenji-

4

А як щодо Парі ? Він побудований на найкращому GMP і надає всі інші смаки щодо операцій з теорії чисел, які вам коли-небудь знадобляться (і багато символічних матеріалів для обчислень).


Привіт fortran (!), Це виглядає добре! Дякуємо за вашу інформацію!
Siu Ching Pong -Asuka Kenji-

Ласкаво просимо :-) Також за допомогою Pari ви можете скочувати швидкі прототипи за допомогою GP, і коли ви задоволені, напишіть оптимізовану версію C (і я думаю, що вона поставляється з компілятором GP-> C, щоб допомогти і в цьому)
fortran
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.