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

Use this formula to implement a cube-root procedure analogous to the square-root procedure. (In section 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.)

I modeled this after the improved procedures written for the previous exercise. The names `cube-root`

and `cube-root-iter`

are different but the procedures are the same as the analagous ones. The procedure `good-enough?`

is the same except the tolerance is smaller for more accuracy. The procedure `improve-guess`

has the formula given in this exercise instead of the one for improving square roots.

```
(define (cube-root x)
(cube-root-iter 0.0 1.0 x))
(define (cube-root-iter previous-guess guess x)
(if (good-enough? previous-guess guess)
guess
(cube-root-iter guess (improve guess x) x)))
(define (good-enough? previous-guess guess)
(< (abs (/ (- previous-guess guess) guess)) 0.0000001))
(define (improve guess x)
(/ (+ (/ x (square guess)) (* 2 guess)) 3))
(define (square a)
(* a a))
```

This works for negative numbers too, with one exception. When the given number is -2, the program gets stuck. To see why, look at the first few iterations:

- The first
`good-enough?`

returns #f. - So
`(cube-root-iter 1.0 (improve 1.0 -2) -2)`

is called. `(improve 1.0 -2)`

returns 0.0.- We have
`(cube-root-iter 1.0 0.0 -2)`

. - This calls
`(good-enough? 1.0 0.0)`

. - I thought this would return an error because it tries to divide by 0. But it turns out it doesn’t return an error; it returns
`#f`

.`(abs (/ (- 1.0 0.0) 0.0))`

returns`+inf.0`

. And`(< +inf.0 0.0000001)`

returns`#f`

. So the procedure continues. - It calls
`(cube-root-iter 0.0 (improve 0.0 -2) -2)`

. - Again,
`(improve 0.0 -2)`

divides by 0, but it doesn’t return an error. It returns`-inf.0`

. - We have
`(cube-root-iter 0.0 -inf.0 -2)`

. - It checks
`(good-enough? 0.0 -inf.0)`

and returns`#f`

again. - So it calls
`(cube-root-iter -inf.0 (improve -inf.0 -2) -2)`

. `(improve -inf.0 -2)`

evaluates to`-inf.0`

. Now we have an infinte loop.`-inf.0`

keeps improving to itself and`good-enough?`

keeps returning`#f`

.

Here’s a log:

```
> (cube-root -2)
>{cube-root-iter 0.0 1.0 -2}
> {good-enough? 0.0 1.0}
< #f
> {improve 1.0 -2}
< 0.0
>{cube-root-iter 1.0 0.0 -2}
> {good-enough? 1.0 0.0}
< #f
> {improve 0.0 -2}
< -inf.0
>{cube-root-iter 0.0 -inf.0 -2}
> {good-enough? 0.0 -inf.0}
< #f
> {improve -inf.0 -2}
< -inf.0
>{cube-root-iter -inf.0 -inf.0 -2}
> {good-enough? -inf.0 -inf.0}
< #f
> {improve -inf.0 -2}
< -inf.0
>{cube-root-iter -inf.0 -inf.0 -2}
> {good-enough? -inf.0 -inf.0}
< #f
```

So I added a special case for if the input is -2:

```
(define (cube-root x)
(if (= x -2)
(cube-root-iter 0.0 2.0 x)
(cube-root-iter 0.0 1.0 x)))
```

Now we get the expected answer for an input of -2:

```
> (cube-root 2)
1.2599210498948732
> (cube-root -2)
-1.2599210498948732
```