t3x.org / sketchy / library / nminus.html
SketchyLISP
Reference
  Copyright (C) 2007
Nils M Holm

n-

Conformance: SketchyLISP Core

Purpose: Subtract two natural numbers.

Arguments:
A - natural number
B - natural number to be subtracted

Model:

(define (n- a b)
  (letrec
    ; Compute difference of two digits with borrow
    ; X Y - digits
    ; CI CO - borrow (carry) in, out
    ; RESULT - (difference . carry out)
    ((d-
       (lambda (x y ci co)
         (cond ((eq? y 0d)
             (cond ((eq? ci 1d)
                 ; subtract carry in
                 (d- x 1d 0d co))
               (else (cons x co))))
           ; handle overflow
           ((null? (pred x))
             (d- 9d (pred y) ci 1d))
           (else (d- (pred x) (pred y) ci co)))))
     ; Subtract two lists of decimal digits forming reverse
     ; decimal numbers. The result is in normal order.
     ; A B - reverse lists of digits
     ; C - carry flag
     ; R - result (normal order)
     (diff
       (lambda (a b c r)
         (cond ((null? a)
             (cond
               ; A=() ; B=()
               ((null? b)
                 (cond
                   ; carry not set? OK
                   ((eq? c 0d) r)
                   ; A<B is undefined
                   (else (bottom 'difference-negative))))
               (else (bottom 'difference-negative))))
           ; A\=() ; B=() ; see above
           ((null? b)
             (cond
               ; carry not set?
               ((eq? c 0d)
                 ; prepend rest of A
                 (append (reverse a) r))
               ; else subtract borrow
               (else (diff a (integer->list 1) 0d r))))
           ; advance to next pair of digits
           (else (diff (cdr a) (cdr b)
                   ; compute borrow
                   (cdr (d- (car a) (car b) c 0d))
                   ; prepend result digit
                   (cons (car (d- (car a) (car b) c 0d))
                     r)))))))
    (normalize
      (list->integer
        (diff (reverse (integer->list a))
              (reverse (integer->list b))
              0d '())
        #t))))

Implementation:

; This function is a primitive function.

Example:

(n- 7 5) 
=> 2

See also:
digits, n+, nquotient, nremainder, n*, -.