Search code examples
schemelispsicpnewtons-method

Getting an wrong answer in scheme program


I am trying to find the cube root of a number using Newton's method. I wrote scheme procedures as follows:

(define (cbrt x)
    (cbrt-iter 1.0 x))

(define (cbrt-iter guess x)
    (if (good-enough? guess x) guess (cbrt-iter (improve guess x) x)))

(define (good-enough? guess x)
    (< (- guess (improve guess x)) 0.00001))

(define (improve guess x)
    (/ (+ (/ x (* guess guess)) (* 2 guess)) 3))

(cbrt 27)
(cbrt 8)
(cbrt 64)

Actually I am working on Exercise 1.8 of the famous (or may be infamous) book SICP. then I run scheme < cuberoot.scm and got the following result:

MIT/GNU Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.

Copyright (C) 2019 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Image saved on Thursday September 5, 2019 at 11:51:46 AM
  Release 10.1.10 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118

1 ]=> (define (cbrt x)
    (cbrt-iter 1.0 x))
;Value: cbrt

1 ]=> (define (cbrt-iter guess x)
    (if (good-enough? guess x) guess (cbrt-iter (improve guess x) x)))
;Value: cbrt-iter

1 ]=> (define (good-enough? guess x)
    (< (- guess (improve guess x)) 0.00001))
;Value: good-enough?

1 ]=> (define (improve guess x)
    (/ (+ (/ x (* guess guess)) (* 2 guess)) 3))
;Value: improve

1 ]=> (cbrt 27)
;Value: 1.

1 ]=> (cbrt 8)
;Value: 1.

1 ]=> (cbrt 64)
;Value: 1.

1 ]=> 
End of input stream reached.
Post proelium, praemium.

The program is always producing 1. as a result. I also tried adjusting the threshold value in good-enough? procedure from 0.00001 to 0.0001 and so on but that didn't worked. Please explain what went wrong and how to fix that.


Solution

  • You need to include an (abs ...) in good-enough?, otherwise you don't just see if two values are close enough, but just if one value is greater than another (approximately).

    (define (good-enough? guess x)
      (< (abs (- guess (improve guess x))) 0.00001))