commit e482146b055647ce836e4756cdb0a716ac25e4ac
parent b32210566cbde0ad630e39f24ad0b068c8e0231f
Author: Yuval Langer <yuval.langer@gmail.com>
Date: Mon, 20 Nov 2023 17:08:03 +0200
Add tests for chapter-1 exercise-8, (1.8).
Diffstat:
2 files changed, 72 insertions(+), 49 deletions(-)
diff --git a/sicp/solutions/chapter-1/exercise-8.scm b/sicp/solutions/chapter-1/exercise-8.scm
@@ -1,49 +1,48 @@
-#!
-
-*Exercise 1.8:* Newton's method for cube roots is based on the
-fact that if y is an approximation to the cube root of x, then a
-better approximation is given by the value
-
-x/y^2 + 2y
-----------
-3
-
-Use this formula to implement a cube-root procedure analogous to
-the square-root procedure. (In section *Note 1-3-4:: we will see
- how to implement Newton's method in general as an abstraction of
- these square-root and cube-root procedures.)
-
-!#
-
-(define (cube-root x)
- (define (improve guess)
- ;; (dp guess x)
-
- (/ (+ (/ x
- (* guess guess))
- (* 2 guess))
- 3))
-
- (define (good-enough? old-guess new-guess)
- (define bound 0.0000000000001)
- (define ratio (/ old-guess new-guess))
-
- (define within-bounds
- (< (- 1 bound) ratio (+ 1 bound)))
-
- ;; (dp bound ratio within-bounds)
-
- within-bounds)
-
- (define (cube-root-iter guess)
- (define new-guess (improve guess))
- ;; (dp new-guess)
-
- (if (good-enough? guess new-guess)
- guess
- (cube-root-iter new-guess)))
-
- (cube-root-iter 1))
-
-(format #t "(cube-root ~f) => ~f\n" 0.000000000001 (cube-root 0.000000000001))
-(format #t "(cube-root ~f) => ~f\n" (/ 1 0.000000000001) (cube-root (/ 1 0.000000000001)))
+(define-library (sicp solutions chapter-1 exercise-8)
+ (import (scheme base))
+ (export cube-root)
+
+ (begin
+ #!
+
+ *Exercise 1.8:* Newton's method for cube roots is based on the
+ fact that if y is an approximation to the cube root of x, then a
+ better approximation is given by the value
+
+ x/y^2 + 2y
+ ----------
+ 3
+
+ Use this formula to implement a cube-root procedure analogous to
+ the square-root procedure. (In section *Note 1-3-4:: we will see
+ how to implement Newton's method in general as an abstraction of
+ these square-root and cube-root procedures.)
+
+ !#
+
+ (define (cube-root x)
+ (define (improve guess)
+ (/ (+ (/ x
+ (* guess guess))
+ (* 2 guess))
+ 3))
+
+ (define (good-enough? old-guess new-guess)
+ (define bound 0.0000000000001)
+ (define ratio (/ old-guess new-guess))
+
+ (define within-bounds
+ (< (- 1 bound) ratio (+ 1 bound)))
+
+ within-bounds)
+
+ (define (cube-root-iter guess)
+ (define new-guess (improve guess))
+ (if (good-enough? guess new-guess)
+ guess
+ (cube-root-iter new-guess)))
+
+ ;; Start with a floating point 1.0 instead of an integer 1 to
+ ;; avoid creating a rational with huge enumerator and
+ ;; denominator with the "/" procedure.
+ (cube-root-iter 1.0))))
diff --git a/sicp/tests/chapter-1/exercise-8.scm b/sicp/tests/chapter-1/exercise-8.scm
@@ -0,0 +1,24 @@
+(define-library (sicp tests chapter-1 exercise-8)
+ (import (scheme base)
+ (scheme write)
+ (srfi :64)
+ (sicp solutions chapter-1 exercise-8))
+
+ (begin
+ (test-begin "chapter-1-exercise-8")
+
+ (test-expect-fail 1)
+ ;; XXX: I don't get the approximation here.
+ (for-each
+ (lambda (x)
+ (let ((expected (expt (expt x 3)
+ (/ 1.0 3)))
+ (test-expr (cube-root (expt x 3)))
+ (error 0.01))
+ (test-approximate
+ expected
+ test-expr
+ error)))
+ (list 20000000000000
+ 2
+ (/ 1 20000000000000)))))