Next: , Up: Number Concepts


12.1.1 Numeric Operations

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.

* 1+ gcd
+ 1- incf
- conjugate lcm
/ decf

Figure 12.1: Operators relating to Arithmetic.

The next figure shows defined names relating to exponential, logarithmic, and trigonometric operations.

abs cos signum
acos cosh sin
acosh exp sinh
asin expt sqrt
asinh isqrt tan
atan log tanh
atanh phase
cis pi

Figure 12.2: Defined names relating to Exponentials, Logarithms, and Trigonometry.

The next figure shows operators relating to numeric comparison and predication.

/= >= oddp
< evenp plusp
<= max zerop
= min
> minusp

Figure 12.3: Operators for numeric comparison and predication.

The next figure shows defined names relating to numeric type manipulation and coercion.

ceiling float-radix rational
complex float-sign rationalize
decode-float floor realpart
denominator fround rem
fceiling ftruncate round
ffloor imagpart scale-float
float integer-decode-float truncate
float-digits mod
float-precision numerator

Figure 12.4: Defined names relating to numeric type manipulation and coercion.

12.1.1.1 Associativity and Commutativity in Numeric Operations

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.

12.1.1.1.1 Examples of Associativity and Commutativity in Numeric Operations

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)
12.1.1.2 Contagion in Numeric Operations

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

12.1.1.3 Viewing Integers as Bits and Bytes
12.1.1.3.1 Logical Operations on Integers

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.

ash boole-ior logbitp
boole boole-nand logcount
boole-1 boole-nor logeqv
boole-2 boole-orc1 logior
boole-and boole-orc2 lognand
boole-andc1 boole-set lognor
boole-andc2 boole-xor lognot
boole-c1 integer-length logorc1
boole-c2 logand logorc2
boole-clr logandc1 logtest
boole-eqv logandc2 logxor

Figure 12.5: Defined names relating to logical operations on numbers.

12.1.1.3.2 Byte Operations on Integers

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.

byte deposit-field ldb-test
byte-position dpb mask-field
byte-size ldb

Figure 12.6: Defined names relating to byte manipulation.