0
votes

I'm doing exercise 1.18 in SICP and I face some trouble. The goal is to make a procedure based on 2 previous exercises. This procedure implements so-called Russian peasant method (or Ancient Egyptian multiplication). I wrote a code, but one procedure just doesn't want to execute. Here's my code:

#lang sicp
(define (double a) (+ a a)) 
(define (halve a) (/ a 2)) 

(define (r_m a b)
  (iter a b 0))
  
(define (iter a b n)
    (cond ((= b 0) 0)
          ((even? a) (iter (halve a) (double b) (+ n b)))
          (else (iter (halve a) (double b) n))))

So, when I call my procedure (r_m) with such arguments (r_m 13 19) it stops after 1st iteration. (iter (halve a) (double b) (+ n b) (with arguments 13 and 19) gives this result: iter (13/2) 38 19

After that, program tries to check if 13/2 is odd. But it can't check such number (13/2), because odd? expects an integer, not this undone division.

For some reason, the halve procedure doesn't work when called. I don't really understand why, because other procedures (double and simple + n b) work fine.

Thank you in advance and I hope my grammar doesn't hurt you too much.

1

1 Answers

1
votes

There are several things wrong with your program. Apart from anything else, even if halve worked the way you want it to work, how would b become zero? This is not the only problem!

However the particular case of halve happens because you are assuming programming languages to do what they normally do: incorrect arithmetic which is convenient for the machine, rather than correct arithmetic which is convenient for humans. Scheme tries hard to do correct arithmetic. What, mathematically, is 13/2? It's not 6, or 7, or 3, it's 13/2, or 6 + 1/2: it's a rational number, not an integer.

If you want the next integer below 13/2, the way you want to get it is by subtracting 1 before you divide: (halve (- 13 1)) is 6, exactly. So if you change that cond clause to have (halve (- a 1)) your program will be closer to working (but, in fact it will then fail to terminate, so in a sense it will be further from working...).