
Hvordan beregne kvadratrota av tall? For eksempel er 7
kvadratrota til 49. Det fins ingen åpenbar måte å regne seg
fram til et eksakt svar.
Men vi kan komme veldig nært ved å gjette oss framover.
Hvis vi skal finne kvadratrota til 49 kan vi f.eks. starte
med 1 og beregne 1 * 1 og se hvor nærme vi treffer.
Etter hver gjetning forbedrer vi gjetningen med å plusse på
f.eks. 0.1 og beregne 1.1 * 1.1 = 1.21 osv osv
helt til differansen mellom 49 og guess * guess er
f.eks mindre enn 0.0001.
Den mest kjent måten å forbedre gjetningen er å anvende
Newton's metode
som tar snittet av guess og x/guess.
Implementert i Common Lisp:
(defun sqrt (x)
(sqrt-iterative 1.0 x))
(defun sqrt-iterative (guess x)
(if (good-enough? guess x)
guess
(sqrt-iterative (improve guess x) x)))
(defun improve (guess x)
"Improve guess with Newton's method"
(/ (+ guess (/ x guess)) 2))
(defun good-enough? (guess x)
(< (abs (- x (* guess guess)))
0.0001))
(print (sqrt 2)) ; Printer 1.4142157
De gradvise gjetningene er:
1.0
1.5
1.4166667
1.4142157
1.4142157
Legg merke til at funksjonen sqrt-iterative er iterativ (looper)
uten bruk av språk looper som for, while, do osv. Selve
funksjonen er rekursivt definert men prosessen er iterativ.
Looping er implementert med funksjonskall.
Er du bekymret for ytelsen i å bruke funksjonskall som iterasjon kan du lese om tail recursion; en teknikk som unngår ny stack frame for hvert kall.