Common Lisp provides a large variety of operations related to numbers. This section provides an overview of those operations by grouping them into categories that emphasize some of the relationships among them.
The next figure shows operators relating to arithmetic operations.
The next figure shows defined names relating to exponential, logarithmic, and trigonometric operations.
|
Figure 12.2: Defined names relating to Exponentials, Logarithms, and Trigonometry.
The next figure shows operators relating to numeric comparison and predication.
|
Figure 12.3: Operators for numeric comparison and predication.
The next figure shows defined names relating to numeric type manipulation and coercion.
|
Figure 12.4: Defined names relating to numeric type manipulation and coercion.
For functions that are mathematically associative (and possibly commutative), a conforming implementation may process the arguments in any manner consistent with associative (and possibly commutative) rearrangement. This does not affect the order in which the argument forms are evaluated; for a discussion of evaluation order, see Section 3.1.2.1.2.3 (Function Forms). What is unspecified is only the order in which the parameter values are processed. This implies that implementations may differ in which automatic coercions are applied; see Section 12.1.1.2 (Contagion in Numeric Operations).
A conforming program can control the order of processing explicitly by separating the operations into separate (possibly nested) function forms, or by writing explicit calls to functions that perform coercions.
Consider the following expression, in which we assume that 1.0
and
1.0e-15
both denote single floats:
(+ 1/3 2/3 1.0d0 1.0 1.0e-15)
One conforming implementation might
process the arguments from left to right,
first adding 1/3
and 2/3
to get 1
,
then converting that to a double float
for combination with 1.0d0
,
then successively converting and adding 1.0
and 1.0e-15
.
Another conforming implementation might process the arguments from
right to left, first performing a single float addition of 1.0
and
1.0e-15
(perhaps losing accuracy in the process), then converting the sum to
a double float and adding 1.0d0
, then converting 2/3
to a
double float and adding it, and then converting 1/3
and adding that.
A third conforming implementation might first scan all the arguments, process all the rationals first to keep that part of the computation exact, then find an argument of the largest floating-point format among all the arguments and add that, and then add in all other arguments, converting each in turn (all in a perhaps misguided attempt to make the computation as accurate as possible).
In any case, all three strategies are legitimate.
A conforming program could control the order by writing, for example,
(+ (+ 1/3 2/3) (+ 1.0d0 1.0e-15) 1.0)
For information about the contagion rules for implicit coercions of arguments in numeric operations, see Section 12.1.4.4 (Rule of Float Precision Contagion), Section 12.1.4.1 (Rule of Float and Rational Contagion), and Section 12.1.5.2 (Rule of Complex Contagion).
Logical operations require integers as arguments;
an error of type type-error
should be signaled
if an argument is supplied that is not an integer.
Integer arguments to logical operations are treated as if
they were represented in two's-complement notation.
The next figure shows defined names relating to logical operations on numbers.
|
Figure 12.5: Defined names relating to logical operations on numbers.
The byte-manipulation functions use objects
called byte specifiers to designate the size and position
of a specific byte within an integer.
The representation of a byte specifier is implementation-dependent;
it might or might not be a number.
The function byte
will construct a byte specifier,
which various other byte-manipulation functions will accept.
The next figure shows defined names relating to manipulating bytes of numbers.