Algoritmus dělení - Division algorithm
A algoritmus dělení je algoritmus které, vzhledem k tomu, dvě celá čísla N a D, počítá jejich kvocient a / nebo zbytek, výsledek Euklidovské dělení. Některé jsou aplikovány ručně, zatímco jiné jsou využívány návrhy digitálních obvodů a softwarem.
Algoritmy dělení spadají do dvou hlavních kategorií: pomalé dělení a rychlé dělení. Algoritmy pomalého dělení vytvářejí jednu číslici konečného kvocientu na iteraci. Mezi příklady pomalého dělení patří obnovení, neprovedení obnovy, neobnovovat, a SRT divize. Metody rychlého dělení začínají těsnou aproximací konečného kvocientu a při každé iteraci produkují dvakrát tolik číslic konečného kvocientu. Newton – Raphson a Goldschmidt algoritmy spadají do této kategorie.
Varianty těchto algoritmů umožňují rychlé použití multiplikační algoritmy. Výsledkem je, že u velkých celých čísel počítačový čas potřebné pro dělení je stejné, až do konstantního faktoru, jako čas potřebný pro násobení, podle toho, který algoritmus násobení je použit.
Diskuse bude odkazovat na formulář , kde
- N = Čitatel (dividenda)
- D = Jmenovatel (dělitel)
je vstup a
- Q = Kvocient
- R = Zbývající část
je výstup.
Dělení opakovaným odečtením
Nejjednodušší algoritmus dělení, historicky začleněný do a největší společný dělitel algoritmus uvedený v Euklidova Elementy, Kniha VII, Proposition 1, najde zbytek daná dvě kladná celá čísla pouze pomocí odečtení a srovnání:
zatímco N ≥ D dělat N := N − Dkonecvrátit se N
Důkaz, že podíl a zbytek existují a jsou jedinečné (popsáno na Euklidovské dělení ) dává vzniknout úplnému algoritmu dělení pomocí sčítání, odčítání a porovnávání:
funkce rozdělit(N, D) -li D = 0 pak chyba(Dělení nulou) konec -li D < 0 pak (Q, R) := rozdělit(N, −D); vrátit se (−Q, R) konec -li N < 0 pak (Q,R) := rozdělit(−N, D) -li R = 0 pak vrátit se (−Q, 0) jiný vrátit se (−Q − 1, D − R) konec konec - V tomto okamžiku N ≥ 0 a D> 0 vrátit se divide_unsigned(N, D)konec funkce divide_unsigned(N, D) Q := 0; R := N zatímco R ≥ D dělat Q := Q + 1 R := R − D konec vrátit se (Q, R)konec
Tento postup vždy produkuje R ≥ 0. I když je velmi jednoduchý, vyžaduje kroky Ω (Q), a je tedy exponenciálně pomalejší než dokonce i algoritmy pomalého dělení, jako je dlouhé dělení. Je užitečné, pokud je známo, že Q je malý (je to algoritmus citlivý na výstup ) a může sloužit jako spustitelná specifikace.
Dlouhé dělení
Dlouhé dělení je standardní algoritmus používaný pro dělení víceciferných čísel vyjádřených v desítkové soustavě perem a papírem. Postupně se posouvá z levého na pravý konec dividendy a v každé fázi odečte největší možný násobek dělitele (na úrovni číslic); násobky se pak stanou číslicemi kvocientu a konečný rozdíl je pak zbytek.
Při použití s binárním radixem tvoří tato metoda základ pro (nepodepsané) celočíselné dělení s níže uvedeným algoritmem zbytku. Krátké dělení je zkrácená forma dlouhého dělení vhodná pro jednociferné dělitele. Kouskování - také známá jako metoda částečných kvocientů nebo metoda kata - je méně efektivní forma dlouhého dělení, která může být snáze srozumitelná. Tím, že umožníte jednomu odečíst více násobků, než jaké má aktuálně v každé fázi, lze také vyvinout volnější variantu dlouhého dělení[1]
Celé dělení (bez znaménka) se zbytkem
Následující algoritmus, binární verze slavného dlouhé rozdělení, se rozdělí N podle D, umístění kvocientu dovnitř Q a zbytek v R. V následujícím kódu jsou všechny hodnoty považovány za celá čísla bez znaménka.
-li D = 0 pak chyba(DivisionByZeroException) konecQ := 0 - Inicializujte kvocient a zbytek na nuluR := 0 pro i := n − 1 .. 0 dělat - Kde n je počet bitů v N R := R << 1 - Levý posun R o 1 bit R(0) := N(i) - Nastavte nejméně významný bit R rovný bitu čitatele -li R ≥ D pak R := R − D Q(i) := 1 koneckonec
Příklad
Vezmeme-li N = 11002 (1210) a D = 1002 (410)
Krok 1: Nastavte R = 0 a Q = 0 Krok 2: Nastavit i = 2 Krok 2: Nastavit i = 1 Krok 2: Nastavit i = 0 konec Metody pomalého dělení jsou založeny na standardní rovnici opakování [2] kde: Obnovující divize pokračuje pevný bod zlomková čísla a závisí na předpokladu 0 < D < N.[Citace je zapotřebí ] Číslice kvocientu q jsou tvořeny ze sady číslic {0,1}. Základní algoritmus pro binární (radix 2) obnovující dělení je: Výše uvedený algoritmus obnovení dělení se může vyhnout kroku obnovení uložením posunuté hodnoty 2R před odečtením v dalším registru T (tj., T = R << 1) a kopírování registru T na R když je výsledek odečtení 2R − D je negativní. Neprovádějící obnovovací dělení je podobné jako obnovení dělení kromě toho, že je uložena hodnota 2R, takže D není třeba přidávat zpět pro případ R <0. Neobnovující dělení používá pro číslice kvocientu místo {0, 1} sadu číslic {−1, 1}. Algoritmus je složitější, ale má tu výhodu, když je implementován do hardwaru, že existuje pouze jedno rozhodnutí a sčítání / odčítání na kvocientový bit; po odečtení neexistuje žádný krok obnovy, který potenciálně snižuje počet operací až o polovinu a umožňuje rychlejší provedení.[3] Základní algoritmus pro binární (radix 2) neobnovující dělení nezáporných čísel je: Podle tohoto algoritmu je kvocient v nestandardní formě skládající se z číslic −1 a +1. Tento formulář je třeba převést na binární, aby se vytvořil konečný kvocient. Příklad: Pokud -1 číslice jsou poté uloženy jako nuly (0) je a výpočetní technika je triviální: provést něčí doplněk (kousek po kousku) na originálu . Nakonec jsou podíly vypočítané tímto algoritmem vždy liché a zbytek v R je v rozsahu −D ≤ R Skutečný zbytek je R >> n. (Stejně jako u obnovovacího dělení jsou bity R řádu nižšího řádu spotřebovány stejnou rychlostí jako jsou vytvářeny bity kvocientu Q a pro oba je běžné používat jeden posuvný registr.) Divize SRT, pojmenovaná pro své tvůrce (Sweeney, Robertson a Tocher), je populární metodou pro dělení v mnoha mikroprocesor implementace.[4][5] SRT divize je podobná neobnovující divizi, ale používá a vyhledávací tabulka na základě dividendy a dělitele k určení každé číslice kvocientu. Nejvýznamnějším rozdílem je, že a nadbytečné zastoupení se používá pro kvocient. Například při implementaci dělení radix-4 SRT se vybírá každá číslice kvocientu Pět možnosti: {−2, −1, 0, +1, +2}. Z tohoto důvodu nemusí být volba číslice kvocientu dokonalá; pozdější číslice kvocientu mohou opravit drobné chyby. (Například páry digitálních kvocientů (0, +2) a (1, −2) jsou ekvivalentní, protože 0 × 4 + 2 = 1 × 4-2.) Tato tolerance umožňuje vybrat číslice kvocientu pouze pomocí několika nejvýznamnější bity dividendy a dělitele, spíše než vyžadovat odečítání celé šířky. Toto zjednodušení zase umožňuje použít radix vyšší než 2. Stejně jako neobnovující dělení jsou závěrečné kroky konečným odečtením celé šířky k vyřešení posledního kvocientu kvocientu a převodem kvocientu do standardní binární formy. The Intel Pentium procesor je neslavný chyba dělení s plovoucí desetinnou čárkou byla způsobena nesprávně kódovanou vyhledávací tabulkou. Pět z 1066 záznamů bylo omylem vynecháno.[6][7] Newton – Raphson používá Newtonova metoda najít reciproční z a vynásobte to vzájemně najít konečný kvocient . Kroky divize Newton – Raphson jsou: Aby bylo možné použít Newtonovu metodu k nalezení převrácené hodnoty , je nutné najít funkci který má nulu na . Zřejmá taková funkce je , ale Newton-Raphsonova iterace pro toto je neužitečná, protože ji nelze vypočítat, aniž bychom již neznali převrácenou hodnotu (navíc se pokouší spočítat přesný reciproční v jednom kroku, místo aby umožnil iterativní vylepšení). Funkce, která funguje, je , což dává iterace Newton – Raphson ze kterého lze vypočítat pomocí pouze násobení a odčítání nebo pomocí dvou fúzované násobení - dodává. Z hlediska výpočtu výrazy a nejsou ekvivalentní. Získání výsledku s přesností 2n bitů při použití druhého výrazu je třeba vypočítat součin mezi a s dvojnásobnou přesností (n bitů).[Citace je zapotřebí ] Naproti tomu produkt mezi a je třeba počítat pouze s přesností n bity, protože vedoucí n bitů (za binárním bodem) jsou nuly. Pokud je chyba definována jako , pak: Toto druhou mocninu chyby v každém iteračním kroku - tzv kvadratická konvergence Newton - Raphsonova metoda - má za následek, že počet správných číslic ve výsledku zhruba zdvojnásobí pro každou iteraci, vlastnost, která se stává nesmírně cennou, když mají zúčastněná čísla mnoho číslic (např. v doméně velkých celých čísel). Znamená to však také, že počáteční konvergence metody může být poměrně pomalá, zejména pokud se jedná o počáteční odhad je špatně vybrán. Pro dílčí problém výběru počátečního odhadu , je vhodné použít na dělitele bitový posun D měřítko tak, aby 0,5 ≤D ≤ 1; použitím stejného bitového posunu v čitateli N, jeden zajistí, že kvocient se nezmění. Pak by se dalo použít lineární přiblížení ve formě inicializovat Newton – Raphson. Minimalizovat maximum absolutní hodnoty chyby této aproximace na intervalu , jeden by měl použít Koeficienty lineární aproximace se stanoví následovně. Absolutní hodnota chyby je . Minimum maximální absolutní hodnoty chyby je určeno pomocí Čebyševova ekvioscilační věta aplikován na . Místní minimum nastane, když , který má řešení . Funkce na tomto minimu musí mít opačné znaménko jako funkce v koncových bodech, jmenovitě, . Dvě rovnice ve dvou neznámých mají jedinečné řešení a a maximální chyba je . Při použití této aproximace je absolutní hodnota chyby počáteční hodnoty menší než Je možné vygenerovat polynomiální přizpůsobení stupně většího než 1, výpočet koeficientů pomocí Remezův algoritmus. Kompromisem je, že počáteční odhad vyžaduje více výpočetních cyklů, ale doufejme, že výměnou za méně iterací Newton – Raphson. Protože pro tuto metodu konvergence je přesně kvadratický, z toho vyplývá kroky stačí k výpočtu hodnoty až binární místa. To odpovídá hodnotám 3 pro IEEE jediná přesnost a 4 pro oba dvojnásobná přesnost a dvojité prodloužení formáty. Následující výpočet kvocientu N a D s přesností na P binární místa: Například pro dělení s plovoucí desetinnou čárkou s dvojitou přesností používá tato metoda 10 násobení, 9 přidání a 2 posuny. Metodu dělení Newton-Raphson lze upravit tak, aby byla mírně rychlejší, a to následujícím způsobem. Po přeřazení N a D aby D je v [0,5, 1,0], inicializujte pomocí Toto je nejlepší kvadratické přizpůsobení 1 /D a udává absolutní hodnotu chyby menší nebo rovnou 1/99. Je vybráno tak, aby se chyba rovnala změněnému třetímu řádu Čebyševův polynom prvního druhu. Koeficienty by měly být předem vypočítány a pevně zakódovány. Pak ve smyčce použijte iteraci, která krychli chybu. The Y·E termín je nový. Pokud je smyčka provedena, dokud X nesouhlasí s 1 /D na jeho čele P bitů, pak počet iterací nebude větší než což je počet, kolikrát 99 musí být krychlový, aby se dostal na 2P+1. Pak je podíl k P bity. Použití polynomů vyššího stupně při inicializaci nebo iteraci vede ke snížení výkonu, protože potřebné vícenásobné násobení by bylo lépe vynaloženo na provádění více iterací. Divize Goldschmidt[8] (po Robertu Elliottu Goldschmidtovi[9]) používá iterativní proces opakovaného vynásobení dividendy i dělitele společným faktorem Fi, zvoleno tak, že dělitel konverguje k 1. To způsobí, že dividenda konverguje k hledanému kvocientu Q: Kroky pro divizi Goldschmidt jsou: Za předpokladu N/D byl změněn tak, aby 0 <D <1, každý Fi je založeno na D: Vynásobením dividendy a dělitele výnosy faktoru: Po dostatečném počtu k iterací . Metoda Goldschmidt se používá v AMD CPU Athlon a novější modely.[10][11] Je také známý jako algoritmus Anderson Earle Goldschmidt Powers (AEGP) a je implementován různými procesory IBM.[12][13] Metodu Goldschmidt lze použít s faktory, které umožňují zjednodušení pomocí binomická věta Předpokládejme, že měřítko N / D bylo změněno a síla dvou takhle .Vybíráme si a .To je výnos Po kroky , jmenovatel lze zaokrouhlit na s relativní chyba což je maximum na když , čímž poskytuje minimální přesnost binární číslice. Metody navržené pro implementaci hardwaru se obecně nezmění na celá čísla s tisíci nebo miliony desetinných míst; ty se často vyskytují například v modulární snížení v kryptografie. U těchto velkých celých čísel efektivnější dělící algoritmy transformují problém tak, aby používal malý počet násobení, které lze poté provést pomocí asymptoticky účinného multiplikační algoritmus tak jako Algoritmus Karatsuba, Násobení Toom – Cook nebo Schönhage – Strassenův algoritmus. Výsledkem je, že výpočetní složitost dělení je stejného řádu (až do multiplikativní konstanty) jako násobení. Mezi příklady patří redukce na násobení pomocí Newtonova metoda tak jako popsáno výše,[14] stejně jako o něco rychlejší Barrettova redukce a Montgomeryho redukce algoritmy.[15][je nutné ověření ] Newtonova metoda je obzvláště účinná ve scénářích, kdy je třeba mnohokrát dělit stejným dělitelem, protože po počáteční Newtonově inverzi je pro každé dělení potřeba pouze jedno (zkrácené) násobení. Dělení konstantou D je ekvivalentní násobení jeho reciproční. Jelikož je jmenovatel konstantní, je i jeho reciproční (1 /D). Je tedy možné vypočítat hodnotu (1 /D) jednou v době kompilace a v době běhu proveďte násobení N·(1/D) spíše než rozdělení N / D. v plovoucí bod aritmetika použití (1 /D) představuje malý problém, ale v celé číslo aritmetika bude reciproční vždy vyhodnocovat na nulu (za předpokladu |D| > 1). Není nutné používat konkrétně (1 /D); libovolná hodnota (X/Y), která se sníží na (1 /D) může být použit. Například pro dělení 3 lze použít faktory 1/3, 2/6, 3/9 nebo 194/582. V důsledku toho, pokud Y byla síla dvou, krok dělení by se snížil na rychlý posun bitů doprava. Účinek výpočtu N/D tak jako (N·X)/Y nahradí divizi násobením a posunem. Všimněte si, že závorky jsou důležité, protože N·(X/Y) vyhodnotí na nulu. Nicméně pokud D sama o sobě je síla dvou, není X a Y který splňuje výše uvedené podmínky. Naštěstí, (N·X)/Y dává přesně stejný výsledek jako N/D v celočíselné aritmetice, i když (X/Y) není přesně rovno 1 /D, ale „dostatečně blízko“, že chyba zavedená aproximací je v bitech, které jsou zahozeny operací posunu.[16][17][18] Jako beton aritmetika s pevným bodem například pro 32bitová celá čísla bez znaménka lze dělení 3 nahradit násobením 2863311531/233, násobení 2863311531 (hexadecimální 0xAAAAAAAB) následovaný 33bitovým posunem doprava. Hodnota 2863311531 se počítá jako 233/3, pak zaokrouhleno nahoru. Podobně dělení 10 lze vyjádřit jako násobení 3435973837 (0xCCCCCCCD) následované dělením 235 (nebo 35 pravý bitový posun). V některých případech lze dělení konstantou dosáhnout za ještě kratší dobu převedením „násobení konstantou“ na série posunů a sčítání nebo odčítání.[19] Zvláště zajímavé je dělení 10, pro které se získá přesný kvocient, se zbytkem v případě potřeby.[20] Chyba zaokrouhlování mohou být zavedeny divizními operacemi kvůli omezenému přesnost.
Krok 2: Vezměte i = 3 (jeden menší než počet bitů v N)
Krok 3: R = 00 (vlevo posunuto o 1)
Krok 4: R = 01 (nastavení R (0) až N (i))
Krok 5: R
Krok 3: R = 010
Krok 4: R = 011
Krok 5: R
Krok 3: R = 0110
Krok 4: R = 0110
Krok 5: R> = D, výpis zadán
Krok 5b: R = 10 (R − D)
Krok 5c: Q = 10 (nastavení Q (i) na 1)
Krok 3: R = 100
Krok 4: R = 100
Krok 5: R> = D, výpis zadán
Krok 5b: R = 0 (R − D)
Krok 5c: Q = 11 (nastavení Q (i) na 1)
Q = 112 (310) a R = 0.Metody pomalého dělení
Obnovuje se rozdělení
R := ND := D << n - R a D potřebují dvojnásobnou šířku slova než N a Qpro i := n − 1 .. 0 dělat - Například 31..0 pro 32 bitů R := 2 * R − D - Zkušební odčítání od posunuté hodnoty (násobení 2 je posun v binární reprezentaci) -li R ≥ 0 pak q(i) := 1 - Výsledkový bit 1 jiný q(i) := 0 - Výsledný bit 0 R := R + D - Nový částečný zbytek je (obnovená) posunutá hodnota koneckonec- Kde: N = čitatel, D = jmenovatel, n = #bity, R = částečný zbytek, q (i) = bit #i kvocientu
Neobnovující se rozdělení
R := ND := D << n - R a D potřebují dvojnásobnou šířku slova než N a Qpro i = n − 1 .. 0 dělat - například 31..0 pro 32 bitů -li R >= 0 pak q[i] := +1 R := 2 * R − D jiný q[i] := −1 R := 2 * R + D konec -likonec - Poznámka: N = čitatel, D = jmenovatel, n = # bitů, R = částečný zbytek, q (i) = bit #i kvocientu.
Převést následující kvocient na sadu číslic {0,1}: Start: 1. Vytvořte pozitivní termín: 2. Zamaskujte negativní výraz *: 3. Odečíst: : *. (Podepsaná binární notace s Jeden doplněk bez Doplněk dvou ) Q := Q − bit.bnot(Q) * Odpovídající -li −1 Číslice v Q jsou Zastoupeno tak jako nuly tak jako je běžný.
-li R < 0 pak Q := Q − 1 R := R + D - Nutné pouze v případě, že je o Zájmena zájem.konec -li
SRT divize
Metody rychlého dělení
Divize Newton – Raphson
Pseudo kód
Express D jako M × 2E kde 1 ≤ M <2 (standardní reprezentace s plovoucí desetinnou čárkou) D ': = D / 2e + 1 // měřítko mezi 0,5 a 1, lze provést s bitovým posunem / odečtením exponentuN ': = N / 2e + 1X: = 48/17 - 32/17 × D ' // předpočítá konstanty se stejnou přesností jako D.opakovat krát // lze předpočítat na základě pevného P X: = X + X × (1 - D '× X)konecvrátit se N '× X
Varianta Newton – Raphsonova divize
Divize Goldschmidt
Binomická věta
Metody velkých celých čísel
Dělení konstantou
Chyba zaokrouhlování
Viz také
Reference
Další čtení