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.
(+ 3 4)                   7
(+ 3)                     3
(+)                       0
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.
(* 4)                     4
(*)                       1
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.
(/ 3 4 5)                 3/20
(/ 3)                     1/3
8.5.7.14 Absolute Value
(abs q)
Returns the magnitude of its argument.
(abs -7)                  7
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