git @ Cat's Eye Technologies Robin / master stdlib / divide.robin
master

Tree @master (Download .tar.gz)

divide.robin @masterraw · history · blame

;'<<SPEC'

<!--
Copyright (c) 2012-2024, Chris Pressey, Cat's Eye Technologies.
This file is distributed under a 2-clause BSD license.  See LICENSES/ dir.
SPDX-License-Identifier: LicenseRef-BSD-2-Clause-X-Robin
-->

### `divide` ###

    -> Tests for functionality "Evaluate Robin Expression (with Arith)"

`divide` evaluates both of its arguments to numbers and evaluates to the
result of integer division of the first number by the second.  Integer
division computes by what integer the second number can be multiplied
to make it as big as possible without exceeding the first number.

    | (divide 100 3)
    = 33

    | (divide (subtract 0 100) 3)
    = -34

    | (divide 100 (subtract 0 3))
    = -34

    | (divide 33 33)
    = 1

    | (divide 33 34)
    = 0

    | (divide 10 0)
    ? abort (division-by-zero 10)

Division by zero is undefined, and an abort value will be produced.

    | (divide 10 0)
    ? abort (division-by-zero 10)

`divide` expects exactly two arguments, both numbers.

    | (divide 14)
    ? abort (illegal-arguments

    | (divide 14 23 57)
    ? abort (illegal-arguments

    | (divide 14 #t)
    ? abort (expected-number #t)

    | (divide #t 51)
    ? abort (expected-number #t)

'<<SPEC'

(define divide (fun (n d)
  (bind divide-r-pos (fun (self n d acc) ;(d is positive)
    (if (gt? d n)
      acc
      (self self (subtract n d) d (add 1 acc))))
    (bind divide-r-neg (fun (self n d acc) ;(d is negative)
      (if (gt? (abs d) n)
        (subtract 0 (add 1 acc))
        (self self (add n d) d (add 1 acc))))
      (if (equal? d 0)
        (abort (list (literal division-by-zero) n))
        (bind n-prime (if (lt? n 0) (subtract 0 n) n)
          (bind d-prime (if (lt? n 0) (subtract 0 d) d)
            (if (gt? d-prime 0)
              (divide-r-pos divide-r-pos n-prime d-prime 0)
              (divide-r-neg divide-r-neg n-prime d-prime 0)))))))))