Pitkä aritmetiikka

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 21. tammikuuta 2022 tarkistetusta versiosta . tarkastukset vaativat 2 muokkausta .

Pitkät aritmeettiset - aritmeettiset operaatiot, jotka  suoritetaan tietokoneella ( yhteen- , vähennys- , kerto- , jakolasku- , eksponentio- , alkeisfunktiot ) luvuille, joiden bittisyvyys ylittää tämän tietokoneen konesanan pituuden. Näitä toimintoja ei toteuteta laitteistolla, vaan ohjelmistolla käyttäen peruslaitteistoa pienempien tilausten kanssa työskentelyyn. Erikoistapaus - mielivaltainen tarkkuusaritmetiikka  - viittaa aritmetiikkaan, jossa numeroiden pituutta rajoittaa vain käytettävissä olevan muistin määrä.

Sovellus

Pitkää aritmetiikkaa käytetään seuraavilla alueilla:

Tarvittava laitteisto toimiakseen pitkän aritmeettisen kanssa

Tarkkaan ottaen prosessorilta vaaditaan vain epäsuoraa osoitusta mielivaltaisen tarkkuuden aritmetiikkaan toteuttamiseksi ; kiinteän tarkkuuden aritmetiikassa pärjäät jopa ilman sitä. Tietyt prosessorin toiminnot kuitenkin nopeuttavat pitkää aritmetiikkaa ja yksinkertaistavat sen ohjelmointia.

Toteutus ohjelmointikielillä

Ohjelmointikielissä on sisäänrakennetut tietotyypit, jotka eivät yleensä ylitä 64 bittiä (noin 10 19 ). Desimaalipitkä aritmetiikka toteutettiin Neuvostoliiton ohjelmointikielillä ALMIR - 65 MIR-1- tietokoneessa ja ANALYTIK MIR-2- tietokoneessa . Työskennelläksesi suurten numeroiden kanssa nykyaikaisissa ohjelmointikielissä on useita valmiita optimoituja kirjastoja pitkää aritmetiikkaa varten.

Useimmat toiminnalliset kielet antavat sinun vaihtaa tavallisesta aritmeettisesta pitkälle aritmeettiseen aritmetiikkaan ilman, että sinun tarvitsee muuttaa aritmeettista koodia. Esimerkiksi Erlang ja Scheme edustavat aina tarkkoja lukuja yhtä pitkiä. Standard ML :ssä kaikkien kokonaislukulajikkeiden toteutukset määritetään allekirjoituksen perusteella INTEGER, jolloin voit valita tarvittavan ulottuvuuden, mukaan lukien moduulin IntInf, joka toteuttaa mielivaltaisen tarkkuuden kokonaislukuja; PolyML-toteutus käyttää tätä moduulia oletuksena.

PascalABC.NET:ssä, Rubyssa , Pythonissa ja Javassa on sisäänrakennettuja kirjastoja suurten numeroiden käsittelyä varten .

Algoritmit

Kertolalgoritmit

Seuraavaa kokonaislukujen esitystä käytetään yleensä kuvaamaan algoritmeja. Pohja on valittu . Sitten pituus kokonaisluku voidaan esittää muodossa [1] :

missä

Perus

Se on koulun menetelmän mukainen algoritmi "sarakkeessa". Kestää aikaa missä  ovat kerrottujen lukujen koot.

Algoritmi voidaan esittää muodossa [1] [2] :

Algoritmi 1 BasecaseMultiply
Input: Output: for from to do




Karatsuban kertominen

Karatsuban kertolaskumenetelmä kuuluu " hajoita ja hallitse " -paradigmaan. Algoritmin laskennallinen monimutkaisuus :

.

Tämä algoritmi on yksinkertainen toteutus [3] syöttötietojen jakamisesta, josta on tullut alla lueteltujen algoritmien perusta. Ajatuksena on jakaa yksi kertolaskuoperaatio lukuisille luvuille kolmeen kertolaskuoperaatioon luvuilla, joiden pituus on plus [1] .

Kahden konesanaa suuremman luvun kertomiseksi Karatsuban algoritmia kutsutaan rekursiivisesti, kunnes luvut ovat tarpeeksi pieniä kertoakseen suoraan. Esimerkki tällaisesta algoritmista:

Algoritmi 2 KaratsubaMultiply
Input: Output: KaratsubaMultiply KaratsubaMultiply KaratsubaMultiply







Lasketaan :

Kolme välikerrointa on laskettava:

Tulos:

Tooman algoritmi

Tämä algoritmi on yleistys Karatsuba-algoritmista ja on nopeampi. Kun on annettu kaksi kokonaislukua ja , Toomin algoritmi jakaa ne pienempiin osiin, joista jokainen on yhtä pitkä kuin konesanan pituus, ja suorittaa operaatiot näille osille. Algoritmin laskennan monimutkaisuus:

Tooma-3 algoritmi

Ajatuksen esitti ensimmäisen kerran A. L. Toom vuonna 1963 [4] , ja se koostuu syötetietojen (kertoimien) jakamisesta kolmeen yhtä suureen osaan (yksinkertaisuuden vuoksi kaikkia osia pidetään samanarvoisina). Toom-3 vähentää alkeiskertotoimintojen lukumäärää 9:stä 5:een. Algoritmin monimutkaisuus

Harkitse tätä algoritmia seuraavassa esimerkissä. Olkoon kaksi numeroa ja . Määritellään operaatioita numeroille, joiden koko on yhtä suuri kuin 1/3 alkuperäisten lukujen koosta (katso kuva). Oletetaan myös, että luvut vievät yhtä paljon muistia ja ovat jaollisia tarkalleen kolmella osalla, muuten täytämme molemmat luvut nollilla vaadittuun kokoon.

Sitten suoritetaan näiden osien kartoitus (parametrisointi) 2. asteen polynomeiksi.

Otetaan käyttöön määritelmän mukaan sellainen, että polynomien arvot ovat vastaavasti yhtä suuria kuin syöteluvut ja . Numeroiden bittikohtaisessa esityksessä tämä luku on kaksi potenssiin, joka vastaa kunkin osan pituutta bitteinä.

Esittelemme myös polynomin:

(yksi)

Kun alkiot on määritetty  - polynomin kertoimet , niitä käytetään saadakseen , koska . Kertoimien koko on 2 kertaa suurempi (muistista) kuin osio tai . Lopullinen tuotetta vastaava luku löytyy lisäämällä siirrolla alla olevan kuvan mukaisesti.

Kertoimet voidaan laskea seuraavasti: ja niin edelleen, mutta tämä vaatii kaikki 9 kertolaskua: i:lle j=0,1,2, ja se vastaa yksinkertaista kertolaskua.

Sen sijaan otettiin erilainen lähestymistapa. lasketaan kohdassa (1) 5 pisteellä eri .

Alla oleva taulukko näyttää polynomien arvot yhtälössä (1)

Parametri on ehdollinen. Se tarkoittaa kertoimien banaalista yhtäläisyyttä kohdassa , joten saamme arvon välittömästi. Tämä järjestelmä on lineaarinen 5 tuntemattomassa. Kun se on ratkaistu, saamme tuntemattomia . Seuraavaksi saamme polynomin arvon edellä kuvatulla tavalla.

Tooma-4 algoritmi

Algoritmin monimutkaisuus Edustaa 7 alkeiskertotoimintoa. Toom-4 jakaa syötteen 4 osaan.

Rakennamme kaksi polynomia samalla periaatteella kuin Toom-3:ssa:

ja lasketaan 7 eri pisteessä, lasketaan myös arvo näissä kohdissa.

mistä pääsemme heti
mistä pääsemme heti

Toom-4:n yhteen- ja kertolaskuoperaatioiden määrä on paljon suurempi kuin Toom-3:n. Mutta jotkut ilmaisut esiintyvät useammin kuin kerran. Esimerkiksi laskettu ja [5] .

Toomin algoritmi mielivaltaiselle osiolle

Toomin algoritmi syötettyjen lukujen jakamiseksi n:ksi operandiksi vastaa yllä kuvattua algoritmia. Yleensä kahden yhtä pitkän operandin jakaminen osiin johtaa pistearvojen laskemiseen . Pisteenä järjestelmän ratkaisemisesta he yleensä ottavat .

Fourier-kertolasku

Tätä kertolaskualgoritmia käytetään suurille ja erittäin suurille luvuille [6] .

Tämä algoritmi kertoo kaksi numeroa ajassa, missä  on kerrottujen lukujen merkitsevien numeroiden lukumäärä (olettaen, että ne ovat yhtä suuret). Luomisen syyksi ovat Cooley (Coolet) ja Tyuki (Tukey) - 1965. On myös ehdotuksia, että tämä algoritmi oli tunnettu aiemmin, mutta sillä ei ollut suurta merkitystä ennen ensimmäisten tietokoneiden keksimistä. Todennäköisiä ehdokkaita tämän algoritmin keksinnölle kutsutaan myös nimellä Runge (Runge) ja Koenig (Konig) - 1924 sekä Gauss - 1805.

Olkoon luku, esitämme sen polynomina, kuten teimme aiemmin. Kutsutaan tätä polynomiksi . Esittelemme myös polynomin diskreetin Fourier-muunnoksen vektorina , jossa on koordinaatit . Missä määritetään  - 1:n asteen kompleksijuuri , joka ei ole yhtä suuri kuin 1. Tosiasia on, että luvun 1 kompleksijuuri on määritelty vaihekertoimeen asti, näiden juurien lukumäärä on . Fourier-muunnosta käytetään polynomien kertoimien konvoluutio korvaamiseksi ja :  - niiden Fourier-kuvien tulolla.

jossa kertolasku tarkoittaa vektorien skalaarituloa.

Oletetaan, että on kahden potenssi.

Löytäminen tapahtuu rekursiivisesti (hajota ja hallitse). Ajatuksena on jakaa alkuperäinen polynomi kahdeksi polynomiksi,

Sitten .

Huomaa, että kaikista numeroista vain eri numerot. Siksi DFT on -elementti . Ja koska DFT koostuu elementeistä , niin luvun 1 kompleksijuuri on asteen juuri .

tarkoittaa,

missä ja

Käytimme kompleksilukujen ominaisuuksia: kaiken asteen eri juuria . .

Saamme rekursiivisen algoritmin:
yhden elementin DFT on yhtä suuri kuin tämä elementti
DFT A:n löytämiseksi, jaamme kertoimet A parillisiin ja parittoihin, saamme kaksi polynomia ja löydämme niille DFT:n, löydämme DFT:n. : varten . Seuraavasta väitteestä on todisteita: Käänteinen DFT löydetään samalla tavalla kuin suora DFT, paitsi että pisteet otetaan pisteiksi, jotka ovat symmetrisiä todellisen akselin suhteen, sen sijaan, että niitä käytetään suorassa DFT-muunnoksessa. On myös tarpeen jakaa kaikki polynomin kertoimet n:llä



Juurenpoistoalgoritmit

Neliöjuuri

Yksi neliöjuurialgoritmeista on Karatsuba Square Root -algoritmi. Tämä on ylivoimaisesti tunnetuin menetelmä n - numeroisen luvun neliöjuuren laskemiseen. Tämä algoritmi käyttää nopeaa Fourier-muunnosta ja Newtonin menetelmää , jonka kompleksisuus on 5 M ( n ) [7] .

Esitetty algoritmi perustuu Burnickel-Ziegler (Burnikel-Ziegler) Karatsuban jakoon. Kun annetaan kokonaisluku n , algoritmi laskee samanaikaisesti sen kokonaisluvun neliöjuuren ja vastaavan jäännöksen, joka on Tämä ei ole asymptoottisesti optimaalinen, mutta käytännössä erittäin tehokas operaatioiden monimutkaisuuden järjestyksessä, missä K ( n ) on kertomiseen tarvittavien operaatioiden määrä kaksi n -bittistä numeroa käyttäen Karatsuba-algoritmia. Syynä tähän vähäiseen monimutkaisuuteen on Burnickelin ja Zieglerin äskettäin löytämä kaunis Karatsuba-divisioona ja jäännösten huolellinen käsittely, joka välttää turhat laskelmat.

Lause . SqrtRem-algoritmin käyttämien operaatioiden määrä 2n -bittisellä tulolla on rajoitettu

jossa K ( n ) on operaatioiden määrä, joka tarvitaan kertomaan 2 n -bittistä lukua käyttämällä Karatsuban algoritmia.

Algoritmi SqrtRem Input: kanssa Output: sellainen, että jos sitten palaa

Algoritmit lukujärjestelmän muuntamiseen

Oletetaan, että olet muuntamassa kantaa b kanta B [8] .

Tapoja muuntaa kokonaislukuja


Menetelmä 1 (jako B:llä käyttämällä lukujen b-kantaesitystä). Tietylle kokonaisluvulle u voidaan
saada muodon B-kantamuodossa esitys tekemällä

, , , asti .


Menetelmä 2 (Kerto B:llä käyttämällä b-kantaesitystä). Jos luvun u esitys kannassa b on muotoa , niin käyttämällä aritmeettisia operaatioita lukujen kanssa, jotka esitetään muodossa B, voit saada polynomin muodossa (( .


Menetelmä 1 (a) (Kerto b:llä käyttämällä lukujen B-kantaesitystä). Tietylle murtoluvulle ja voit laskea sen esityksen numeroiden arvot kanta B:ssä seuraavasti: , , ,… missä {x} tarkoittaa xmod1 = x- . Tuloksen pyöristämiseksi M numeroon laskenta voidaan keskeyttää vastaanottamisen jälkeen , ja jos {…{{uВ}В}...В} on suurempi kuin 1/2, arvoa tulee suurentaa yhdellä. (Huomaa kuitenkin, että tämä operaatio voi johtaa tarpeeseen suorittaa käännöksiä, jotka tulisi sisällyttää tulokseen käyttämällä aritmeettisia operaatioita B-kannassa. Olisi helpompi lisätä vakio alkuperäiseen numeroon u ennen laskelmien aloittamista , mutta tämä voi johtaa virheelliseen tulokseen, jos tietokoneessa lukua ei voida esittää tarkasti kanta b -muodossa Huomaa myös, että tulos on mahdollista pyöristää muotoon if ). Menetelmä 2 (a) (Kerto B:llä käyttäen emäksen b esitystä). Jos luvun esitys kannassa b on muotoa , niin käyttämällä aritmeettisia operaatioita lukujen kanssa, jotka esitetään muodossa B-kanta, saat polynomin muodossa ((… + …) + .


tapoja muuntaa murto-osia


Menetelmä 1 (b) (Kerto b:llä käyttämällä lukujen B-kantaesitystä). Tietylle murtoluvulle u voit laskea sen esityksen bittien arvot kantassa B seuraavasti: , , ,… missä {x} tarkoittaa xmod1 = x- . Tuloksen pyöristämiseksi M numeroon laskenta voidaan keskeyttää vastaanottamisen jälkeen , ja jos {…{{uВ}В}...В} on suurempi kuin 1/2, arvoa tulee suurentaa yhdellä. (Huomaa kuitenkin, että tämä operaatio voi johtaa tarpeeseen suorittaa käännöksiä, jotka tulisi sisällyttää tulokseen käyttämällä aritmeettisia operaatioita B-kannassa. Olisi helpompi lisätä vakio alkuperäiseen numeroon u ennen laskelmien aloittamista , mutta tämä voi johtaa virheelliseen tulokseen, jos tietokoneessa lukua ei voida esittää tarkasti kanta b -muodossa Huomaa myös, että tulos on mahdollista pyöristää muotoon if ).


Menetelmä 2 (b) (jako b:llä käyttämällä lukujen B-kantaesitystä). Jos luku u esitetään kannassa b , niin käyttämällä aritmeettisia operaatioita kantassa B, se voidaan laskea muodossa . On tarpeen tarkkailla huolellisesti virheitä, joita esiintyy lyhennyksen tai pyöristyksen aikana jakamisen aikana b:llä; ne ovat yleensä merkityksettömiä, mutta näin ei aina ole.

Multiple Precision Transformation


Erittäin pitkien lukujen muuntaminen on kätevintä aloittaa muuntamalla bittilohkoja, joiden toiminnot voidaan suorittaa yhdellä tarkkuudella. Yhdistät sitten nämä lohkot yksinkertaisilla menetelmillä, jotka ovat ominaisia ​​useille tarkkuuksille. Olkoon esimerkiksi 10n suurin potenssi 10:llä pienempi kuin konesanan koko. Sitten:
a) Jos haluat muuntaa kokonaisluvun "Luku moninkertaisella tarkkuudella binääristä desimaaliin, se on kerrottava 10n:lla (siten muunnetaan binääriarvosta desimaaliksi kantaluvulla 10n käyttämällä menetelmää 1, a); käyttämällä operaatioita yhdellä tarkkuudella, saamme n desimaalin pistettä kullekin esitysyksikölle kantaluvussa 10n;
b) muuntaaksesi murto-osan "monitarkkuuden luvun binääriluvusta desimaaliksi, toimi samalla tavalla kertomalla se : lla: (eli menetelmällä 2, a, missä B \u003d 10n); c) Muuntaaksemme kokonaisluvun moninkertaisella tarkkuudella desimaaliluvusta binääriarvoksi muunnamme ensin n bitin lohkot; sitten muuntaaksesi kantasta 10n binääriseksi, käytä menetelmää 1, b; d) Jos haluat muuntaa moninkertaisen tarkkuuden murto-osan desimaalista binääriarvoksi, muunna ensin kantaluvuksi 10n kuten menettelyssä (c) ja käytä sitten menetelmää 2, b.

Jakoalgoritmit

Algoritmin, jolla jaetaan n-bittinen luku u n-bittisellä luvulla v, on saatava kaksi n-bittistä lukua - u mod v ja u div v. Alla kuvatut algoritmit eivät sovellu käytännössä, koska ne löytävät jaon tuloksena reaaliluvun, ei kahta n-bittistä lukua.

Teoriassa n-bittisen luvun u jakamiseksi n-bittisellä luvulla v, voit ensin löytää n-bittisen approksimaatioluvun luvulle 1/v, sitten kertoa sen u:lla, mikä antaa likiarvon luvulle , ja lopuksi suorita toinen kertolasku tehdäksesi pienen korjauksen varmistaaksesi, että epäyhtälö pätee . Edellä olevan perusteella riittää, että on tehokas algoritmi, joka muodostaisi annetusta n-bittisestä luvusta likimääräisen arvon luvulle, joka on n-bittisen luvun käänteisarvo. Käytä seuraavaksi n-bittisten lukujen kertomisalgoritmia. [9]


Algoritmi R (käänteisluvun saaminen suurella tarkkuudella) Olkoon luvulla v binääriesitys , jossa . Tämä algoritmi laskee luvun likiarvon z siten, että . R1 (Alkuarvio) Määritä ja . R2 (Newton Iteration) Tässä meillä on numero z binäärimuodossa , jossa on jakopisteen ja jälkeiset merkit . Laske tarkasti käyttämällä nopeaa kertolaskuohjelmaa . Laske sen jälkeen tarkalleen missä . Määritä sitten , jossa , joka täyttää epäyhtälön , lisätään tarvittaessa pyöristämään niin, että se on :n kerrannainen . Ja lopuksi määrätä . R3 Jos , palaa vaiheeseen R2; muuten algoritmin suoritus päättyy.



Muut algoritmit

Muistiinpanot

  1. 1 2 3 Richard P. Brent ja Paul Zimmermann, Modern Computer Aritmetic
  2. Donald E. Knuth "Tietokoneohjelmoinnin taito", kohta 4.3.1
  3. Donald E. Knuth "Tietokoneohjelmoinnin taito", osio 4.3.3, osa A
  4. Neuvostoliiton tiedeakatemian raportit 150 (1963), 496-498
  5. Toom 4-suuntainen kertolasku - GNU MP 5.1.3 . Haettu 13. joulukuuta 2013. Arkistoitu alkuperäisestä 14. maaliskuuta 2013.
  6. Donald E. Knuth "Tietokoneohjelmoinnin taito", osio 4.3.3, osa C
  7. Paul Zimmermann. Karatsuban neliöjuuri. [Tutkimusraportti] RR-3805, 1999, s.8. < inria-00072854 Arkistoitu 2. joulukuuta 2014 Wayback Machinessa >
  8. Donald E. Knuth "Tietokoneohjelmoinnin taito", osa 2, osa 4.4
  9. Donald E. Knuth "Tietokoneohjelmoinnin taito", osa 2, osa 4.3.3

Kirjallisuus

  • Donald E. Knuth, " The Art of Computer Programming ", osa 2, "Seminumerical Algorithms", 3. painos, Addison-Wesley, 1998
  • Dan Zuras, "Suurten kokonaislukujen neliöistämisestä ja kertomisesta", ARITH-11: IEEE Symposium on Computer Aithmetic, 1993, s. 260-271.
  • DAN SSSR 150 (1963), 496-498
  • Richard P. Brent ja Paul Zimmermann, Modern Computer Aithmetic
  • Sähköiset välineet ja ohjausjärjestelmät: Kansainvälisen tieteellisen ja käytännön konferenssin (13.-16.10.2010) raporttien aineisto. - Tomsk: V-Spectrum, 2011: Klo 2 tuntia - Osa 2.  - 178 s. ISBN 978-5-91191-223-6, s. 123-129