8.5.7 Quantities and Numbers
8.5.7.1 Numerical Types
The expression language provides a quantity data type which represents
lengths and quantities derived from lengths,
such as areas and volumes.
The SI meter is used as the base unit for representing quantities.
The name of this unit is
m
.
Any quantity may be represented as the product of a number and
the base unit raised to the power of an integer.
The dimension of a quantity is the power to which the base unit
is raised when the quantity is so represented.
A quantity with dimension 0 is dimensionless.
It is convenient to be able to express quantities not only in terms
of the base unit but also in terms of other derived units.
[77] unit-declaration =
(
define-unit
unit-name expression
)
expression shall evaluate to a quantity.
A unit-declaration declares the derived quantity unit-name
to be equivalent to this quantity.
In this context, unit-name is a separate token.
Derived units for centimeters, millimeters, inches, picas, and
points, corresponding to the following declarations, are pre-defined.
(define-unit cm 0.01m)
(define-unit mm 0.001m)
(define-unit in 0.0254m)
(define-unit pt 0.0003527778m)
(define-unit pica 0.004233333m)
The number data type is
considered to be a subtype of quantity that represents dimensionless
quantities. The expression language provides two types of number:
reals and integers.
Integers are considered to be a subtype of reals, and reals are a
subtype of numbers. For example, the integer 3 is also considered to
be a real number, which, in turn, is considered to be a (dimensionless)
quantity. The types quantity, number, real, and integer are defined
by the predicates quantity?, number?, real?,
and integer?.
Angle (or more precisely, plane angle) is considered to be a
dimensionless quantity (the ratio of two lengths). The integer 1 is
equivalent to 1 radian. It is recommended that
rad
be declared as the name of a derived unit equal to the
dimensionless quantity 1.
8.5.7.2 Exactness
It is necessary to distinguish between quantities that are
represented exactly and those that may not be. For example, indexes
into data structures shall be known exactly.
In order to catch uses of inexact quantities where exact quantities are
required, the expression language explicitly distinguishes exact from inexact quantities.
This distinction is orthogonal to the dimension of type.
Quantities are either exact or inexact. A quantity is
exact if it was written as an exact constant or was derived from
exact quantities using only exact operations. A quantity 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 quantity.
If two implementations produce exact results for a
computation that did not involve inexact intermediate results,
the two ultimate results shall be mathematically equivalent. This is
generally not true of computations involving inexact quantities
since approximate methods such as floating point arithmetic may be used,
but implementations should 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.
With the exception of inexact->exact, the operations described in
this section shall 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 quantity by an exact zero
may produce an exact zero result, even if the other argument is
inexact.
8.5.7.3 Implementation Restrictions
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 floating point numbers to represent all its
inexact real numbers may
support a practically unbounded range of exact integers
while limiting the range of inexact reals (and, therefore,
the range of inexact integers)
to the dynamic range of the floating point format.
All implementations are required to support exact integers
between -2147483647 and 2147483647.
An implementation shall support exact integers
throughout the range of numbers that may be used for indexes of
lists and strings or that may result from computing the length of a
list or string. The length
and string-length procedures shall return an exact
integer, and it shall be 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, shall indeed be read as an exact
integer, regardless of any implementation restrictions that may apply
outside this range. Finally, the procedures listed below shall 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:
+ - *
quotient remainder modulo
max min abs
floor ceiling truncate
round expt
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 International Standard recommends, but does not require, that the
IEEE 32-bit
and 64-bit floating point standards be followed by implementations that use
floating point representations, and that implementations using
other representations should match or exceed the precision achievable
using these floating point standards.
In particular, implementations that use floating point representations
shall follow these rules. A floating point result
shall 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 quantity is operated upon so as to produce an inexact result
(as by sqrt), and if the result is represented as a floating point number, then
the most precise floating point format available shall be used; but if the result
is represented in some other way, then the representation shall have at
least as
much precision as the most precise floating point format available.
If an implementation encounters an exact numerical constant that
it cannot represent as an exact quantity, then it may either report a
violation of an implementation restriction, or it may silently represent the
constant by an inexact quantity.
8.5.7.4 Syntax of Numerical Constants
[78] number = num-2
| num-8
| num-10
| num-16
[79] num-2 =
#b
sign? digit-2+
[80] num-8 =
#o
sign? digit-8+
[81] num-16 =
#x
sign? digit-16+
[82] num-10 =
#d
? sign? decimal exponent? unit?
[83] decimal = digit-10+
|
.
digit-10+
| digit-10+
.
digit-10*
[84] exponent = exponent-marker sign? digit+
[85] exponent-marker =
e
[86] unit = unit-name (sign? digit-10+)?
[87] unit-name = letter+
[88] sign =
+
|
-
[89] digit-2 =
0
|
1
[90] digit-8 =
0
|
1
|
2
|
3
|
4
|
5
|
6
|
7
[91] digit-10 = digit
[92] digit-16 = digit-10
|
a
|
b
|
c
|
d
|
e
|
f
[93] digit =
0
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
A quantity 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 quantity is assumed to be expressed in decimal.
A numerical constant is
inexact if it contains a decimal point, an
exponent or
a
unit; otherwise, it is exact.
NOTE 15
The examples used in this section assume that any numerical constant written
using an exact notation is indeed represented as an exact
quantity. Some examples also assume that certain numerical constants written
using an inexact notation may be represented without loss of
accuracy; the inexact constants were chosen so that this is
likely to be true in implementations that use floating point numbers to represent
inexact quantities.
A numerical constant may have a unit suffix. Each unit-name
shall be the name of the base unit or shall be declared by
a unit-declaration.
A unit-name shall not be an
exponent-marker. If no number follows the unit-name, the
constant is multiplied by the quantity associated with the unit. If a
number with no sign or a sign of
+
follows the
unit-name, the constant is multiplied by the quantity associated
with the number name raised to the power of the following number. If a
number with a sign of
-
follows the unit-name, the
constant is divided by the quantity associated with the unit-name
raised to the power of the absolute value of the following number.
8.5.7.5 Number Type Predicates
(quantity?
obj
)
(number?
obj
)
(real?
obj
)
(integer?
obj
)
These type predicates may be applied to any kind of
argument, including non-quantities. 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 quantity, then all higher
type predicates are also true of that quantity. Consequently, if a type
predicate is false for a quantity, then all lower type predicates are
also false for that quantity.
If
x
is an inexact
real number, then
(integer?
x
)
is true if and only if
(=
x
(round
x
))
.
(real? 3) #t
(integer? 3.0) #t
NOTE 16
The behavior of these type predicates on inexact quantities
is unreliable, since any inaccuracy may affect the result.
8.5.7.6 Exactness Predicates
(exact?
q
)
(inexact?
q
)
These numerical predicates provide tests for the exactness of a
quantity. For any quantity, precisely one of these predicates
is true.
8.5.7.7 Comparison Predicates
(=
q1
q2
q3
…)
(<
q1
q2
q3
…)
(>
q1
q2
q3
…)
(<=
q1
q2
q3
…)
(>=
q1
q2
q3
…)
These procedures return #t if their arguments are (respectively):
equal, monotonically increasing, monotonically decreasing,
monotonically nondecreasing, or monotonically nonincreasing.
These predicates are required to be transitive.
The dimensions of all the arguments shall be identical.
NOTE 17
While it is not an error to compare inexact quantities using these
predicates, the results may be unreliable because a small inaccuracy
may affect the result; this is especially true of = and zero?.
8.5.7.8 Numerical Property Predicates
(zero?
q
)
(positive?
q
)
(negative?
q
)
(odd?
n
)
(even?
n
)
These predicates test a quantity for a particular property,
returning #t or #f. See note above.
8.5.7.9 Maximum and Minimum
(max
q1
q2
…)
(min
q1
q2
…)
These procedures return the maximum or minimum of their arguments.
The dimensions of all the arguments shall be identical;
the dimension of the result shall be the same as the dimension
of the arguments.
(max 3 4) 4 ; exact
(max 3.9 4) 4.0 ; inexact
NOTE 18
If any argument is inexact, then the result shall 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 quantities of mixed exactness, and the numerical
value of the result cannot be represented as an inexact quantity without loss of
accuracy, then the procedure may report a violation of an implementation
restriction.
8.5.7.10 Addition
(+
q1
…)
Returns the sum of its arguments, which shall all have the same
dimension. The result shall have the same dimension as
the arguments.
8.5.7.11 Multiplication
(*
q1
…)
Returns the product of its arguments.
The dimension of the result shall
be the sum of the dimensions of the arguments.
8.5.7.12 Subtraction
(-
q1
q2
)
(-
q
)
(-
q1
q2
…)
With two or more arguments, returns the difference of its arguments,
associating to the left; with one argument, returns the negation
of its argument.
The dimensions of all the arguments shall be identical.
The dimension of the result shall be the same as the dimension
of the arguments.
(- 3 4) -1
(- 3 4 5) -6
(- 3) -3
8.5.7.13 Division
(/
q1
q2
)
(/
q
)
(/
q1
q2
…)
With two or more arguments, returns the
quotient of its arguments, associating to the left; with one argument,
returns 1 divided by the argument.
The dimension of the result shall
be the difference of the dimensions of each of the arguments.
8.5.7.14 Absolute Value
(abs
q
)
Returns the magnitude of its argument.
8.5.7.15 Number-theoretic Division
(quotient
n1
n2
)
(remainder
n1
n2
)
(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 = n2n3 +n4 and
0 ≤ n4 < n2, then the following is true.
(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 is either zero or has the sign of the dividend,
whereas 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
8.5.7.16 Real to Integer Conversion
(floor
x
)
(ceiling
x
)
(truncate
x
)
(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.
round
rounds to even for consistency with the default rounding
mode specified by the IEEE floating point standard.
If the argument to one of these procedures is inexact, then the result
shall also be inexact. If an exact value is needed, the
result should be passed to the
inexact->exact
procedure.
(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) 7
8.5.7.17 en and Natural Logarithm
(exp
x
)
(log
x
)
Returns e raised to the power of
x
.
log computes the natural logarithm of
x
(not the base-ten logarithm). If
x
is
zero or negative, an error shall be signaled.
8.5.7.18 Trigonometric Functions
(sin
x
)
(cos
x
)
(tan
x
)
sin, cos, and tan return the sine, cosine, and
tangent of their arguments, respectively.
The result shall be a number.
8.5.7.19 Inverse Trigonometric Functions
(asin
x
)
(acos
x
)
(atan
x
)
(atan
q1
q2
)
asin, acos, and atan return
the arcsine, arccosine, and arctangent of their arguments,
respectively. The result shall be a number. The two-argument variant of atan returns the
angle of the complex number whose real part is the numerical value of
q2
and whose imaginary part is the numerical value of
q1
; the dimensions of
q1
and
q2
shall be
identical.
asin returns a value in the range -π/2
to π/2. acos returns a value in the
range 0 to π. atan
returns a value in the range -π/2 to
π/2.
8.5.7.20 Square Root
(sqrt
q
)
Returns the square root of
q
.
The dimension of
q
shall be even.
The dimension of the result shall
be half the dimension of
q
.
If
q
is negative, an error is signaled.
8.5.7.21 Exponentiation
(expt
x1
x2
)
Returns
x1
raised to the power
x2
.
(expt
x1
0)
is defined to be equal to 1.
8.5.7.22 Exactness Conversion
(exact->inexact
q
)
(inexact->exact
q
)
Exact->inexact returns an inexact representation of
q
.
The value returned is the
inexact quantity 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.
Inexact->exact returns an exact representation of
q
. The value returned is the exact quantity 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.
These procedures implement the natural one-to-one correspondence between
exact and inexact integers throughout an
implementation-dependent range.
8.5.7.23 Quantity to Number Conversion
(quantity->number
q
)
Returns the number of the quantity
q
.
8.5.7.24 Number to String Conversion
(number->string
number
)
(number->string
number
radix
)
Radix
shall 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
))
(equal? number
(string->number (number->string number
radix)
radix)))
is true. It shall be an error if no possible result makes this
expression true.
If
number
is inexact, the radix is 10, and the above expression
may 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 19
If
number
is an inexact number represented using floating-point
numbers, 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-floating-point representations.
(format-number
n
string
)
Returns a string representation of
n
.
string
specifies the
format to use as follows:
1
means use 0, 1, 2 …
01
means use 00, 01, 02, … 10, 11 … 100, 101 …
and similarly for any number
of leading zeros;
a
means use 0, a, b, c, … z, aa, ab, …
A
means use 0, A, B, C, … Z, AA, AB, …
i
means use 0, i, ii, iii, iv, v, vi, vii, viii, ix, x, …
I
means use 0, I, II, III, IV, V, VI, VII, VIII, IX, X, …
(format-number-list
list
obj1
obj2
)
Returns a string representation of
list
, where
list
is a list
of integers.
obj1
specifies the format to use for each
number. It shall be either a single string specifying the format to
use for all numbers in the same manner as format-number or a
list of strings with the same number of members as
list
specifying
the format to use for each string in the same manner as
format-number.
obj2
is either a single string or a
list of strings specifying the separator to be used between the
strings representing each number; it shall contain either a single
string or a list of strings with one fewer members than
list
.
8.5.7.25 String to Number Conversion
(string->number
string
)
(string->number
string
radix
)
Returns a number of the maximally precise representation expressed by the
given
string
.
radix
shall 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