quotient, remainder, modulo - number-theoretic integer division

LIBRARY

(import (rnrs r5rs))                ;R6RS
(import (scheme r5rs))              ;R7RS
(import (scheme base))              ;R7RS

SYNOPSIS

(quotient n1 n2)
(remainder n1 n2)
(modulo n1 n2)

DESCRIPTION

These procedures implement number-theoretic (integer) division. N2 must be non-zero.

If n1/n2 is an integer object:

(quotient n1 n2)  => n1/n2
(remainder n1 n2) => 0
(modulo n1 n2)    => 0

If n1/n2 is not an integer object:

(quotient n1 n2)  => nq
(remainder n1 n2) => nr
(modulo n1 n2)    => nm

where nq is n1/n2 rounded towards zero, 0 < abs(nr) < abs(n2), 0 < abs(nm) < abs(n2), nr and nm differ from n1 by a multiple of n2, nr has the same sign as n1, and nm has the same sign as n2.

Consequently, for integer objects n1 and n2 with n2 not equal to 0,

(= n1 (+ (* n2 (quotient n1 n2))
         (remainder n1 n2)))
   => #t

provided all number object involved in that computation are exact.

IMPLEMENTATION NOTES

R6RS contains this reference implementation (which is missing type checks):

(define (sign n)
  (cond ((negative? n) -1)
        ((positive? n) 1)
        (else 0)))

(define (quotient n1 n2)
  (* (sign n1) (sign n2) (div (abs n1) (abs n2))))

(define (remainder n1 n2)
  (* (sign n1) (mod (abs n1) (abs n2))))

(define (modulo n1 n2)
  (* (sign n2) (mod (* (sign n2) n1) (abs n2))))

RETURN VALUES

These procedures return a single value; an integer object.

EXAMPLES

(modulo 13 4)         =>  1
(remainder 13 4)      =>  1

(modulo -13 4)        =>  3
(remainder -13 4)     =>  -1

(modulo 13 -4)        =>  -3
(remainder 13 -4)     =>  1

(modulo -13 -4)       =>  -1
(remainder -13 -4)    =>  -1

(remainder -13 -4.0)  =>  -1.0   ; inexact

APPLICATION USAGE

Both R6RS and R7RS provide these procedures for compatibility. They have often unexpected behavior when one of the arguments is negative. Unless you know that you need something else then you should probably prefer Euclidean division. See div-and-mod(3scm).

COMPATIBILITY

R7RS implementation do not need to provide inexact integers, and the integer range may be reduced, but otherwise these procedures should work the same everywhere.

ERRORS

This procedure can raise exceptions with the following condition types:
&assertion (R6RS)
The wrong number of arguments was passed or an argument was outside its domain.
R7RS
The assertions described above are errors. Implementations may signal an error, extend the procedure's domain of definition to include such arguments, or fail catastrophically.

SEE ALSO

div-and-mod(3scm), floor-remainder(3scm)

STANDARDS

R4RS, IEEE Scheme, R5RS, R6RS, R7RS

HISTORY

These procedures first appeared in R2RS. Scheme previous to R2RS, running on MacLisp, also had similar quotient and remainder procedures. They became legacy procedures in both R6RS and R7RS.

AUTHORS

This page is part of the scheme-manpages project. It includes materials from the RnRS documents. More information can be found at https://github.com/schemedoc/manpages/.

BUGS

Depending on this these procedures are used, programs that use them may behave unexpectedly when one of the arguments is negative.


Markup created by unroff 1.0sc,    March 04, 2023.