Arytmetyka dowolnej precyzji (ang. arbitrary-precision arithmetic), znana również jako arytmetyka bignum, wielokrotnej precyzji lub nieskończonej precyzji – sposób wykonywania obliczeń komputerowych, w którym dokładność obliczeń jest ograniczona jedynie dostępną pamięcią RAM komputera. Arytmetyka ta operuje na dużych liczbach typu integer (całkowitych). Przezwyciężono w ten sposób ograniczenia zakresu dotychczas stosowanych zapisów liczb całkowitych, których wielkości były ograniczone przez rozmiar rejestru procesora: do 32 bitów (w rejestrach 32-bitowych) lub do 64 bitów (w rejestrach 64-bitowych).
Operacje arytmetyczne wykonywane są blokowo, na poszczególnych słowach. Np. dodawanie dwóch liczb, zapisanych za pomocą tablic słów
jest realizowane od prawej strony do lewej według schematu:
gdzie oznacza przeniesienie (carry) nadmiarowego bitu z wyniku dodawania słów .
Takie podejście zapobiega powstania przepełnienia arytmetycznego (overflow), które występuje przy przekroczeniu zakresów liczb 32- i 64-bitowych, ponieważ liczba słów maszynowych, w jakich jest zapisywany wynik, jest programowo rozszerzana w pamięci operacyjnej w miarę potrzeby. Jednocześnie operacje na małych wartościach są optymalizowane i wykonywane w sposób zbliżony do typów natywnych procesora, co zapewnia dobrą wydajność w typowych zastosowaniach.
Arytmetyka dowolnej precyzji znajduje zastosowanie tam, gdzie wymagane są dokładne obliczenia, na przykład w bankowości, oraz tam, gdzie konieczne jest operowanie na bardzo dużych liczbach, na przykład w kryptografii. Jest również wykorzystywana do obliczania podstawowych stałych matematycznych, takich jak liczba , z dokładnością do milionów lub większej liczby cyfr, oraz do analizy właściwości ciągów cyfr tych liczb. Ponadto stosuje się ją do badania precyzyjnego zachowania funkcji, takich jak funkcja dzeta Riemanna, w przypadkach, gdy pewne własności są trudne do analizy metodami analitycznymi. Innym zastosowaniem jest generowanie obrazów fraktalnych przy ekstremalnie dużych powiększeniach, na przykład zbioru Mandelbrota.
Arytmetyka dowolnej precyzji w językach programowania W niektórych językach programowania obsługę dużych liczb całkowitych zapewniają specjalne biblioteki (np. GMP dla C). W języku Python v.3 czy Ruby zmienne, reprezentujące liczby całkowite, mają dynamiczne rozmiary, tj. zapisywane są jako struktury złożone z wielu słów maszynowych, o rozmiarach zależnych od rejestru, np. za pomocą 32 lub 64 bitów, a ilość słów jest powiększana w miarę wzrostu wartości zmiennej. Ograniczeniem może być tylko pamięć RAM komputera.
Przykładowe zastosowanie – silnia w Pythonie + Wybrane wartości silni 0 1 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40 320 9 362 880 10 3 628 800 11 39 916 800 12 479 001 600 13 6 227 020 800 14 87 178 291 200 15 1 307 674 368 000 16 20 922 789 888 000 17 355 687 428 096 000 18 6 402 373 705 728 000 19 121 645 100 408 832 000 20 2 432 902 008 176 640 000 25 ∼1,551 121 004 · 1025 50 ~3,041 409 32 · 1064 70 ~1,197 857 167 · 10100 100 ~9,332 621 544 · 10157 450 ~1,733 368 733 · 101000 1000 ~4,023 872 601 · 102567 10 000 ~2,846 259 681 · 1035 659 100 000 ~2,824 229 408 · 10456 573 1 000 000 ~8,263 931 688 · 105 565 708 10 000 000 ~1,202 423 401 · 1065 657 05910100 ~109,956 570 552 · 10101 W klasycznych typach całkowitoliczbowych zakres możliwych do obliczenia wartości silni jest ograniczony. 32-bitowych typu całkowitego można obliczyć najwyżej wartość(9 cyfr). Dla liczb 64-bitowych typu całkowitego można maksymalnie obliczyć(20 cyfr).
Dla większych argumentów konieczne jest zastosowanie arytmetyki wielkiej precyzji. W języku Python liczby całkowite mają dowolną precyzję, co umożliwia bezpośrednie obliczanie dużych wartości silni. Przykładowa implementacja ma postać: def silnia(n): s=1 for i in range(2,n+1): s=s*i return s
# Przykład n=1558 wynik = silnia(n) print("Liczba cyfr =", len(str(wynik))) print("n =", n, "silnia =", wynik) Przykładowo, wartość 1558! zawiera około 4300 cyfr:
(w przybliżeniu ).
Dla bardzo dużych wartości n bezpośrednie obliczanie silni staje się nieefektywne lub niemożliwe ze względu na ograniczenia pamięciowe. W takich przypadkach stosuje się metody przybliżone, oparte m.in. na logarytmach oraz funkcji gamma.
Poniższy przykład wykorzystuje bibliotekę mpmath do wyznaczenia liczby cyfr oraz pierwszych cyfr rozwinięcia n!:!pip install mpmath import mpmath import time
# Dane ------------------------------------- n=10**100 # dana liczba m = 10 # ile pierwszych cyfr dokładnych w wyniku
# Konfiguracja precyzji mpmath (liczba cyfr znaczących) mpmath.mp.dps = m + 10 print(f"n={n} - liczenie n! metodą wysokiej precyzji (mpmath)...") start_time = time.perf_counter()
# 1. Obliczamy log10(n!) używając wysokiej precyzji loggamma # log10(x) = ln(x) / ln(10) ln_fact = mpmath.loggamma(n + 1) log10_fact = ln_fact / mpmath.log(10)
# 2. Liczba cyfr (część całkowita + 1) liczba_cyfr = mpmath.floor(log10_fact) + 1
# 3. Wyciągamy pierwsze m cyfr # Mantysa logarytmu dziesiętnego mantysa = log10_fact - mpmath.floor(log10_fact)
# Pierwsze cyfry to 10^mantysa # Przesuwamy przecinek o m-1 miejsc pierwsze_cyfry_raw = mpmath.power(10, mantysa) wynik_finalny = int(pierwsze_cyfry_raw * mpmath.power(10, m - 1))
end_time = time.perf_counter()
print("-" * 45) print(f"Całkowita liczba cyfr: {int(liczba_cyfr)}") print(f"Pierwsze {m} cyfr: {wynik_finalny}") print(f"Czas obliczeń: {end_time - start_time:.6f} s") print("-" * 45)Dla silnia wynosi w przybliżeniu:
Zobacz też
GNU Multiple Precision Arithmetic Library MPSolve OpenSSL
Bibliografia
BigInteger Struct (System.Numerics). docs.microsoft.com. Retrieved 2026-04-26.
Kategoria:Komputerowe reprezentacje danych