The good and bad news is that the caller of these functions is in charge of the accuracy of the calculation. The caller can, and frequently must exercise this control. There would be a significance shedding operation which might be part of the arithmetic ops, especially multiply, or might be separate. I assume separate here. I think that divide must have accuracy guidance.
; Divide (lambda (p q a) (let ((n (cdr p))(d (cdr q))(e (car p))(f (car q))) (cons (- e f a) (quotient (arithmetic-shift n a) d)))) ; Shuck (lambda (n p) (cons (+ p (car n)) (arithmetic-shift (cdr n) (- p)))) ; Multiply (lambda (p q) (cons (+ (car p)(car q)) (* (cdr p)(cdr q)))) ; Neg (lambda (p) (cons (car p) (- (cdr p)))) ; Add (lambda (p q) (let ((add (lambda (p q) (let ((c (car q))) (cons c (+ (arithmetic-shift (cdr p) (- (car p) c)) (cdr q))))))) (if (< (car q) (car p)) (add p q) (add q p)))) (div '(0 . 100) '(0 . 10) 3) ; => (-3 . 80) (add '(0 . 100) '(0 . 10)) ; => (0 . 110) (add '(0 . 100) '(2 . 10)) ; => (0 . 140) (add '(0 . 100) '(-2 . 10)) ; => (-2 . 410) (add '(-2 . 10) '(0 . 100)) ; => (-2 . 410) (add '(3 . 15) '(-2 . 6)) ; => (-2 . 486) (add '(-2 . 6) '(3 . 15)) ; => (-2 . 486)