Updated arithmetic, part 3
Multiplication has been written!
The %digit-multiply-add primitive is provided for radix and internal representation independence. It has four arguments. The first two digits are the multiplier and multiplicand digits. The third digit is used to provide the carry from a previous multiply-and-add, and the fourth digit can be used to provide a digit from the product being accummulated.
Multiplication is simpler than subtraction – with the choice of sign+magnitude representation, there is no need to convert the magnitude to or from complemented form.
Because it was simpler to do, and easier to verify, the current added procedures, listed below, do not use the fourth argument (it’s always 0). A partial product is created by multiplying one operand by a single digit from the other operand. Each partial product is added to an accummulated product, and the result is passed on to the next partial product step (function application). To align the partial products properly, we add a least significant 0 digit to the current multidigit operand and pass it on to the next step as the new multidigit operand.
(multiply
(lambda (x y)
(cond
( (number? x)
(cond
( (number? y) (mpy-num x y) )
( #t '***undefined*** ) ))
( #t '***undefined*** ) )))
(mpy-num
(lambda (x y)
(%list->number (mpy-num1 (%number->list x) (%number->list y)))))
(mpy-num1
(lambda (x y)
(cond
( (eq? (car x) #\0) (list #\0) )
( (eq? (car y) #\0) (list #\0) )
( (eq? (car x) (car y)) (cons #\+ (mpy-magnitude (cdr x) (cdr y))) )
( #t (cons #\- (mpy-magnitude (cdr x) (cdr y))) ))))
(mpy-magnitude
(lambda (x y)
(mpy-mag1 x y)))
(mpy-mag1
(lambda (x y)
(cond
( (null? x) (list digit0) )
( #t
(mpy-mag2
(cdr x)
(cons digit0 y)
(mpy-mag3 (car x) y digit0) )))))
(mpy-mag2
(lambda (x y partial)
(cond
( (null? x) partial )
( #t
(mpy-mag2
(cdr x)
(cons digit0 y)
(add-magnitude
(mpy-mag3 (car x) y digit0)
partial)) ))))
(mpy-mag3
(lambda (d y carry)
(cond
( (null? y) (list carry) )
( #t
(cons
(car (%digit-multiply-add d (car y) carry digit0))
(mpy-mag3
d
(cdr y)
(car(cdr
(%digit-multiply-add d (car y) carry digit0))))) ))))