47 |
53 |
141 |
235 |
2491 |
Násobení v binární soustavě a redundantní binární soustavě není pro člověka běžné. Lidé totiž díky deseti prstům provádějí výpočty v soustavě desítkové, tj. čísla zapisují pomocí mocnin desítky a cifer od 0 do 9. Se soustavou binární ovšem pracuje valná většina počítačů.
- Binární soustava
Každé přirozené číslo n lze právě jedním způsobem vyjádřit ve tvaru:n = ak2k + ak-12k-1 + ... + a121 + a020,kde koeficienty ak, ak-1, ..., a1, a0 nabývají hodnot nula nebo jedna. Řetězci ak ak-1 ... a1 a0 říkáme binární zápis čísla n. Připomeňme, že binární zápis se získá hladovým algoritmem:- Chceme-li najít binární zápis čísla 13, podíváme se, jakou nejvyšší mocninu dvojky číslo 13 obsahuje. To je 8.
- Poté od 13 odečteme 8 a pro získaný rozdíl 5 opět najdeme největší mocninu dvojky, kterou číslo 5 obsahuje. To je 4.
- Na závěr spočteme rozdíl 5 - 4 = 1, a to je nultá mocnina dvojky.
- Získáme 13 = 8 + 4 + 1, a tedy číslo 13 má v binární soustavě zápis 1101.
Program na binární násobení. - Redundantní binární soustava
Připusťme nyní v binární soustavě cifry -1, 0 a 1. Zápisy čísel už nejsou jediné možné, soustava je redundantní. Například 15 = 8 + 4 + 2 + 1 a taky 15 = 16 - 1, tedy jak 1111 tak i 10001 jsou zápisy 15 v redundantní binární soustavě. Vyberme zápis s maximálním počtem nul. K tomu stačí aplikovat následující přepisovací pravidla, dokud je co přepisovat:
Zatímco průměrný počet nul ve standardním binárním zápisu je 1/2, v redundantním binárním zápisu s maximálním možným počtem nul jsou to 2/3. Jelikož je rychlost násobení úměrná počtu nul, je jasné, že redundantní binární soustava je pro násobení velkých čísel výhodnější. Na závěr ještě poznamenejme, že násobíme analogicky jako v klasické binární soustavě. Pouze u znamének dáváme pozor: při násobení cifer stejného znaménka má výsledek znaménko plus, při násobení cifer opačného znaménka má výsledek znaménko mínus. Tedy například násobení 11 a 5 proběhne následovně:01111 → 10001 01111 → 10001 11 → 01 11 → 01
Klasické násobení označuje násobení dvou přirozených čísel zadaných pomocí zápisů v bázi b, kde b je přirozené číslo větší nebo rovno 2. Binární zápis (b = 2) a desítkový zápis (b = 10) jsou speciální případy zápisu čísel v bázi b s ciframi 0, 1, ..., b-1.
- Soustava s přirozeným základem
Každé přirozené číslo n lze právě jedním způsobem vyjádřit ve tvaru:n = akbk + ak-1bk-1 + ... + a1b1 + a0b0,kde koeficienty ak, ak-1, ..., a1, a0 nabývají hodnot 0, 1, ..., b-1. Řetězci ak ak-1 ... a1 a0 říkáme zápis čísla n v soustavě se základem b. Připomeňme, že takový zápis se získá hladovým algoritmem:- Chceme-li najít zápis čísla n v bázi b, podíváme se, jakou nejvyšší mocninu bk číslo n obsahuje a kolikrát ji obsahuje. To bude koeficient ak, který je jistě menší než b.
- Poté od n odečteme akbk a pro získaný rozdíl opět najdeme největší mocninu bj, kterou obsahuje, a jako aj označíme počet výskytů bj v rozdílu.
- Všechny koeficienty mezi aj a ak (pokud nějaké takové jsou, tj. pokud je j menší než k-1) jsou nulové. Analogicky pokračujeme dále.
- Algoritmus M (multiplication)
Násobíme přirozená čísla U,V, kde un-1 ... u1u0 je zápis U v bázi b a vm-1 ... v1v0 je zápis V v bázi b. Označme W = U × V. Snadno si rozmyslíme, že délka zápisu W v bázi b bude maximálně m+n. Označme wm+n-1 ... w1w0 zápis W.- Inicializace W a i , j Polož wn-1 = ... = w1 = w0 a i = 0 a j = 0.
- Násobení nulou Pokud vj = 0, pak polož wi+j = 0 a jdi na krok 6.
- Inicializace i Polož i = 0, k = 0.
- Násob a sečti Polož t = ui × vj + wi+j + k. Pak polož wi+j = t mod b a k = [t/b], kde [x] je největší celé číslo, které je menší nebo rovno x a t mod b = t-b[t/b] (zbytek po celočíselném dělení).
- Cyklus na i Polož i:= i + 1. Pokud i < n, jdi na krok 4. Jinak polož wi+j = k.
- Cyklus na j Polož j := j + 1. Pokud j < m, jdi na krok 2. Jinak konec.
- Algoritmus M versus násobení na papíře
Při násobení na papíře tvoříme částečné součiny, které příslušně posunuté vlevo sepisujeme pod sebe a na závěr vysčítáme. Na počítači je výhodnější provádět násobení a sčítání současně - tak postupuje algoritmus M. Není těžké si rozmyslet, že t nabývá hodnot 0, 1, ..., b2-1 a přenos (carry) k nabývá hodnot 0, 1, ..., b-1, proto víme, jak velké registry potřebujeme pro implementaci. Počítače navíc pracují s bází 2, krok 2 tedy ušetří práci, nastává průměrně v polovině případů. (Už z předchozí sekce víme, že v binární soustavě je rychlost násobení úměrná počtu nul v binárním zápisu násobitele.) Nevýhodou klasického algoritmu je jeho pomalost. Už pro m = n = 4 je možné násobit U × V rychleji. - Složitost algoritmu M pro bázi b = 2
Definujme nejprve elementární operace:- součet a rozdíl 1-bitových čísel a případně přenos,
- součin dvou 1-bitových čísel s 2-bitovým výsledkem,
- celočíselné dělení 2-bitového čísla 1-bitovým za předpokladu, že kvocient i zbytek výsledku jsou 1-bitové.
Rychlé násobení je násobení se složitostí menší než násobení klasické. Snaha o zrychlení algoritmů se zesiluje ruku v ruce s rozvojem počítačů a speciálně snaha o maximální zrychlení násobení je dána potřebami kryptografie, kde je nutné násobit v přijatelném čase ohromná čísla (řádově 10100). My popíšeme dvě rychlá násobení - Karacubovo násobení a Schönhageovo násobení v modulární aritmetice - založená na důvtipných myšlenkách a poměrně jednoduše popsatelná. Mezi rychlými algoritmy patří k těm nejstarším, ovšem algoritmy ještě rychlejší už jsou příliš technické.
Karacubovo násobení vyvrátilo domněnku, že složitost násobení dvou přirozených čísel s binárním rozvojem délky n je O(n2). Tento názor razil ještě v roce 1960 na semináři moskevské univerzity zakladatel teorie složitosti algoritmů Andrej N. Kolmogorov (na obrázku).
- Zapíšeme U, V následujícím způsobem U = 2nU1 + U0 a V = 2nV1 + V0. Platí tedy, že U1 má binární zápis u2n-1...un a U0 má zápis un-1...u1u0, podobně V1 má binární zápis v2n-1...vn a V0 má zápis vn-1...v1v0.
- Následující formule redukuje problém na 3 násobení n-bitových čísel, několik sčítání, resp. odečítání a posouvání binární čárky:
U×V = (22n+2n)U1V1+2n(U1-U0)(V0-V1)+(2n+1)U0V0.
Adaptací na desítkovou soustavu lze převést násobení 8-místných čísel na násobení čísel 4-místných, které už dobří počtáři zvládnou zpaměti. Kupodivu se nezdá, že by taková metoda byla známa před rokem 1962 a že by ji tedy používali "zázrační počtáři", kteří v minulosti bavili obecenstvo násobením obrovských čísel.Schönhageovo násobení v modulární aritmetice sice není rychlejší než Karacubův algoritmus, ale je založeno na odlišných myšlenkách a na neobvyklé reprezentaci čísel, takže je rozhodně zajímavé do jeho tajů proniknout.
- Modulární zápis
Dosud jsme se seznámili jen se zápisy přirozených čísel v pozičních soustaváchch s přirozenou bází (případně jsme připustili záporné cifry). Nyní přijde naprosto odlišný zápis přirozených čísel.
Nechť jsou dána přirozená čísla m1, m2, ..., mr. Pak modulárním zápisem nezáporného celého čísla U nazveme (u1,u2,...,ur,), kde ui je rovno U mod mi pro každé i od 1 do r. Připomeňme, že mod k znamená zbytek po celočíselném dělení číslem k a nabývá hodnot od 0 do k-1. (Například 13=3.4+1, a tedy 13 mod 4=1.) Ukažme si na příkladu takovou modulární reprezentaci.
Nechť a,u1,u2,...,ur jsou nezáporná celá čísla a nechť m1, m2, ..., mr jsou přirozená po dvou nesoudělná čísla. Pak existuje právě jedno U, které splňuje- a <= U < a + m = a + m1. m2. ... . mr,
- (u1,u2,,...,ur) je modulární reprezentace U.
- Modulární aritmetika
V modulární aritmetice je možné paralelizovat sčítání a násobení. Platí totiž, že pokud U a V jsou přirozená čísla s modulárními reprezentacemi (u1,u2,...,ur) a (v1,v2,...,vr) a obě leží mezi 0 a m = m1. m2. ... . mr, pak- U + V má modulární reprezentaci ((u1+v1) mod m1, (u2+v2) mod m2,...,(ur+vr) mod mr),
- U x V má modulární reprezentaci ((u1.v1) mod m1, (u2.v2) mod m2,...,(ur.vr) mod mr).
- Binární modulární aritmetika
Jak uvidíme, takovou rychlou konverzi poskytuje vhodná volba modulí m1, m2, ..., mr. Následující nápad se zrodil v hlavě A. S. Fraenkela.
Volme modula mi= 2ei -1, kde e1 < e2 < ... < er jsou po dvou nesoudělná. Nesoudělnost takových modulí je zaručena následující větou:
Nechť e, f jsou přirozená čísla. Pak 2e -1 a 2f -1 jsou nesoudělná, právě když e a f jsou nesoudělná.- Konverze U na (u1,u2,...,ur)
Zapišme U ve tvaru U = atAt + at-1At-1 + ... +a1A + a0, kde A = 2ei. Uvědomme si, že binární zápis a0 získáme tak, že vezmeme posledních ei bitů v binárním zápisu U, pro získání a1 vezmeme předposledních ei bitů atd. Vlastně jen nasekáme binární zápis U od konce po ei bitech. Protože A = 1 mod (2ei-1), dostaneme ui = (at + at-1 + ... + a0) mod (2ei-1).
V desítkové soustavě máme analogii (tzv. casting out nines - vyloučení devítek)
789 mod 9 = 7 + 8 + 9 mod 9 = 6, což skutečně platí, protože 789 = 87.9 + 6. Ilustrujme tento algoritmus opět na příkladu.
- Konverze (u1,u2,...,ur) na U
Je o něco složitější. Probíhá ve dvou krocích:- Nejprve je třeba najít r(r-1)/2 konstant cij, indexy i,j nabývají hodnot od 1 do r, i < j a platí
cijmi=1 mod mj.
K tomu využijeme následující algoritmus.
- Poté položíme U = vr mr-1...m2m1 +...+ v3 m2m1 + v2 m1 + v1, kde
v1 = u1 mod m1
v2 = (u2-v1)c12 mod m2
v3 = ((u3-v1)c13-v2)c23 mod m3
...
vr = (((ur-v1)c1r-v2)c2r-...)cr-1r mod mr
Snadno se přesvědčíme, že takto spočtené U splňuje- U je nezáporné číslo menší než m,
- U mod mi = ui pro každé i od 1 do r.
- Nejprve je třeba najít r(r-1)/2 konstant cij, indexy i,j nabývají hodnot od 1 do r, i < j a platí
cijmi=1 mod mj.
- Konverze U na (u1,u2,...,ur)
- Schönhageovo násobení
Nyní máme vše připraveno k tomu, abychom pochopili fungování algoritmu, který Arnold Schönhage v roce 1966 navrhl. Nejprve si všimněme, jak šikovně volí 6 modulí, která budou v jeho algoritmu vystupovat.
Teď již samotný Schönhageův algoritmus. Chceme násobit přirozená čísla U a V, označme W = U x V. Najdeme nejmenší pk tak, že násobená čísla jsou nejvýše pk-bitová. K pk najdeme příslušná modula.