]> git.rkrishnan.org Git - sicp.git/commitdiff
exercise 1.7 solution.
authorRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Thu, 25 Mar 2010 03:14:22 +0000 (08:44 +0530)
committerRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Thu, 25 Mar 2010 03:14:22 +0000 (08:44 +0530)
chapter1/ch1_1.clj

index 777e38413339324d62b17246bb34b419f6b6bc6f..bcb63291c33b23444fc42923ce751b471e1dad2d 100644 (file)
   are evaluated before it gets called. good-enough? will return a false unless
   the guess and x are almost the same. guess evaluated to the initial value of
   guess. sqrt-iter gets evaluated, but gets into an infinite loop. The predicate
-  will have no effect.)
\ No newline at end of file
+  will have no effect.)
+
+;; Exercise 1.7: The good-enough? test used in computing square roots will not
+;; be very effective for finding the square roots of very small numbers. Also,
+;; in real computers, arithmetic operations are almost always performed with
+;; limited precision. This makes our test inadequate for very large numbers.
+;; Explain these statements, with examples showing how the test fails for small
+;; and large numbers.
+user> (sqrt (square 0.001))
+0.031260655525445276
+user> (sqrt (square 0.2))
+0.20060990407779591
+user> (sqrt (square 0.01))
+0.03230844833048122
+user> (sqrt (square 0.02))
+0.0354008825558513
+user> (sqrt (square 10))
+10.000000000139897
+user> (sqrt (square 100))
+100.00000025490743
+user> (sqrt (square 200))
+200.000000510076
+user> (sqrt (square 2))
+2.0000000929222947
+user> (sqrt (square 0.1))
+0.10032578510960607
+user> (sqrt (square 0.01))
+0.03230844833048122
+user> (sqrt (square 10000))
+10000.0
+user> (sqrt (square 20000))
+20000.0
+user> (sqrt (square 200000))
+200000.0
+user> (sqrt (square 20000000))
+2.0E7
+user> (sqrt (square 20000000000))
+2.0E10
+user> (sqrt (square 200000.012))
+200000.012
+user> (sqrt (square 2000000.123))
+2000000.123
+user> (sqrt (square 200000000.123))
+2.00000000123E8
+user> (sqrt (square 2000000000.123))
+2.000000000123E9
+user> (sqrt (square 20000000000.123))
+2.0000000000123E10
+user> (sqrt (square 2000000000000.123))
+2.000000000000123E12
+
+;; An alternative strategy for implementing good-enough? is to watch how guess
+;; changes from one iteration to the next and to stop when the change is a very
+;; small fraction of the guess.
+(defn sqrt-iter [old-guess new-guess x]
+  (if (good-enough? old-guess new-guess x)
+    new-guess
+    (sqrt-iter new-guess (improve new-guess x)
+              x)))
+
+(defn improve [guess x]
+  (average guess (/ x guess)))
+
+(defn average [x y]
+  (/ (+ x y) 2))
+
+(defn good-enough? [old-guess new-guess x]
+  (< (/ (abs (- new-guess old-guess)) new-guess) 0.0001))
+
+(defn sqrt [x]
+  (sqrt-iter x 1.0 x))
+
+user> (sqrt (square 0.01))
+0.010000000025490743
+user> (sqrt (square 0.001))
+0.0010000000000000117
+user> (sqrt (square 0.0001))
+1.0000000000082464E-4
+user> (sqrt (square 0.02))
+0.020000000050877154
+user> (sqrt (square 0.002))
+0.0020000000000000235
+user> (sqrt (square 4))
+4.000000000000051
+user> (sqrt (square 20))
+20.000000000298428
+user> (sqrt (square 25))
+25.000000063076968
+user> (sqrt 5)
+2.236067977499978
+user> (sqrt 25)
+5.000000000053722
+user> (sqrt 9)
+3.000000001396984
+user> (sqrt 81)
+9.000000000007091
+
+;; exercise 1.8: