[plt-scheme] Endless loop and I don't see why
Hey
I'm reading SICP and doing exercise 1.7 and 1.8 (merged in
same source) I have a problem and don't seem to find what
is wrong. When it calculates the square-root all works as
expected. When cube-root is calculated, the program keeps
looking for a solution, even when it seems to have found
one! All the display and display-and-return statements are
inserted so I could debug the problem.
Also if it was possible could you comment on my solution for
exercise 1.7 (write a better version for good-enough?), the
books version is when the if condition is #?, my own
version is when the if condition is #f.
Here is the code, other comments are also welcome.
; root-iter : number number (number number -> number) ->
number
; seeks ideal solution based on the function improve
(define (root-iter guess x improve)
(if (good-enough? guess x)
guess
(root-iter (improve guess x)
x
improve)))
; average : number ... number -> number
; calculates the average for the numbers given as arguments
(define (average . nums)
(/ (apply + nums)
(length nums)))
; square : number -> number
(define (square n)
(* n n))
; cube : number -> number
(define (cube n)
(* n n n))
; display-and-return : X -> X
; as a side effect displays x and
; return it afterwards
(define (display-and-return x)
(display x) (newline)
x)
; square-root : number -> number
; calculate the square root
(define (square-root x)
(root-iter 1.0 x (lambda (guess x)
(map display (list guess #\tab x
#\newline))
(display-and-return (average guess (/ x
guess))))))
; cube-root : number -> number
; calculate the cube root
(define (cube-root x)
(root-iter 1.0 x (lambda (guess x)
(map display (list guess #\tab x
#\newline))
(display-and-return (/ (+ (/ x (square
guess)) (* 2 guess))
3)))))
; this variable belongs to the exercise 1.7 version
; so to keep state, is there a better way to keep it
; as it is now, this looks global pollution to me
(define good-enough-change 0)
; good-enough? : number number -> bool
; returns true if the number we are searching for is close
enough
(define good-enough?
(if #t ;; true is the books version, false is the
exercise 1.7 version
(lambda (guess x)
(map display (list #\tab guess #\tab x #\newline))
(< (abs (- (square guess) x)) 0.001))
(lambda (guess x) ;; exercise 1.7 version, is it any
good
(map display (list #\tab guess #\tab x #\newline))
(let ((diff (abs (- (square guess) x))))
(display diff) (newline)
(if (< diff good-enough-change 0.00001)
#t
(begin (set! good-enough-change diff)
#f))))))
; testing functions
(square-root (square 8))
(square-root (square 3))
; here it goes into endless loop,
; but calculations (as outputed with display) seem done
right
(cube-root (cube 8))
(cube-root (cube 3))
I think the problem is in cube-root but I'm unable to find what I'm doing
wrong, help is appreciated.
Pieter