-
Notifications
You must be signed in to change notification settings - Fork 0
/
1-7_8-newton.scm
94 lines (73 loc) · 2.3 KB
/
1-7_8-newton.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
;; SICP 1.1.7 Square Roots by Newton's Method.
(define eps 0.001)
(define (square x) (* x x))
;; Exercise 1.6
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) eps))
(define (average x y)
(/ (+ x y) 2))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
;; Would never finish: recursively calls sqrt-iter and never new-if.
;; (new-if (good-enough? guess x)
;; new-if is not a special form anymore.
guess
(sqrt-iter (improve guess x) x)))
(define (nsqrt x)
(sqrt-iter 1.0 x))
(display (nsqrt 2)) (newline)
(display (nsqrt 3)) (newline)
(display (nsqrt 9)) (newline)
(display (nsqrt 0.001)) (newline)
;; Exercise 1.7
;; good-enough? fails for small and large numbers:
;; If GUESS were 0.001, this...
;; (nsqrt 0.001)
;; ...would evaluate to .001, which is wrong; should be 0.031622.
;; 0.001^2 = 0.000001
;; 0.000999 < eps
;; Very large numbers:
(display (nsqrt 1e48)) (newline)
;; finishes, but...
;; (nsqrt 1e49)
;; ...does not. (improve guess x) keeps yielding the same result.
;; Another approach: watch how GUESS changes between iterations and
;; stop when the difference is a small fraction of GUESS.
(define (good-enough-alt? guess x)
(< (abs (- guess (improve guess x))) (/ guess 1000)))
;; Best:
(define (good-enough-best? guess x)
(= (improve guess x) guess))
(define (sqrt-iter-alt guess x)
(if (good-enough-alt? guess x)
guess
(sqrt-iter (improve guess x) x)))
(define (nsqrt-alt x)
(sqrt-iter-alt 1.0 x))
(display (nsqrt-alt 2)) (newline)
(display (nsqrt-alt 3)) (newline)
(display (nsqrt-alt 9)) (newline)
(display (nsqrt-alt 1e48)) (newline)
;; 1e49 still doesn't work :(
(display (nsqrt-alt 0.001)) (newline)
;; Exercise 1.8
;; Newton's cube root.
(define (good-enough-cube? guess x)
(= (improve-cube guess x) guess))
(define (improve-cube guess x)
(/ (+ (/ x (* guess guess)) (* 2 guess)) 3))
(define (cube-root-iter guess x)
(if (good-enough-cube? guess x)
guess
(cube-root-iter (improve-cube guess x) x)))
(define (cube-root x)
(cube-root-iter 1.0 x))
(display (cube-root 27)) (newline)
(display (cube-root 64)) (newline)
(display (cube-root 729)) (newline)
(display (cube-root 7)) (newline)