Dalybos metodas paremtas liestinių metodu

Iš testwiki.
Pereiti į navigaciją Jump to search

Dalybos metodas paremtas liestinių metodu


Funkcijos y=f(x) liestinės lygtis taške x0 yra tokia:
y=f(x0)+f′(x0)(x−x0).
Arba
y−f(x0)=f′(x0)(x−x0).(1)
Įstatydami čia koordinates (d, 0) susikirtimo taško liestinės su ašimi x, gausime:
0−f(x0)=f′(x0)(d−x0),
iš kur
d=x0−f(x0)f′(x0).(2)
Kad skaičiuoti šituo metodu, reikia iš pradžių žinoti apytikslę reikšmę 1/D funkcijos f(x)=1/x. Šis metodas suranda kam lygu 1/D.
Kad panaudoti liestinių metodą reikia pažymėti X=1/D ir sukūrti funkciją f(X)=1X−D. Taigi, reikia žinoti apytikslią 1/D reikšmę, kuri suteikiama X0≈1/D reikšmei.
Funkcijos f(X) išvestinė yra tokia:
f′(X)=(1X−D)′=−1X2.
Tada pagal (2) formulę
X1=X0−f(X0)f′(X0)=X0−1X0−D−1X02=X0+X0−DX021=X0+X0(1−DX0)=X0(2−DX0).(3)
Dabar reikšmė X1 labiau atitinką ieškomą reikšmę 1/D. Toliau,
X2=X1(2−DX1),(4)
X3=X2(2−DX2),(5)
Xi+1=Xi(2−DXi).(6)

Pavyzdžiai

  • Reikia apskaičiuoti N/D = 1.7890625/1.3984375. Čia N = 1.7890625, D = 1.3984375.
Paimama apytiksli 1/D reikšmė. Kadangi tiksli 1/D reikšmė yra
1/1.3984375 = 0.71508379888268156424581005586592, tai paėmus X0=0.715 galima pradėti skaičiavimus. Taigi, pagal (3) formulę,
X1=X0(2−DX0)=0.715⋅(2−1.3984375⋅0.715)=
= 0.715 * (2 - 1.3984375 * 0.715) = 0.7150837890625.
Jau gauti 7 pirmi teisingi 1/D = 1/1.3984375 skaitmenys.
Toliau atliekama antra iteracija:
X2=X1(2−DX1)=0.7150837890625⋅(2−1.3984375⋅0.7150837890625)=
= 0.7150837890625 * (2 - 1.3984375 * 0.7150837890625) = 0.71508379888268142938613891601563.
Dabar gauta 15 pirmų teisingų skaitmenų (po kablelio).
Toliau atliekama trečia iteracija:
X3=X2(2−DX2)=
= 0.71508379888268142938613891601563 * (2 - 1.3984375 * 0.71508379888268142938613891601563) =
= 0.7150837988826815642458100558659.
Dabar gauti 31 pirmi teisingi skaitmenys (po kablelio).
Tada
N/D=N⋅X3=
= 1.7890625 * 0.7150837988826815642458100558659 = 1.2793296089385474860335195530726.

Dalyba su dvejetainiais skaičiais

1 pav. Dalyba dvejetainėje sistemoje.
2 pav. Slankaus kablelio skaičių dalyba.
Pirmas paveikslėlis parodo sveikujų skaičių dalybą. Ten 8 bitų skaičius 01000011 yra dalinys (dividend), 4 bitų skaičius 1001 yra daliklis (divisor), 4 bitų skaičius 0100 yra liekana (remainder) ir 4 bitų skaičius 0111 yra dalmuo (quotient). Kiti tarpiniai skaičiai 10000111, 0011111, 01101 yra dalinės liekanos (partial remainder).
Čia [ https://www.righto.com/2023/04/reverse-engineering-8086-divide-microcode.html ] aprašyta kaip sveikus skaičius dvejetainėje sistemoje dalina intel 8086 procesorius.
Dalijimo esmė dvejetainėje sistemoje yra atimti daliklį (divisor) iš dalinio (dividend). Jeigu atimties rezultatas teigiamas, tada pirmas dalmens (quotient) bitas yra 1, o jeigu rezultatas neigiamas, tada pirmas dalmens bitas yra 0. Toliau gaunamas partial remainder, kuris yra per vieną bitą kairiau nuo daliklio padauginto iš 0 arba 1. Jeigu atėmus daliklį iš partial remainder gaunamas neigiamas rezultatas (yra borrow, kas atrodo yra carry flag), tai antras dalmens (quotient) bitas yra 0, o jeigu gaunamas teigiamas rezultatas, tai antras dalmens bitas yra 1. Toliau antras partial remainder esantis viena bito pozicija į kairę nuo atimamo dalmens nustato trečią bitą. Jeigu dabar atimties rezultatas yra neigiamas, tai trečias dalmens (quotient) bitas yra 0, o jeigu – teigiamas, tai trečias bitas yra 1. Ir t. t.
Taip dalinant nereikia spelioti dalmens bitų, kaip dalinant dešimtainėje sistemoje reikia spelioti dalmens skaitmenys. 8086 iš tikro dalmenį (quotient) gauna su apverstais bitais (detaliau paaiškinta toje nuorodoje), o paskui pabaigoje visus quotient bitus apverčia į priešingus (tas pats kas quotient XOR 1111...111).
1 paveiksle skaičius 67 dalinamas iš 9 ir gaunamas dalmuo 7 ir liekana 4. Ir 9*7+4=67.


Antrame paveikslėlyje dalybos tikslumas yra mažas, nes yra mažai mantisos bitų. Pavyzdžiui,
1.1111111 = 1 + 1/2 + 1/4 + 1/8 + 1/16 + 1/32 + 1/64 + 1/128 = 1.9921875,
o
1.111111111111 = 1 + 1/2 + 1/4 + 1/8 + 1/16 + 1/32 + 1/64 + 1/128 + 1/256 + 1/512 + 1/1024 + 1/2048 + 1/4096 = 1.999755859375.
Su labai daug vienetų po kablelio turėtų gautis skaičius dešimtainėje sistemoje 1.999999999999999999...
Taip kaip parodyta 2 pav. dalino visi FPU x87 coprocesor'iai. Nuo 8087 iki 486 FPU. O Pentium procesoriaus FPU naudoja SRT dalybą, kai kažkokiu budu kaskart gaunamas ne vienas quotient bitas, o iškart du bitai. Todėl tokia dalyba teoriškai yra apie 2 kartus greitesnė, bet kuri privedė prie Pentium FDIV bug. Daugiau apie tai čia [ https://www.righto.com/2024/12/this-die-photo-of-pentium-shows.html ].
Čia [ https://www.ece.ucdavis.edu/~vojin/CLASSES/EPFL/Papers/4-Fandrianto_division_ARITH8.pdf ] aprašytas SRT algoritmas.