Dlouhá aritmetika

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 21. ledna 2022; kontroly vyžadují 2 úpravy .

Dlouhé aritmeticko - aritmetické operace  prováděné pomocí počítače ( sčítání , odčítání , násobení , dělení , umocňování , elementární funkce ) na číslech, jejichž bitová hloubka přesahuje délku strojového slova tohoto počítače. Tyto operace jsou realizovány nikoli hardwarově, ale softwarově, s využitím základního hardwaru pro práci s čísly nižších řádů. Speciální případ - aritmetika s libovolnou přesností  - se týká aritmetiky, ve které je délka čísel omezena pouze velikostí dostupné paměti.

Aplikace

Dlouhá aritmetika se používá v následujících oblastech:

Požadovaný hardware pro práci s dlouhou aritmetikou

Přísně vzato, k implementaci aritmetiky s libovolnou přesností je od procesoru vyžadováno pouze nepřímé adresování ; v aritmetice s pevnou přesností se dokonce obejdete i bez ní. Některé funkce procesoru však zrychlují dlouhou aritmetiku a zároveň zjednodušují jeho programování.

Implementace v programovacích jazycích

Programovací jazyky mají vestavěné datové typy, které obecně nepřesahují 64 bitů (asi 10 19 ). Desítková dlouhá aritmetika byla implementována v sovětských programovacích jazycích ALMIR-65 na počítači MIR-1 a ANALYTIK na počítači MIR-2 . Pro práci s velkými čísly existuje v moderních programovacích jazycích poměrně málo hotových optimalizovaných knihoven pro dlouhou aritmetiku.

Většina funkčních jazyků vám umožňuje přepnout z běžné aritmetiky na dlouhou aritmetiku, aniž byste museli měnit aritmetický kód. Například Erlang a Scheme vždy představují přesná čísla stejně dlouhá. Ve Standard ML jsou implementace všech variant celých čísel určovány na základě signatury INTEGER, což vám umožňuje vybrat požadovanou dimenzi, včetně modulu IntInf, který implementuje celá čísla s libovolnou přesností; implementace PolyML tento modul standardně používá.

Existují vestavěné knihovny pro práci s velkými čísly v PascalABC.NET, Ruby , Python a Java .

Algoritmy

Násobící algoritmy

Následující reprezentace celých čísel se obvykle používá k popisu algoritmů. Je vybrána základna . Celé číslo délky pak může být reprezentováno jako [1] :

kde

Základní

Jde o algoritmus podle školní metody "ve sloupci". Chce to čas , kde  jsou velikosti násobených čísel.

Algoritmus může být reprezentován jako [1] [2] :

Algoritmus 1 BasecaseMultiply
Input: Output: for from to do




Násobení Karatsuba

Karatsubova metoda násobení patří do paradigmatu „ rozděl a panuj “. Výpočetní složitost algoritmu:

.

Tento algoritmus je jednoduchou implementací [3] myšlenky rozdělení vstupních dat, která se stala základem pro algoritmy uvedené níže. Cílem je rozdělit jednu operaci násobení na -ciferných číslech na tři operace násobení na číslech délky plus [1] .

K vynásobení dvou čísel větších než je strojové slovo se Karatsubův algoritmus volá rekurzivně, dokud nejsou čísla dostatečně malá, aby je bylo možné přímo násobit. Příklad takového algoritmu:

Algoritmus 2 KaratsubaMultiply
Vstup: Výstup: KaratsubaMultiply KaratsubaMultiply KaratsubaMultiply







Pojďme počítat :

Je třeba vypočítat tři mezilehlé koeficienty:

Výsledek:

Toomův algoritmus

Tento algoritmus je zobecněním algoritmu Karatsuba a je rychlejší. Jsou-li dána dvě celá čísla a , Toomův algoritmus je rozdělí na menší části, z nichž každá je rovna délce strojového slova, a provádí s těmito částmi operace. Výpočetní složitost algoritmu:

Algoritmus Tooma-3

Myšlenku poprvé navrhl A. L. Toom v roce 1963 [4] , spočívá v rozdělení vstupních dat (násobičů) na 3 stejné části (pro zjednodušení jsou všechny části považovány za stejné). Toom-3 snižuje počet základních operací násobení z 9 na 5. Složitost algoritmu

Zvažte tento algoritmus v následujícím příkladu. Nechť jsou dvě čísla a . Nechť jsou operace definovány na číslech, jejichž velikost je rovna 1/3 velikosti původních čísel (viz obrázek). Předpokládáme také, že čísla zabírají stejnou paměť a jsou dělitelná přesně na 3 části, jinak obě čísla doplníme nulami na požadovanou velikost.

Poté dochází k zobrazení (parametrizaci) těchto částí na polynomy 2. stupně.

Uveďme podle definice takové, že hodnoty polynomů jsou rovny vstupním číslům a . Pro bitovou reprezentaci čísel je toto číslo dvě na mocninu rovnající se délce každé části v bitech.

Zavedeme také polynom:

(jeden)

Poté, co jsou prvky určeny  - koeficienty polynomu , budou použity k získání , protože . Velikost koeficientů je 2krát větší (z paměti) než oddíl nebo . Konečné číslo rovnající se součinu lze nalézt sečtením s posunem, jak je znázorněno na obrázku níže.

Koeficienty lze vypočítat následovně: a tak dále, ale to bude vyžadovat všech 9 násobení: pro i je j=0,1,2 a bude ekvivalentní jednoduchému násobení.

Místo toho byl zvolen jiný přístup. se počítají v (1) na 5 bodech pro různé .

Níže uvedená tabulka ukazuje hodnoty polynomů v rovnici (1)

Parametr je podmíněný. Znamená to banální rovnost koeficientů na , takže hodnotu dostaneme okamžitě. Tento systém je lineární v 5 neznámých. Když se to vyřeší, dostaneme neznámé . Dále získáme hodnotu polynomu, jak je popsáno výše.

Algoritmus Tooma-4

Složitost algoritmu Představuje 7 základních operací násobení. Toom-4 rozdělí vstup na 4 části.

Na stejném principu jako v Toom-3 sestavíme dva polynomy:

a jsou počítány v 7 různých bodech, počítá se také hodnota v těchto bodech.

odkud se hned dostaneme
odkud se hned dostaneme

Počet operací sčítání a násobení pro Toom-4 je mnohem větší než pro Toom-3. Některé výrazy se ale vyskytují více než jednou. Například počítáno pro a pro [5] .

Toomův algoritmus pro libovolný oddíl

Toomův algoritmus pro dělení vstupních čísel na n operandů je ekvivalentní výše popsanému. Obecně platí, že rozdělení dvou stejně dlouhých operandů na části vede k výpočtu hodnot bodů . Jako body za vyřešení systému většinou berou .

Fourierovo násobení

Tento násobící algoritmus se používá pro velká a velmi velká čísla [6] .

Tento algoritmus násobí dvě čísla v čase , kde  je počet platných číslic ve vynásobených číslech (za předpokladu, že jsou stejná). Vytvoření je připisováno Cooley (Coolet) a Tyuki (Tukey) - 1965. Existují také návrhy, že tento algoritmus byl znám již dříve, ale neměl velký význam před vynalezením prvních počítačů. Pravděpodobní kandidáti na autorství vynálezu tohoto algoritmu se také nazývají Runge (Runge) a Koenig (Konig) - 1924, stejně jako Gauss - 1805.

Nechť existuje číslo, znázorníme ho jako polynom, jak jsme to udělali dříve. Nazvěme tento polynom Také zavedeme diskrétní Fourierovu transformaci polynomu jako vektor se souřadnicemi . Kde jsou definovány jako  - komplexní odmocnina tého stupně z 1, nerovná se 1. Faktem je, že komplexní odmocnina z 1 je definována až do fázového faktoru, počet těchto kořenů je . Fourierova transformace je použita za účelem nahrazení konvoluce koeficientů polynomů a :  - součinem jejich Fourierových obrazů.

kde násobení znamená skalární součin vektorů.

Předpokládejme, že existuje mocnina dvou.

Hledání se provádí rekurzivně (rozděl a panuj). Cílem je rozdělit původní polynom na dva polynomy,

Pak .

Všimněte si, že ze všech čísel jsou pouze různá. Proto bude DFT -element . A protože DFT se skládá z prvků, pak komplexní kořen 1 bude kořenem stupně .

Prostředek,

kde a

Použili jsme vlastnosti komplexních čísel: různé kořeny stupně všeho . .

Získáme rekurzivní algoritmus:
DFT jednoho prvku se rovná tomuto prvku
, abychom našli DFT A, rozdělíme koeficienty A na sudé a liché, dostaneme dva polynomy a , najdeme pro ně DFT, najdeme DFT : pro . Existuje důkaz následujícího tvrzení: Inverzní DFT se nalézá podobně jako přímá DFT s tím rozdílem, že body jsou brány jako body, které jsou symetrické podle skutečné osy, místo těch, které se používají v přímé transformaci DFT. Je také nutné vydělit všechny koeficienty polynomu n



Algoritmy extrakce kořenů

Druhá odmocnina

Jedním z algoritmů druhé odmocniny je algoritmus Karatsuba Square Root. Toto je zdaleka nejznámější metoda pro výpočet druhé odmocniny n - ciferného čísla. Tento algoritmus využívá rychlou Fourierovu transformaci a Newtonovu metodu se složitostí 5 M ( n ) [7] .

Prezentovaný algoritmus je založen na dělení Burnickel-Ziegler (Burnikel-Ziegler) Karatsuba. Vzhledem k celému číslu n algoritmus vypočítá současně jeho celočíselnou odmocninu a odpovídající zbytek, což je Toto není asymptoticky optimální, ale v praxi velmi efektivní s řádovou složitostí operací, kde K ( n ) je počet operací potřebných k vynásobení dvě n - bitová čísla pomocí algoritmu Karatsuba. Důvodem této nízké složitosti je krásná divize Karatsuba, kterou nedávno objevili Burnickel a Ziegler, a pečlivé zacházení se zbytky, které se vyhýbá zbytečným výpočtům.

Věta . Počet operací, které používá algoritmus SqrtRem s 2n - bitovým vstupem, je omezený

kde K ( n ) je počet operací potřebných k vynásobení 2 n -bitových čísel pomocí Karatsubova algoritmu.

Algoritmus SqrtRem Vstup: s výstupem: takový, že pokud se vrátí

Algoritmy pro převod číselné soustavy

Předpokládejme, že převádíte ze základu b na základ B [8] .

Způsoby převodu celých čísel


Metoda 1 (Dělení B pomocí reprezentace čísel se základem b). Pro dané celé číslo u lze
získat reprezentaci ve formátu základního B formuláře , tím, že uděláme

, , , do .


Metoda 2 (Násobení B pomocí reprezentace báze b). Pokud má reprezentace čísla u v základu b tvar , pak pomocí aritmetických operací s čísly, která jsou reprezentována ve formátu v základu B, můžete získat polynom ve tvaru (( .


Metoda 1 (a) (Násobení b pomocí základní B reprezentace čísel). Pro dané zlomkové číslo a můžete vypočítat hodnoty číslic jeho reprezentace v základu B takto: , , ,… kde {x} znamená xmod1 = x- . Pro zaokrouhlení výsledku na M číslic lze výpočet po obdržení přerušit , a pokud je {…{{uВ}В}...В} větší než 1/2, pak by se hodnota měla zvýšit o jednu. (Upozorňujeme však, že tato operace může vést k nutnosti provádět překlady, které by měly být zahrnuty do výsledku pomocí aritmetických operací v základu B. Před zahájením výpočtů by bylo jednodušší přidat k původnímu číslu u konstantu , ale to může vést k nesprávnému výsledku, pokud v počítači nelze číslo přesně vyjádřit ve formátu základu b. Všimněte si také, že je možné zaokrouhlit výsledek na if ). Metoda 2 (a) (Násobení B pomocí reprezentace báze b). Pokud má reprezentace čísla a v základu b tvar , pak pomocí aritmetických operací s čísly, která jsou uvedena ve formátu v základu B, můžete získat polynom ve tvaru ((… + …) + .


Způsoby převodu zlomkových čísel


Metoda 1 (b) (Násobení b pomocí základní B reprezentace čísel). Pro dané zlomkové číslo u můžete vypočítat hodnoty bitů jeho reprezentace v základu B takto: , , ,… kde {x} znamená xmod1 = x- . Pro zaokrouhlení výsledku na M číslic lze výpočet po obdržení přerušit , a pokud je {…{{uВ}В}...В} větší než 1/2, pak by se hodnota měla zvýšit o jednu. (Upozorňujeme však, že tato operace může vést k nutnosti provádět překlady, které by měly být zahrnuty do výsledku pomocí aritmetických operací v základu B. Před zahájením výpočtů by bylo jednodušší přidat k původnímu číslu u konstantu , ale to může vést k nesprávnému výsledku, pokud v počítači nelze číslo přesně vyjádřit ve formátu základu b. Všimněte si také, že je možné zaokrouhlit výsledek na if ).


Metoda 2 (b) (Dělení b pomocí reprezentace čísel na bázi B). Pokud je číslo u reprezentováno v základu b jako , pak pomocí aritmetických operací v základu B lze vypočítat jako . Je nutné pečlivě sledovat chyby, ke kterým dochází při ořezávání nebo zaokrouhlování při operaci dělení b; jsou obvykle bezvýznamné, ale není tomu tak vždy.

Vícenásobná přesná transformace


Nejpohodlnější je začít s převodem velmi dlouhých čísel převodem bloků bitů, s nimiž lze operace provádět s jedinou přesností. Tyto bloky pak zkombinujete pomocí jednoduchých metod, které jsou specifické pro vícenásobnou přesnost. Například nechť 10n je nejvyšší mocnina o 10 menší než velikost strojového slova. Potom:
a) pro převod celého čísla "Číslo s násobnou přesností z binárního na desítkové je nutné jej vynásobit 10n (tedy převést z binárního na desítkové se základem 10n metodou 1, a); pomocí operací s jedinou přesností, získáme n desetinných míst pro každou reprezentační jednotku v základu 10n;
b) pro převod zlomkové části „Část čísla s vícenásobnou přesností z binárního na desetinné postupujte obdobným způsobem vynásobením : (tj. pomocí metody 2, a, kde B \u003d 10n); c) pro převod celého čísla s násobnou přesností z desítkové na binární nejprve převedeme bloky o n bitech; potom pro převod ze základu 10n na binární použijte metodu 1, b; d) Chcete-li převést zlomkovou část s vícenásobnou přesností z desítkové na binární, nejprve převeďte na základ 10n jako v postupu (c) a poté použijte metodu 2, b.

Algoritmy dělení

Výsledkem algoritmu pro dělení n-bitového čísla u n-bitovým číslem v musí být dvě n-bitová čísla - u mod v a u div v. Algoritmy popsané níže nejsou v praxi použitelné, protože jako výsledek dělení naleznou reálné číslo a ne dvě n-bitová čísla.

Teoreticky, pro dělení n-bitového čísla u n-bitovým číslem v, můžete nejprve najít n-bitovou aproximaci k číslu 1/v, pak ji vynásobit u, čímž získáte aproximaci k , a nakonec proveďte další násobení, abyste provedli malou opravu, abyste se ujistili, že nerovnost platí . Na základě výše uvedeného stačí mít účinný algoritmus, který by z daného n-bitového čísla vytvořil přibližnou hodnotu čísla, které je inverzní k n-bitovému číslu. Dále použijte algoritmus pro násobení n-bitových čísel. [9]


Algoritmus R (Získání reciproční hodnoty s vysokou přesností) Nechť číslo v má binární reprezentaci , kde . Tento algoritmus vypočítá aproximaci z čísla tak, že . R1 (počáteční odhad) Přiřadit a . R2 (Newton Iteration) Zde máme číslo z v binárním tvaru se znaménky za dělicím bodem a . Počítejte přesně pomocí programu rychlého násobení . Poté spočítejte kde přesně . Pak přiřaďte , kde , která vyhovuje nerovnosti , se podle potřeby přidá k zaokrouhlení tak , aby byl násobkem . A nakonec přiřadit . R3 If , pak se vraťte ke kroku R2; jinak se provádění algoritmu ukončí.



Jiné algoritmy

Poznámky

  1. 1 2 3 Richard P. Brent a Paul Zimmermann, Moderní počítačová aritmetika
  2. Donald E. Knuth „Umění počítačového programování“, oddíl 4.3.1
  3. Donald E. Knuth „Umění počítačového programování“, oddíl 4.3.3, část A
  4. Zprávy Akademie věd SSSR 150 (1963), 496-498
  5. Toom 4-cestné násobení - GNU MP 5.1.3 . Získáno 13. prosince 2013. Archivováno z originálu dne 14. března 2013.
  6. Donald E. Knuth „Umění počítačového programování“, oddíl 4.3.3, část C
  7. Paul Zimmermann. Karatsuba druhá odmocnina. [Výzkumná zpráva] RR-3805, 1999, s.8. < inria-00072854 Archivováno 2. prosince 2014 na Wayback Machine >
  8. Donald E. Knuth „Umění počítačového programování“, svazek 2, oddíl 4.4
  9. Donald E. Knuth „Umění počítačového programování“, svazek 2, oddíl 4.3.3

Literatura

  • Donald E. Knuth, " The Art of Computer Programming ", svazek 2, "Seminumerical Algorithms", 3. vydání, Addison-Wesley, 1998
  • Dan Zuras, "On Squaring and Multiplying Large Integers", ARITH-11: IEEE Symposium on Computer Arithmetic, 1993, str. 260 až 271.
  • DAN SSSR 150 (1963), 496-498
  • Richard P. Brent a Paul Zimmermann, Moderní počítačová aritmetika
  • Elektronické prostředky a řídicí systémy: Sborník zpráv z Mezinárodní vědecko-praktické konference (13.-16. října 2010). - Tomsk: V-Spectrum, 2011: Ve 2 hodiny - Část 2.  - 178 s. ISBN 978-5-91191-223-6 , s.123-129