quotient(3scm) Scheme Programmer's Manual quotient(3scm)

quotient, remainder, modulo - number-theoretic integer division

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

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

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.

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))))
    

These procedures return a single value; an integer object.

(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

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).

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

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. In particular, n2 must not be zero.
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.

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

R4RS, IEEE Scheme, R5RS, R6RS, R7RS

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.

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

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