   This file documents the MIT Scheme system.

   Copyright (C) 1988-2002 Massachusetts Institute of Technology

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the section entitled "GNU
Free Documentation License".

Numerical types
===============

   Mathematically, numbers may be arranged into a tower of subtypes in
which each level is a subset of the level above it:

     number
     complex
     real
     rational
     integer

   For example, 3 is an integer.  Therefore 3 is also a rational, a
real, and a complex.  The same is true of the Scheme numbers that model
3.  For Scheme numbers, these types are defined by the predicates
`number?', `complex?', `real?', `rational?', and `integer?'.

   There is no simple relationship between a number's type and its
representation inside a computer.  Although most implementations of
Scheme will offer at least two different representations of 3, these
different representations denote the same integer.

   Scheme's numerical operations treat numbers as abstract data, as
independent of their representation as possible.  Although an
implementation of Scheme may use fixnum, flonum, and perhaps other
representations for numbers, this should not be apparent to a casual
programmer writing simple programs.

   It is necessary, however, to distinguish between numbers that are
represented exactly and those that may not be.  For example, indexes
into data structures must be known exactly, as must some polynomial
coefficients in a symbolic algebra system.  On the other hand, the
results of measurements are inherently inexact, and irrational numbers
may be approximated by rational and therefore inexact approximations.
In order to catch uses of inexact numbers where exact numbers are
required, Scheme explicitly distinguishes exact from inexact numbers.
This distinction is orthogonal to the dimension of type.

Exactness
=========

   Scheme numbers are either _exact_ or _inexact_.  A number is exact
if it was written as an exact constant or was derived from exact
numbers using only exact operations.  A number is inexact if it was
written as an inexact constant, if it was derived using inexact
ingredients, or if it was derived using inexact operations. Thus
inexactness is a contagious property of a number.

   If two implementations produce exact results for a computation that
did not involve inexact intermediate results, the two ultimate results
will be mathematically equivalent.  This is generally not true of
computations involving inexact numbers since approximate methods such as
floating point arithmetic may be used, but it is the duty of each
implementation to make the result as close as practical to the
mathematically ideal result.

   Rational operations such as `+' should always produce exact results
when given exact arguments.  If the operation is unable to produce an
exact result, then it may either report the violation of an
implementation restriction or it may silently coerce its result to an
inexact value.  See Implementation restrictions.

   With the exception of `inexact->exact', the operations described in
this section must generally return inexact results when given any
inexact arguments.  An operation may, however, return an exact result if
it can prove that the value of the result is unaffected by the
inexactness of its arguments.  For example, multiplication of any number
by an exact zero may produce an exact zero result, even if the other
argument is inexact.

Implementation restrictions
===========================

   Implementations of Scheme are not required to implement the whole
tower of subtypes (see Numerical types), but they must implement a
coherent subset consistent with both the purposes of the implementation
and the spirit of the Scheme language.  For example, an implementation
in which all numbers are real may still be quite useful.(1)

   Implementations may also support only a limited range of numbers of
any type, subject to the requirements of this section.  The supported
range for exact numbers of any type may be different from the supported
range for inexact numbers of that type.  For example, an implementation
that uses flonums to represent all its inexact real numbers may support
a practically unbounded range of exact integers and rationals while
limiting the range of inexact reals (and therefore the range of inexact
integers and rationals) to the dynamic range of the flonum format.
Furthermore the gaps between the representable inexact integers and
rationals are likely to be very large in such an implementation as the
limits of this range are approached.

   An implementation of Scheme must support exact integers throughout
the range of numbers that may be used for indexes of lists, vectors, and
strings or that may result from computing the length of a list, vector,
or string.  The `length', `vector-length', and `string-length'
procedures must return an exact integer, and it is an error to use
anything but an exact integer as an index.  Furthermore any integer
constant within the index range, if expressed by an exact integer
syntax, will indeed be read as an exact integer, regardless of any
implementation restrictions that may apply outside this range.
Finally, the procedures listed below will always return an exact integer
result provided all their arguments are exact integers and the
mathematically expected result is representable as an exact integer
within the implementation:

     *                gcd                modulo
     +                imag-part          numerator
     -                inexact->exact     quotient
     abs              lcm                rationalize
     angle            magnitude          real-part
     ceiling          make-polar         remainder
     denominator      make-rectangular   round
     expt             max                truncate
     floor            min

   Implementations are encouraged, but not required, to support exact
integers and exact rationals of practically unlimited size and
precision, and to implement the above procedures and the `/' procedure
in such a way that they always return exact results when given exact
arguments.  If one of these procedures is unable to deliver an exact
result when given exact arguments, then it may either report a
violation of an implementation restriction or it may silently coerce its
result to an inexact number.  Such a coercion may cause an error later.

   An implementation may use floating point and other approximate
representation strategies for inexact numbers.  This report recommends,
but does not require, that the IEEE 32-bit and 64-bit floating point
standards be followed by implementations that use flonum
representations, and that implementations using other representations
should match or exceed the precision achievable using these floating
point standards.

   In particular, implementations that use flonum representations must
follow these rules: A flonum result must be represented with at least as
much precision as is used to express any of the inexact arguments to
that operation.  It is desirable (but not required) for potentially
inexact operations such as `sqrt', when applied to exact arguments, to
produce exact answers whenever possible (for example the square root of
an exact 4 ought to be an exact 2).  If, however, an exact number is
operated upon so as to produce an inexact result (as by `sqrt'), and if
the result is represented as a flonum, then the most precise flonum
format available must be used; but if the result is represented in some
other way then the representation must have at least as much precision
as the most precise flonum format available.

   Although Scheme allows a variety of written notations for numbers,
any particular implementation may support only some of them.(2) For
example, an implementation in which all numbers are real need not
support the rectangular and polar notations for complex numbers.  If an
implementation encounters an exact numerical constant that it cannot
represent as an exact number, then it may either report a violation of
an implementation restriction or it may silently represent the constant
by an inexact number.

   ---------- Footnotes ----------

   (1) MIT Scheme implements the whole tower of numerical types.  It has
unlimited-precision exact integers and exact rationals.  Flonums are
used to implement all inexact reals; on machines that support IEEE
floating-point arithmetic these are double-precision floating-point
numbers.

   (2) MIT Scheme implements all of the written notations for numbers.

Syntax of numerical constants
=============================

   A number may be written in binary, octal, decimal, or hexadecimal by
the use of a radix prefix.  The radix prefixes are `#b' (binary), `#o'
(octal), `#d' (decimal), and `#x' (hexadecimal).  With no radix prefix,
a number is assumed to be expressed in decimal.

   A numerical constant may be specified to be either exact or inexact
by a prefix.  The prefixes are `#e' for exact, and `#i' for inexact.
An exactness prefix may appear before or after any radix prefix that is
used.  If the written representation of a number has no exactness
prefix, the constant may be either inexact or exact.  It is inexact if
it contains a decimal point, an exponent, or a `#' character in the
place of a digit, otherwise it is exact.

   In systems with inexact numbers of varying precisions it may be
useful to specify the precision of a constant.  For this purpose,
numerical constants may be written with an "exponent marker" that
indicates the desired precision of the inexact representation.  The
letters `s', `f', `d', and `l' specify the use of _short_, _single_,
_double_, and _long_ precision, respectively.  (When fewer than four
internal inexact representations exist, the four size specifications
are mapped onto those available.  For example, an implementation with
two internal representations may map short and single together and long
and double together.)  In addition, the exponent marker `e' specifies
the default precision for the implementation.  The default precision
has at least as much precision as _double_, but implementations may
wish to allow this default to be set by the user.

     3.14159265358979F0
            Round to single -- 3.141593
     0.6L0
            Extend to long -- .600000000000000

Numerical operations
====================

   See Entry Format, for a summary of the naming conventions used to
specify restrictions on the types of arguments to numerical routines.
The examples used in this section assume that any numerical constant
written using an exact notation is indeed represented as an exact
number.  Some examples also assume that certain numerical constants
written using an inexact notation can be represented without loss of
accuracy; the inexact constants were chosen so that this is likely to be
true in implementations that use flonums to represent inexact numbers.

 - procedure: number? object
 - procedure: complex? object
 - procedure: real? object
 - procedure: rational? object
 - procedure: integer? object
     These numerical type predicates can be applied to any kind of
     argument, including non-numbers.  They return `#t' if the object
     is of the named type, and otherwise they return `#f'.  In general,
     if a type predicate is true of a number then all higher type
     predicates are also true of that number.  Consequently, if a type
     predicate is false of a number, then all lower type predicates are
     also false of that number.(1)

     If Z is an inexact complex number, then `(real? Z)' is true if and
     only if `(zero? (imag-part Z))' is true.  If X is an inexact real
     number, then `(integer? X)' is true if and only if `(= X (round
     X))'.

          (complex? 3+4i)         =>  #t
          (complex? 3)            =>  #t
          (real? 3)               =>  #t
          (real? -2.5+0.0i)       =>  #t
          (real? #e1e10)          =>  #t
          (rational? 6/10)        =>  #t
          (rational? 6/3)         =>  #t
          (integer? 3+0i)         =>  #t
          (integer? 3.0)          =>  #t
          (integer? 8/4)          =>  #t

     Note: The behavior of these type predicates on inexact numbers is
     unreliable, since any inaccuracy may affect the result.

 - procedure: exact? z
 - procedure: inexact? z
     These numerical predicates provide tests for the exactness of a
     quantity.  For any Scheme number, precisely one of these
     predicates is true.

 - procedure: exact-integer? object
 - procedure: exact-nonnegative-integer? object
 - procedure: exact-rational? object
     These procedures test for some very common types of numbers.  These
     tests could be written in terms of simpler predicates, but are more
     efficient.

 - procedure: = z1 z2 z3 ...
 - procedure: < x1 x2 x3 ...
 - procedure: > x1 x2 x3 ...
 - procedure: <= x1 x2 x3 ...
 - procedure: >= x1 x2 x3 ...
     These procedures return `#t' if their arguments are (respectively):
     equal, monotonically increasing, monotonically decreasing,
     monotonically nondecreasing, or monotonically nonincreasing.

     These predicates are transitive.  Note that the traditional
     implementations of these predicates in Lisp-like languages are not
     transitive.

     Note: While it is not an error to compare inexact numbers using
     these predicates, the results may be unreliable because a small
     inaccuracy may affect the result; this is especially true of `='
     and `zero?'.  When in doubt, consult a numerical analyst.

 - procedure: zero? z
 - procedure: positive? x
 - procedure: negative? x
 - procedure: odd? x
 - procedure: even? x
     These numerical predicates test a number for a particular property,
     returning `#t' or `#f'.  See note above regarding inexact numbers.

 - procedure: max x1 x2 ...
 - procedure: min x1 x2 ...
     These procedures return the maximum or minimum of their arguments.

          (max 3 4)              =>  4    ; exact
          (max 3.9 4)            =>  4.0  ; inexact

     Note: If any argument is inexact, then the result will also be
     inexact (unless the procedure can prove that the inaccuracy is not
     large enough to affect the result, which is possible only in
     unusual implementations).  If `min' or `max' is used to compare
     numbers of mixed exactness, and the numerical value of the result
     cannot be represented as an inexact number without loss of
     accuracy, then the procedure may report a violation of an
     implementation restriction.(2)

 - procedure: + z1 ...
 - procedure: * z1 ...
     These procedures return the sum or product of their arguments.

          (+ 3 4)                 =>  7
          (+ 3)                   =>  3
          (+)                     =>  0
          (* 4)                   =>  4
          (*)                     =>  1

 - procedure: - z1 z2 ...
 - procedure: / z1 z2 ...
     With two or more arguments, these procedures return the difference
     or quotient of their arguments, associating to the left.  With one
     argument, however, they return the additive or multiplicative
     inverse of their argument.

          (- 3 4)                 =>  -1
          (- 3 4 5)               =>  -6
          (- 3)                   =>  -3
          (/ 3 4 5)               =>  3/20
          (/ 3)                   =>  1/3

 - procedure: 1+ z
 - procedure: -1+ z
     `(1+ z)' is equivalent to `(+ z 1)'; `(-1+ z)' is equivalent to
     `(- z 1)'.

 - procedure: abs x
     `abs' returns the magnitude of its argument.

          (abs -7)                =>  7

 - procedure: quotient n1 n2
 - procedure: remainder n1 n2
 - procedure: modulo n1 n2
     These procedures implement number-theoretic (integer) division: for
     positive integers N1 and N2, if N3 and N4 are integers such that

          N1 = (N2 * N3) + N4

          0 <= N4 < N2

     then

          (quotient N1 N2)        =>  N3
          (remainder N1 N2)       =>  N4
          (modulo N1 N2)          =>  N4

     For integers N1 and N2 with N2 not equal to 0,

          (= N1
             (+ (* N2 (quotient N1 N2))
                (remainder N1 N2)))
                                              =>  #t

     provided all numbers involved in that computation are exact.

     The value returned by `quotient' always has the sign of the product
     of its arguments.  `remainder' and `modulo' differ on negative
     arguments -- the `remainder' always has the sign of the dividend,
     the `modulo' always has the sign of the divisor:

          (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

     Note that `quotient' is the same as `integer-truncate'.

 - procedure: integer-floor n1 n2
 - procedure: integer-ceiling n1 n2
 - procedure: integer-truncate n1 n2
 - procedure: integer-round n1 n2
     These procedures combine integer division with rounding.  For
     example, the following are equivalent:

          (integer-floor N1 N2)
          (floor (/ N1 N2))

     However, the former is faster and does not produce an intermediate
     result.

     Note that `integer-truncate' is the same as `quotient'.

 - procedure: integer-divide n1 n2
 - procedure: integer-divide-quotient qr
 - procedure: integer-divide-remainder qr
     `integer-divide' is equivalent to performing both `quotient' and
     `remainder' at once.  The result of `integer-divide' is an object
     with two components; the procedures `integer-divide-quotient' and
     `integer-divide-remainder' select those components.  These
     procedures are useful when both the quotient and remainder are
     needed; often computing both of these numbers simultaneously is
     much faster than computing them separately.

     For example, the following are equivalent:

          (lambda (n d)
            (cons (quotient n d)
                  (remainder n d)))

          (lambda (n d)
            (let ((qr (integer-divide n d)))
              (cons (integer-divide-quotient qr)
                    (integer-divide-remainder qr))))

 - procedure: gcd n1 ...
 - procedure: lcm n1 ...
     These procedures return the greatest common divisor or least common
     multiple of their arguments.  The result is always non-negative.

          (gcd 32 -36)            =>  4
          (gcd)                   =>  0

          (lcm 32 -36)            =>  288
          (lcm 32.0 -36)          =>  288.0  ; inexact
          (lcm)                   =>  1

 - procedure: numerator q
 - procedure: denominator q
     These procedures return the numerator or denominator of their
     argument; the result is computed as if the argument was
     represented as a fraction in lowest terms.  The denominator is
     always positive.  The denominator of 0 is defined to be 1.

          (numerator (/ 6 4))  =>  3
          (denominator (/ 6 4))  =>  2
          (denominator (exact->inexact (/ 6 4))) => 2.0

 - procedure: floor x
 - procedure: ceiling x
 - procedure: truncate x
 - procedure: round x
     These procedures return integers.  `floor' returns the largest
     integer not larger than X.  `ceiling' returns the smallest integer
     not smaller than X.  `truncate' returns the integer closest to X
     whose absolute value is not larger than the absolute value of X.
     `round' returns the closest integer to X, rounding to even when X
     is halfway between two integers.

     Rationale: `round' rounds to even for consistency with the rounding
     modes required by the IEEE floating point standard.

     Note: If the argument to one of these procedures is inexact, then
     the result will also be inexact.  If an exact value is needed, the
     result should be passed to the `inexact->exact' procedure (or use
     one of the procedures below).

          (floor -4.3)          =>  -5.0
          (ceiling -4.3)        =>  -4.0
          (truncate -4.3)       =>  -4.0
          (round -4.3)          =>  -4.0

          (floor 3.5)           =>  3.0
          (ceiling 3.5)         =>  4.0
          (truncate 3.5)        =>  3.0
          (round 3.5)           =>  4.0  ; inexact

          (round 7/2)           =>  4    ; exact
          (round 7)             =>  7

 - procedure: floor->exact x
 - procedure: ceiling->exact x
 - procedure: truncate->exact x
 - procedure: round->exact x
     These procedures are similar to the preceding procedures except
     that they always return an exact result.  For example, the
     following are equivalent

          (floor->exact x)
          (inexact->exact (floor x))

     except that the former is faster and has fewer range restrictions.

 - procedure: rationalize x y
 - procedure: rationalize->exact x y
     `rationalize' returns the _simplest_ rational number differing
     from X by no more than Y.  A rational number R1 is _simpler_ than
     another rational number R2 if R1=P1/Q1 and R2=P2/Q2 (both in
     lowest terms) and |P1|<=|P2| and |Q1|<=|Q2|.  Thus 3/5 is simpler
     than 4/7.  Although not all rationals are comparable in this
     ordering (consider 2/7 and 3/5) any interval contains a rational
     number that is simpler than every other rational number in that
     interval (the simpler 2/5 lies between 2/7 and 3/5).  Note that
     0=0/1 is the simplest rational of all.

          (rationalize (inexact->exact .3) 1/10)  => 1/3    ; exact
          (rationalize .3 1/10)                   => #i1/3  ; inexact

     `rationalize->exact' is similar to `rationalize' except that it
     always returns an exact result.

 - procedure: simplest-rational x y
 - procedure: simplest-exact-rational x y
     `simplest-rational' returns the simplest rational number between X
     and Y inclusive; `simplest-exact-rational' is similar except that
     it always returns an exact result.

     These procedures implement the same functionality as `rationalize'
     and `rationalize->exact', except that they specify the input range
     by its endpoints; `rationalize' specifies the range by its center
     point and its (half-) width.

 - procedure: exp z
 - procedure: log z
 - procedure: sin z
 - procedure: cos z
 - procedure: tan z
 - procedure: asin z
 - procedure: acos z
 - procedure: atan z
 - procedure: atan y x
     These procedures compute the usual transcendental functions.  `log'
     computes the natural logarithm of Z (not the base ten logarithm).
     `asin', `acos', and `atan' compute arcsine, arccosine, and
     arctangent, respectively.  The two-argument variant of `atan'
     computes `(angle (make-rectangular X Y))' (see below).

     In general, the mathematical functions log, arcsine, arccosine, and
     arctangent are multiply defined.  For nonzero real X, the value of
     log X is defined to be the one whose imaginary part lies in the
     range minus PI (exclusive) to PI (inclusive).  log 0 is undefined.
     The value of log Z when Z is complex is defined according to the
     formula

          log Z = log magnitude(Z) + i angle(Z)

     With log defined this way, the values of arcsine, arccosine, and
     arctangent are according to the following formulae:

          arcsin(Z) = -i log(i Z + sqrt(1 - Z^2))
          arccos(Z) = pi/2 - arcsin(Z)
          arctan(Z) = (log(1 + i Z) + log(1 - i Z)) / (2 i)

     The above specification follows `Common Lisp: the Language', which
     in turn cites `Principal Values and Branch Cuts in Complex APL';
     refer to these sources for more detailed discussion of branch cuts,
     boundary conditions, and implementation of these functions.  When
     it is possible these procedures produce a real result from a real
     argument.

 - procedure: sqrt z
     Returns the principal square root of Z.  The result will have
     either positive real part, or zero real part and non-negative
     imaginary part.

 - procedure: expt z1 z2
     Returns Z1 raised to the power Z2:

          Z1^Z2 = e^(Z2 log Z1)

     0^0 is defined to be equal to 1.

 - procedure: make-rectangular x1 x2
 - procedure: make-polar x3 x4
 - procedure: real-part z
 - procedure: imag-part z
 - procedure: magnitude z
 - procedure: angle z
 - procedure: conjugate z
     Suppose X1, X2, X3, and X4 are real numbers and Z is a complex
     number such that

          Z = X1 + X2 i = X3 e^(i X4)

     Then `make-rectangular' and `make-polar' return Z, `real-part'
     returns X1, `imag-part' returns X2, `magnitude' returns X3, and
     `angle' returns X4.  In the case of `angle', whose value is not
     uniquely determined by the preceding rule, the value returned will
     be the one in the range minus PI (exclusive) to PI (inclusive).

     `conjugate' returns the complex conjugate of Z.

 - procedure: exact->inexact z
 - procedure: inexact->exact z
     `exact->inexact' returns an inexact representation of Z.  The
     value returned is the inexact number that is numerically closest
     to the argument.  If an exact argument has no reasonably close
     inexact equivalent, then a violation of an implementation
     restriction may be reported; MIT Scheme signals an error of type
     `condition-type:bad-range-argument' in this case.

     `inexact->exact' returns an exact representation of Z.  The value
     returned is the exact number that is numerically closest to the
     argument.  If an inexact argument has no reasonably close exact
     equivalent, then a violation of an implementation restriction may
     be reported; in MIT Scheme this case does not occur because all
     inexact numbers are representable as exact numbers.

     These procedures implement the natural one-to-one correspondence
     between exact and inexact integers throughout an
     implementation-dependent range.  See Implementation restrictions.

   ---------- Footnotes ----------

   (1) In MIT Scheme the `rational?' procedure is the same as `real?',
and the `complex?' procedure is the same as `number?'.

   (2) MIT Scheme signals an error of type
`condition-type:bad-range-argument' in this case.

Numerical input and output
==========================

 - procedure: number->string number [radix]
     RADIX must be an exact integer, either 2, 8, 10, or 16.  If
     omitted, RADIX defaults to 10.  The procedure `number->string'
     takes a number and a radix and returns as a string an external
     representation of the given number in the given radix such that

          (let ((number NUMBER)
                (radix RADIX))
            (eqv? number
                  (string->number (number->string number radix)
                                  radix)))

     is true.  It is an error if no possible result makes this
     expression true.

     If NUMBER is inexact, the radix is 10, and the above expression
     can be satisfied by a result that contains a decimal point, then
     the result contains a decimal point and is expressed using the
     minimum number of digits (exclusive of exponent and trailing
     zeroes) needed to make the above expression true; otherwise the
     format of the result is unspecified.

     The result returned by `number->string' never contains an explicit
     radix prefix.

     Note: The error case can occur only when NUMBER is not a complex
     number or is a complex number with an non-rational real or
     imaginary part.

     Rationale: If NUMBER is an inexact number represented using
     flonums, and the radix is 10, then the above expression is normally
     satisfied by a result containing a decimal point.  The unspecified
     case allows for infinities, NaNs, and non-flonum representations.

 - variable: flonum-parser-fast?
     This variable controls the behavior of `string->number' when
     parsing inexact numbers.  Specifically, it allows the user to
     trade off accuracy against speed.

     When set to its default value, `#f', the parser provides maximal
     accuracy, as required by the Scheme standard.  If set to `#t', the
     parser uses faster algorithms that will sometimes introduce small
     errors in the result.  The errors affect a few of the
     least-significant bits of the result, and consequently can be
     tolerated by many applications.

 - variable: flonum-unparser-cutoff
     This variable controls the action of `number->string' when NUMBER
     is a flonum (and consequently controls all printing of flonums).
     The value of this variable is normally a list of three items:

    ROUNDING-TYPE
          One of the following symbols: `normal', `relative', or
          `absolute'.  The symbol `normal' means that the number should
          be printed with full precision.  The symbol `relative' means
          that the number should be rounded to a specific number of
          digits.  The symbol `absolute' means that the number should
          be rounded so that there are a specific number of digits to
          the right of the decimal point.

    PRECISION
          An exact integer.  If ROUNDING-TYPE is `normal', PRECISION is
          ignored.  If ROUNDING-TYPE is `relative', PRECISION must be
          positive, and it specifies the number of digits to which the
          printed representation will be rounded.  If ROUNDING-TYPE is
          `absolute', the printed representation will be rounded
          PRECISION digits to the right of the decimal point; if
          PRECISION is negative, the representation is rounded `(-
          PRECISION)' digits to the left of the decimal point.

    FORMAT-TYPE
          One of the symbols: `normal', `scientific', or `engineering'.
          This specifies the format in which the number will be
          printed.
          `scientific' specifies that the number will be printed using
          scientific notation: `X.XXXeYYY'.  In other words, the number
          is printed as a mantissa between zero inclusive and ten
          exclusive, and an exponent.  `engineering' is like
          `scientific', except that the exponent is always a power of
          three, and the mantissa is constrained to be between zero
          inclusive and 1000 exclusive.  If `normal' is specified, the
          number will be printed in positional notation if it is "small
          enough", otherwise it is printed in scientific notation.  A
          number is "small enough" when the number of digits that would
          be printed using positional notation does not exceed the
          number of digits of precision in the underlying floating-point
          number representation; IEEE double-precision floating-point
          numbers have 17 digits of precision.

     This three-element list may be abbreviated in two ways.  First, the
     symbol `normal' may be used, which is equivalent to the list
     `(normal 0 normal)'.  Second, the third element of the list,
     FORMAT-TYPE, may be omitted, in which case it defaults to `normal'.

     The default value for `flonum-unparser-cutoff' is `normal'.  If it
     is bound to a value different from those described here,
     `number->string' issues a warning and acts as though the value had
     been `normal'.

Some examples of `flonum-unparser-cutoff':

     (number->string (* 4 (atan 1 1)))
                                         => "3.141592653589793"
     (fluid-let ((flonum-unparser-cutoff '(relative 5)))
       (number->string (* 4 (atan 1 1))))
                                         => "3.1416"
     (fluid-let ((flonum-unparser-cutoff '(relative 5)))
       (number->string (* 4000 (atan 1 1))))
                                         => "3141.6"
     (fluid-let ((flonum-unparser-cutoff '(relative 5 scientific)))
       (number->string (* 4000 (atan 1 1))))
                                         => "3.1416e3"
     (fluid-let ((flonum-unparser-cutoff '(relative 5 scientific)))
       (number->string (* 40000 (atan 1 1))))
                                         => "3.1416e4"
     (fluid-let ((flonum-unparser-cutoff '(relative 5 engineering)))
       (number->string (* 40000 (atan 1 1))))
                                         => "31.416e3"
     (fluid-let ((flonum-unparser-cutoff '(absolute 5)))
       (number->string (* 4 (atan 1 1))))
                                         => "3.14159"
     (fluid-let ((flonum-unparser-cutoff '(absolute 5)))
       (number->string (* 4000 (atan 1 1))))
                                         => "3141.59265"
     (fluid-let ((flonum-unparser-cutoff '(absolute -4)))
       (number->string (* 4e10 (atan 1 1))))
                                         => "31415930000."
     (fluid-let ((flonum-unparser-cutoff '(absolute -4 scientific)))
       (number->string (* 4e10 (atan 1 1))))
                                         => "3.141593e10"
     (fluid-let ((flonum-unparser-cutoff '(absolute -4 engineering)))
       (number->string (* 4e10 (atan 1 1))))
                                         => "31.41593e9"
     (fluid-let ((flonum-unparser-cutoff '(absolute -5)))
       (number->string (* 4e10 (atan 1 1))))
                                         => "31415900000."

 - procedure: string->number string [radix]
     Returns a number of the maximally precise representation expressed
     by the given STRING.  RADIX must be an exact integer, either 2, 8,
     10, or 16.  If supplied, RADIX is a default radix that may be
     overridden by an explicit radix prefix in STRING (e.g.
     `"#o177"').  If RADIX is not supplied, then the default radix is
     10.  If STRING is not a syntactically valid notation for a number,
     then `string->number' returns `#f'.

          (string->number "100")        =>  100
          (string->number "100" 16)     =>  256
          (string->number "1e2")        =>  100.0
          (string->number "15##")       =>  1500.0

     Note that a numeric representation using a decimal point or an
     exponent marker is not recognized unless RADIX is `10'.

Fixnum and Flonum Operations
============================

   This section describes numerical operations that are restricted
forms of the operations described above.  These operations are useful
because they compile very efficiently.  However, care should be
exercised: if used improperly, these operations can return incorrect
answers, or even malformed objects that confuse the garbage collector.

Fixnum Operations
-----------------

   A "fixnum" is an exact integer that is small enough to fit in a
machine word.  In MIT Scheme, fixnums are typically 24 or 26 bits,
depending on the machine; it is reasonable to assume that fixnums are at
least 24 bits.  Fixnums are signed; they are encoded using 2's
complement.

   All exact integers that are small enough to be encoded as fixnums are
always encoded as fixnums -- in other words, any exact integer that is
not a fixnum is too big to be encoded as such.  For this reason, small
constants such as `0' or `1' are guaranteed to be fixnums.

 - procedure: fix:fixnum? object
     Returns `#t' if OBJECT is a fixnum; otherwise returns `#f'.

   Here is an expression that determines the largest fixnum:

     (let loop ((n 1))
       (if (fix:fixnum? n)
           (loop (* n 2))
           (- n 1)))

A similar expression determines the smallest fixnum.

 - procedure: fix:= fixnum fixnum
 - procedure: fix:< fixnum fixnum
 - procedure: fix:> fixnum fixnum
 - procedure: fix:<= fixnum fixnum
 - procedure: fix:>= fixnum fixnum
     These are the standard order and equality predicates on fixnums.
     When compiled, they do not check the types of their arguments.

 - procedure: fix:zero? fixnum
 - procedure: fix:positive? fixnum
 - procedure: fix:negative? fixnum
     These procedures compare their argument to zero.  When compiled,
     they do not check the type of their argument.  The code produced
     by the following expressions is identical:

          (fix:zero? FIXNUM)
          (fix:= FIXNUM 0)

     Similarly, `fix:positive?' and `fix:negative?' produce code
     identical to equivalent expressions using `fix:>' and `fix:<'.

 - procedure: fix:+ fixnum fixnum
 - procedure: fix:- fixnum fixnum
 - procedure: fix:* fixnum fixnum
 - procedure: fix:quotient fixnum fixnum
 - procedure: fix:remainder fixnum fixnum
 - procedure: fix:gcd fixnum fixnum
 - procedure: fix:1+ fixnum
 - procedure: fix:-1+ fixnum
     These procedures are the standard arithmetic operations on fixnums.
     When compiled, they do not check the types of their arguments.
     Furthermore, they do not check to see if the result can be encoded
     as a fixnum.  If the result is too large to be encoded as a
     fixnum, a malformed object is returned, with potentially
     disastrous effect on the garbage collector.

 - procedure: fix:divide fixnum fixnum
     This procedure is like `integer-divide', except that its arguments
     and its results must be fixnums.  It should be used in conjunction
     with `integer-divide-quotient' and `integer-divide-remainder'.

   The following are "bitwise-logical" operations on fixnums.

 - procedure: fix:not fixnum
     This returns the bitwise-logical inverse of its argument.  When
     compiled, it does not check the type of its argument.

          (fix:not 0)                             =>  -1
          (fix:not -1)                            =>  0
          (fix:not 1)                             =>  -2
          (fix:not -34)                           =>  33

 - procedure: fix:and fixnum fixnum
     This returns the bitwise-logical "and" of its arguments.  When
     compiled, it does not check the types of its arguments.

          (fix:and #x43 #x0f)                     =>  3
          (fix:and #x43 #xf0)                     =>  #x40

 - procedure: fix:andc fixnum fixnum
     Returns the bitwise-logical "and" of the first argument with the
     bitwise-logical inverse of the second argument.  When compiled, it
     does not check the types of its arguments.

          (fix:andc #x43 #x0f)                    =>  #x40
          (fix:andc #x43 #xf0)                    =>  3

 - procedure: fix:or fixnum fixnum
     This returns the bitwise-logical "inclusive or" of its arguments.
     When compiled, it does not check the types of its arguments.

          (fix:or #x40 3)                         => #x43
          (fix:or #x41 3)                         => #x43

 - procedure: fix:xor fixnum fixnum
     This returns the bitwise-logical "exclusive or" of its arguments.
     When compiled, it does not check the types of its arguments.

          (fix:xor #x40 3)                        => #x43
          (fix:xor #x41 3)                        => #x42

 - procedure: fix:lsh fixnum1 fixnum2
     This procedure returns the result of logically shifting FIXNUM1 by
     FIXNUM2 bits.  If FIXNUM2 is positive, FIXNUM1 is shifted left; if
     negative, it is shifted right.  When compiled, it does not check
     the types of its arguments, nor the validity of its result.

          (fix:lsh 1 10)                          =>  #x400
          (fix:lsh #x432 -10)                     =>  1
          (fix:lsh -1 3)                          =>  -8
          (fix:lsh -128 -4)                       =>  #x3FFFF8

Flonum Operations
-----------------

   A "flonum" is an inexact real number that is implemented as a
floating-point number.  In MIT Scheme, all inexact real numbers are
flonums.  For this reason, constants such as `0.' and `2.3' are
guaranteed to be flonums.

 - procedure: flo:flonum? object
     Returns `#t' if OBJECT is a flonum; otherwise returns `#f'.

 - procedure: flo:= flonum1 flonum2
 - procedure: flo:< flonum1 flonum2
 - procedure: flo:> flonum1 flonum2
     These procedures are the standard order and equality predicates on
     flonums.  When compiled, they do not check the types of their
     arguments.

 - procedure: flo:zero? flonum
 - procedure: flo:positive? flonum
 - procedure: flo:negative? flonum
     Each of these procedures compares its argument to zero.  When
     compiled, they do not check the type of their argument.

 - procedure: flo:+ flonum1 flonum2
 - procedure: flo:- flonum1 flonum2
 - procedure: flo:* flonum1 flonum2
 - procedure: flo:/ flonum1 flonum2
     These procedures are the standard arithmetic operations on flonums.
     When compiled, they do not check the types of their arguments.

 - procedure: flo:finite? flonum
     The IEEE floating-point number specification supports three
     special "numbers": positive infinity (`+inf'), negative infinity
     (`-inf'), and not-a-number (`NaN').  This predicate returns `#f'
     if FLONUM is one of these objects, and `#t' if it is any other
     floating-point number.

 - procedure: flo:negate flonum
     This procedure returns the negation of its argument.  When
     compiled, it does not check the type of its argument.  Equivalent
     to `(flo:- 0.  FLONUM)'.

 - procedure: flo:abs flonum
 - procedure: flo:exp flonum
 - procedure: flo:log flonum
 - procedure: flo:sin flonum
 - procedure: flo:cos flonum
 - procedure: flo:tan flonum
 - procedure: flo:asin flonum
 - procedure: flo:acos flonum
 - procedure: flo:atan flonum
 - procedure: flo:sqrt flonum
 - procedure: flo:expt flonum1 flonum2
 - procedure: flo:floor flonum
 - procedure: flo:ceiling flonum
 - procedure: flo:truncate flonum
 - procedure: flo:round flonum
 - procedure: flo:floor->exact flonum
 - procedure: flo:ceiling->exact flonum
 - procedure: flo:truncate->exact flonum
 - procedure: flo:round->exact flonum
     These procedures are flonum versions of the corresponding
     procedures.  When compiled, they do not check the types of their
     arguments.

 - procedure: flo:atan2 flonum1 flonum2
     This is the flonum version of `atan' with two arguments.  When
     compiled, it does not check the types of its arguments.

Random Numbers
==============

   MIT Scheme provides a facility for generating pseudo-random numbers.
The current implementation is a "subtract-with-carry" random-number
generator, based on the algorithm from `A New Class of Random Number
Generators', George Marsaglia and Arif Zaman, `The Annals of Applied
Probability', Vol. 1, No. 3, 1991.  At the time it was implemented,
this was a good algorithm for general purposes, but the state of the
art in random-number generation is constantly changing.  If necessary,
the implementation will be updated to use a new algorithm while
retaining the same interface.

   The interface described here is very similar to that of Common Lisp.

 - procedure: random modulus [state]
     MODULUS must be a positive real number.  `random' returns a
     pseudo-random number between zero (inclusive) and MODULUS
     (exclusive).  The exactness of the returned number is the same as
     the exactness of MODULUS.  Additionally, if MODULUS is an exact
     integer, the returned number will be also.  Usually, MODULUS is
     either an exact integer or an inexact real; the current
     implementation has been tuned to make these two cases fast.

     If STATE is given and not `#f', it must be a random-state object;
     otherwise, it defaults to the value of the variable
     `*random-state*'.  This object is used to maintain the state of the
     pseudo-random-number generator and is altered as a side effect of
     the `random' procedure.

          (random 1.0)    => .32744744667719056
          (random 1.0)    => .01668326768172354
          (random 10)     => 3
          (random 10)     => 8
          (random 100)    => 38
          (random 100)    => 63
          (random 100/3)  => 130501475769920525/6755399441055744
          (random 100/3)  => 170571694016427575/13510798882111488

 - procedure: flo:random-unit state
     STATE must be a random-state object.  `flo:random-unit' returns a
     pseudo-random number between zero inclusive and one exclusive; the
     returned number is always a flonum and therefore an inexact real
     number.  `flo:random-unit' is equivalent to `random' with a
     MODULUS of `1.0', except that it is faster.

   The next three definitions concern random-state objects.  In
addition to these definitions, it is important to know that
random-state objects are specifically designed so that they can be
saved to disk using the `fasdump' procedure, and later restored using
the `fasload' procedure.  This allows a particular random-state object
to be saved in order to replay a particular pseudo-random sequence.

 - variable: *random-state*
     This variable holds a data structure, a random-state object, that
     encodes the internal state of the random-number generator that
     `random' uses by default.  A call to `random' will perform a side
     effect on this data structure.  This variable may be changed, using
     `set!' or `fluid-let', to hold a new random-state object.

 - procedure: make-random-state [state]
     This procedure returns a new random-state object, suitable for use
     as the value of the variable `*random-state*', or as the STATE
     argument to `random'.  If STATE is not given or `#f',
     `make-random-state' returns a _copy_ of the current random-number
     state object (the value of the variable `*random-state*').  If
     STATE is a random-state object, a copy of that object is returned.
     If STATE is `#t', then a new random-state object is returned that
     has been "randomly" initialized by some means (such as by a
     time-of-day clock).

 - procedure: random-state? object
     Returns `#t' if OBJECT is a random-state object, otherwise returns
     `#f'.

Characters
**********

   Characters are objects that represent printed characters, such as
letters and digits.(1)

   ---------- Footnotes ----------

   (1) Some of the details in this section depend on the fact that the
underlying operating system uses the ASCII character set.  This may
change when someone ports MIT Scheme to a non-ASCII operating system.