Szukam dobrej biblioteki matematycznej o dowolnej precyzji w C lub C ++. Czy mógłbyś dać mi jakieś rady lub sugestie?
Podstawowe wymagania:
To musi obsługiwać dowolnie duże liczby całkowite, moim głównym zainteresowaniem jest na liczby całkowite. Jeśli nie wiesz, co oznacza słowo arbitralnie duże, wyobraź sobie coś w rodzaju 100000! (silnia 100000).
Nie trzeba określać dokładności podczas inicjowania biblioteki lub tworzenia obiektów. Precyzja powinny tylko być ograniczany przez dostępne zasoby systemu.
To powinna wykorzystać pełną moc platformy i powinien obsługiwać „małych” numery natywnie. Oznacza to, że na platformie 64-bitowej obliczenia (2 ^ 33 + 2 ^ 32) powinny wykorzystywać dostępne 64-bitowe instrukcje procesora. Biblioteka nie powinna obliczać tego w taki sam sposób, jak robi to z (2 ^ 66 + 2 ^ 65) na tej samej platformie.
To musi skutecznie obsługiwać dodawania (
+
), odejmowanie (-
), mnożenia (*
), podział całkowita (/
) reszta (%
) zasilania (**
) przyrost (++
) zmniejszania (--
), GCD czynnikowe, i inne zwykłe całkowitą arytmetycznych obliczeń. Możliwość obsługi funkcji, takich jak pierwiastek kwadratowy i logarytm, które nie dają wyników w postaci liczb całkowitych, jest plusem. Zdolność do obsługi obliczeń symbolicznych jest jeszcze lepsza.
Oto, co do tej pory znalazłem:
Java „s BigInteger i BigDecimal klasa: I zostały z wykorzystaniem ich do tej pory. Przeczytałem kod źródłowy, ale nie rozumiem matematyki pod spodem. Może opierać się na teoriach i algorytmach, których nigdy się nie poznałem.
Wbudowany typ liczby całkowitej lub w podstawowych bibliotekach bc , Python , Ruby , Haskell , Lisp , Erlang , OCaml , PHP , kilka innych języków: użyłem niektórych z nich, ale nie mam pojęcia, której biblioteki używają, lub jakiego rodzaju implementacji używają.
Co już wiedziałem:
Używanie
char
do cyfr dziesiętnych ichar*
ciągów dziesiętnych oraz wykonywanie obliczeń na cyfrach przy użyciufor
-loop.Używanie
int
(lublong int
, lublong long
) jako podstawowej „jednostki” i tablicy tego typu jako dowolnej długiej liczby całkowitej i wykonuj obliczenia na elementach za pomocąfor
-loop.Używanie typu całkowitego do przechowywania cyfry dziesiętnej (lub kilku cyfr) jako BCD (dziesiętne kodowane binarnie) .
Czego nie wiem:
- Wydruk powyższej tablicy binarnej w postaci dziesiętnej bez stosowania naiwnych metod. Przykład naiwnej metody: (1) dodaj bity od najniższego do najwyższego: 1, 2, 4, 8, 16, 32,… (2) użyj
char*
-string wspomnianego powyżej do przechowywania pośrednich wyników dziesiętnych).
Co doceniam:
Dobre porównania na temat GMP , MPFR , decNumber (lub innych bibliotek, które są według Ciebie dobre).
Dobre sugestie dotyczące książek i artykułów, które powinienem przeczytać. Na przykład, ilustracja z postaciami, w jaki sposób a nie naiwne binary-to-przecinku działania algorytmu konwersji będzie dobrze. Artykuł „ Zamiana liczb dwójkowych na dziesiętne z ograniczoną precyzją ” autorstwa Douglasa W. Jonesa jest przykładem dobrego artykułu.
Wszelka pomoc w ogóle.
Proszę nie odpowiadać na to pytanie, jeśli uważasz, że użycie double
(lub long double
lub long long double
) może rozwiązać ten problem łatwo. Jeśli tak myślisz, nie rozumiesz problemu.
źródło
Odpowiedzi:
GMP to popularny wybór. Squeak Smalltalk ma bardzo ładną bibliotekę, ale jest napisana w Smalltalk.
Poprosiłeś o odpowiednie książki lub artykuły. Trudną częścią bignum jest długi podział. Polecam artykuł Pera Brincha Hansena Multiple-Length Division Revisited: A Tour of the Minefield .
źródło
char *
(każdychar
reprezentuje cyfrę dziesiętną) lubint *
ciągu BCD ( każdaint
reprezentująca 4/8/16 cyfr BCD). Zastanawiam się jednak, czy biblioteki na poziomie produkcyjnym w świecie rzeczywistym naśladują „metodę papieru i ołówka”, ponieważ jest zbyt wolna.100,000,000,000,000,000 / 333,333,333,333
: Pierwszym krokiem jest porównanie100,000,000,000
z333,333,333,333
. Ponieważ pierwsza jest mniejsza niż druga, obliczenia po prostu przechodzą do następnej cyfry. Drugim krokiem jest znalezienie ilorazu1,000,000,000,000 / 333,333,333,333
, co obejmuje mnożenie metodą prób i błędów333,333,333,333 * 1
(i* 2
,* 3
i* 4
) lub wykonywanie kolejnych odejmowań w pętli. Czy widzisz, jakie to powolne? Uważam, że istnieją wydajniejsze algorytmy.Ogólnie najszybszą biblioteką arbitralnej precyzji ogólnego przeznaczenia jest GMP . Jeśli chcesz pracować z wartościami zmiennoprzecinkowymi, spójrz na bibliotekę MPFR . MPFR jest oparty na GMP.
Jeśli chodzi o natywną obsługę dowolnej precyzji w innych językach, Python używa własnej implementacji ze względu na licencję, rozmiar i przenośność kodu. GMPY moduł umożliwia dostęp Pythona biblioteki GMP.
źródło
Zobacz TTMath , małą bibliotekę z szablonami zawierającą tylko nagłówki, bezpłatną do użytku osobistego i komercyjnego.
źródło
Sam nie porównywałem ze sobą bibliotek arytmetycznych o arbitralnej precyzji, ale ludzie, którzy wydają się mieć mniej lub bardziej jednolite podejście do GMP. Co jest warte, liczby całkowite o arbitralnej precyzji w GHC Haskell i GNU Guile Scheme są zaimplementowane przy użyciu GMP, a najszybsza implementacja testu porównawczego pidigits w strzelaninie językowej jest oparta na GMP.
źródło
A co z Pari ? Jest zbudowany na najwyższym GMP i zapewnia wszystkie inne korzyści związane z operacjami teorii liczb, których kiedykolwiek będziesz potrzebować (i wiele symbolicznych rzeczy obliczeniowych).
źródło