Exercise 1.30 of SICP invites us to rewrite the following code as an iterative (read: tail recursive) procedure:
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
To assist us, we are given the following template:
(define (sum term a next b)
(define (iter a result)
(if <??>
<??>
(iter <??> <??>)))
(iter <??> <??>))
After one false start, I produced the following answer, which appears correct:
(define (sumIT term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (+ (term a) result))))
(iter a 0))
To test this, I copied the following code from just above where this exercise is given:
(define (integral f a b dx)
(define (add-dx x) (+ x dx))
(* (sum f (+ a (/ dx 2.0)) add-dx b)
dx))
(integral cube 0 1 0.01)
(integral cube 0 1 0.001)
And quickly made this version using sumIT
:
(define (integralIT f a b dx)
(define (add-dx x) (+ x dx))
(* (sumIT f (+ a (/ dx 2.0)) add-dx b)
dx))
(integralIT cube 0 1 0.01)
(integralIT cube 0 1 0.001)
Then, as I am running in DrRacket's #lang sicp mode, which does not have a cube
procedure by default, I also defined:
(define (cube x) (* x x x))
Finally, I ran the code.
Unsurprisingly, (integral cube 0 1 0.01)
and (integralIT cube 0 1 0.01)
both produce the exact same result: 0.24998750000000042. But, to my shock and horror, (integral cube 0 1 0.001)
returns 0.249999875000001 whereas (integralIT cube 0 1 0.001)
returns a more precise answer of 0.24999987500000073.
Why is this? Why would rewriting a recursive higher-order procedure to be tail recursive increase the precision of my result? I can't think of any part or error in my code that would cause this.