1; SketchyLISP Library
2; Copyright (C) 2005,2006,2007 Nils M Holm. All rights reserved.
3; See the file LICENSE of the SketchyLISP distribution
4; for conditions of use.
5
6; ---name---
7; divide
8
9; ---conformance---
10; SketchyLISP Core
11
12; ---purpose---
13; Divide two numbers, giving a quotient and a remainder.
14
15; ---args---
16; A - number (dividend)
17; B - number (divisor)
18
19; ---keywords---
20; DIVIDE function, quotient, modulus, division, divide
21; arithmetics
22
23; ---see-also---
24; digits, quotient, remainder, modulo, +, -, *, ndivide
25
26; ---example---
27; (divide 11 -2) => (-5 1)
28
29(define divide #t)
30
31(require "digits.scm")
32(require "list.scm")
33(require "abs.scm")
34(require "zerop.scm") ; zero?
35(require "caar.scm") ; cadr
36(require "ndivide.scm")
37(require "integer.scm")
38(require "negativep.scm") ; negative?
39
40; ---code---
41(define (divide a b)
42  (letrec
43    ((sign
44       (lambda (x)
45         (cond ((eq? (negative? a) (negative? b)) x)
46           (else (list->integer
47                 (cons '- (integer->list x)) #t)))))
48     (rsign
49       (lambda (x)
50         (cond ((negative? a)
51             (list->integer
52               (cons '- (integer->list x)) #t))
53           (else x))))
54     (idiv
55       (lambda (a b)
56         (cond ((zero? b) (bottom 'divide-by-zero))
57           ; overflow?
58           ((n< (abs a) (abs b))
59             (list 0 (rsign (abs a))))
60           ; compute quotient, remainder
61           (else (let ((q (ndivide (abs a) (abs b))))
62                   (list (sign (car q))
63                         (rsign (cadr q)))))))))
64    (idiv (integer a) (integer b))))
65