12. Numbers

12.1 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
-conjugatelcm
/decf

Figure 12–1. Operators relating to Arithmetic.

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

abscossignum
acoscoshsin
acoshexpsinh
asinexptsqrt
asinhisqrttan
atanlogtanh
atanhphase
cispi

Figure 12–2. Defined names relating to Exponentials, Logarithms, and Trigonometry.

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

/=>=oddp
<evenpplusp
<=maxzerop
=min
>minusp

Figure 12–3. Operators for numeric comparison and predication.

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

ceilingfloat-radixrational
complexfloat-signrationalize
decode-floatfloorrealpart
denominatorfroundrem
fceilingftruncateround
ffloorimagpartscale-float
floatinteger-decode-floattruncate
float-digitsmod
float-precisionnumerator

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; !!! Is this a formal use of "should be signaled"? -kmp 13-May-91an 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. Internally an implementation might or might not use a two's-complement representation.

The next figure shows defined names relating to logical operations on numbers.

ashboole-iorlogbitp
booleboole-nandlogcount
boole-1boole-norlogeqv
boole-2boole-orc1logior
boole-andboole-orc2lognand
boole-andc1boole-setlognor
boole-andc2boole-xorlognot
boole-c1integer-lengthlogorc1
boole-c2logandlogorc2
boole-clrlogandc1logtest
boole-eqvlogandc2logxor

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.

bytedeposit-fieldldb-test
byte-positiondpbmask-field
byte-sizeldb

Figure 12–6. Defined names relating to byte manipulation.

12.1.2 Implementation-Dependent Numeric Constants#

The next figure shows defined names relating to implementation-dependent details about numbers.

double-float-epsilonmost-negative-fixnum
double-float-negative-epsilonmost-negative-long-float
least-negative-double-floatmost-negative-short-float
least-negative-long-floatmost-negative-single-float
least-negative-short-floatmost-positive-double-float
least-negative-single-floatmost-positive-fixnum
least-positive-double-floatmost-positive-long-float
least-positive-long-floatmost-positive-short-float
least-positive-short-floatmost-positive-single-float
least-positive-single-floatshort-float-epsilon
long-float-epsilonshort-float-negative-epsilon
long-float-negative-epsilonsingle-float-epsilon
most-negative-double-floatsingle-float-negative-epsilon

Figure 12–7. Defined names relating to implementation-dependent details about numbers.

12.1.3 Rational Computations#

12.1.0 2The rules in this section apply to rational computations.

12.1.3.1 Rule of Unbounded Rational Precision#

Rational computations cannot overflow in the usual sense (though there may not be enough storage to represent a result), since integers and ratios may in principle be of any magnitude.

12.1.3.2 Rule of Canonical Representation for Rationals#

If any computation produces a result that is a mathematical ratio of two integers such that the denominator evenly divides the numerator, then the result is converted to the equivalent integer.

2.1.2 1 This had been removed, but I couldn't figure out why, so I reinstated it. -kmp 19-Oct-91If the denominator does not evenly divide the numerator, the canonical representation of a rational number is as the ratio that numerator and that denominator, where the greatest common divisor of the numerator and denominator is one, and where the denominator is positive and greater than one.

When used as input (in the default syntax), the notation -0 always denotes the integer 0. A conforming implementation must not have a representation of “minus zero” for integers that is distinct from its representation of zero for integers. However, such a distinction is possible for floats; see the type float.

12.1.3.3 Rule of Float Substitutability#

12.5.0 4When the arguments to an irrational mathematical function Reviewer: Barmar: There should be a table of these functions. are all rational and the true mathematical result is also (mathematically) rational, then unless otherwise noted an implementation is free to return either an accurate rational result or a single float approximation. If the arguments are all rational but the result cannot be expressed as a rational number, then a single float approximation is always returned.

If the arguments to Added "irrational" per Boyer/Kaufmann/Moore #14 (by X3J13 vote at May 4-5, 1994 meeting) -kmp 9-May-94 aan irrational mathematical function are all of type (or rational (complex rational)) and the true mathematical result is (mathematically) a complex number with rational real and imaginary parts, then unless otherwise noted an implementation is free to return either an accurate result of type (or rational (complex rational)) or a single float (permissible only if the imaginary part of the true mathematical result is zero) or (complex single-float). If the arguments are all of type (or rational (complex rational)) but the result cannot be expressed as a rational or complex rational, then the returned value will be of type single-float (permissible only if the imaginary part of the true mathematical result is zero) or (complex single-float).

Added per Boyer/Kaufmann/Moore #14 (by X3J13 vote at May 4-5, 1994 meeting) -kmp 9-May-94Float substitutability applies neither to the rational functions +, -, *, and / nor to the related operators 1+, 1-, incf, decf, and conjugate. For rational functions, if all arguments are rational, then the result is rational; if all arguments are of type (or rational (complex rational)), then the result is of type (or rational (complex rational)).

#c(1 0) => 1 per Boyer/Kaufmann/Moore #14 (by X3J13 vote at May 4-5, 1994 meeting) -kmp 9-May-94
FunctionSample Results
abs(abs #c(3 4)) → 5 or 5.0
acos(acos 1) → 0 or 0.0
acosh(acosh 1) → 0 or 0.0
asin(asin 0) → 0 or 0.0
asinh(asinh 0) → 0 or 0.0
atan(atan 0) → 0 or 0.0
atanh(atanh 0) → 0 or 0.0
cis(cis 0) → 1 or #c(1.0 0.0)
cos(cos 0) → 1 or 1.0
cosh(cosh 0) → 1 or 1.0
exp(exp 0) → 1 or 1.0
expt(expt 8 1/3) → 2 or 2.0
log(log 1) → 0 or 0.0
(log 8 2) → 3 or 3.0
phase(phase 7) → 0 or 0.0
signum(signum #c(3 4)) → #c(3/5 4/5) or #c(0.6 0.8)
sin(sin 0) → 0 or 0.0
sinh(sinh 0) → 0 or 0.0
sqrt(sqrt 4) → 2 or 2.0
(sqrt 9/16) → 3/4 or 0.75
tan(tan 0) → 0 or 0.0
tanh(tanh 0) → 0 or 0.0

Figure 12–8. Functions Affected by Rule of Float Substitutability

12.1.4 Floating-point Computations#

The following rules apply to floating point computations.

12.1.4.1 Rule of Float and Rational Contagion#

Barmar noted that the following was said in two different places. I've removed the most casually worded of the two. Hopefully no useful info was lost in the process. -kmp 19-Oct-91 For \term{functions} that combine arguments of different \term{types}, when one argument is a \term{rational} and the other is a \term{float}, the \term{rational} is first converted to a \term{float} of the same format. For \term{functions} that compare arguments of different \term{types}, when one argument is a \term{rational} and the other is a \term{float}, \thefunction{rational} is effectively called to convert the \term{float} to a \term{rational} and then an exact comparison is performed. In the case of \term{complex} numbers, the real and imaginary parts are effectively handled individually.

12.1.0 3When rationals and floats are combined by a numerical function, the rational is first converted to a float of the same format. For functions such as + that take more than two arguments, it is permitted that part of the operation be carried out exactly using rationals and the rest be done using floating-point arithmetic.

When rationals and floats are compared by a numerical function, the function rational is effectively called to convert the float to a rational and then an exact comparison is performed. In the case of complex numbers, the real and imaginary parts are effectively handled individually.

12.1.4.1.1 Examples of Rule of Float and Rational Contagion#
 ;;;; Combining rationals with floats.
 ;;; This example assumes an implementation in which 
 ;;; (float-radix 0.5) is 2 (as in IEEE) or 16 (as in IBM/360),
 ;;; or else some other implementation in which 1/2 has an exact 
 ;;;  representation in floating point.
 (+ 1/2 0.5) → 1.0
 (- 1/2 0.5d0) → 0.0d0
 (+ 0.5 -0.5 1/2) → 0.5

 ;;;; Comparing rationals with floats.
 ;;; This example assumes an implementation in which the default float 
 ;;; format is IEEE single-float, IEEE double-float, or some other format
 ;;; in which 5/7 is rounded upwards by FLOAT.
 (< 5/7 (float 5/7)) → true
 (< 5/7 (rational (float 5/7))) → true
 (< (float 5/7) (float 5/7)) → false
(< 5/7 (rationalize (float 5/7))) \EV \term{implementation-dependent} Moon: The rationalize example is screwy since the two lines preceding it are also implementation-dependent. Also I don't think it sheds any light on the issue at hand (see the name of the subsubsection), so flush it.

12.1.4.2 Rule of Float Approximation#

Computations with floats are only approximate, although they are described as if the results were mathematically accurate. Two mathematically identical expressions may be computationally different because of errors inherent in the floating-point approximation process. The precision of a float is not necessarily correlated with the accuracy of that number. For instance, 3.142857142857142857 is a more precise approximation to π than 3.14159, but the latter is more accurate. The precision refers to the number of bits retained in the representation. When an operation combines a short float with a long float, the result will be a long float. Common Lisp functions assume that the accuracy of arguments to them does not exceed their precision. Therefore when two small floats are combined, the result is a small float. Common Lisp functions never convert automatically from a larger size to a smaller one.

12.1.4.3 Rule of Float Underflow and Overflow#

An error of type floating-point-overflow or floating-point-underflow should be signaled if a floating-point computation causes exponent overflow or underflow, respectively.

12.1.4.4 Rule of Float Precision Contagion#

The following was said in two different places. I've removed the most casually worded of the two. Hopefully no useful info was lost in the process. -kmp 19-Oct-91 When a shorter \term{float} is combined with a longer one in an operation, the result will be of the \term{type} of the longer of the two \term{floats}.

12.1.0 5The result of a numerical function is a float of the largest format among all the floating-point arguments to the function.

12.1.5 Complex Computations#

12.1.0 6The following rules apply to complex computations:

12.1.5.1 Rule of Complex Substitutability#

Except during the execution of irrational and transcendental functions, no numerical function ever yields a complex unless one or more of its arguments is a complex.

12.1.5.2 Rule of Complex Contagion#

When a \issue{REAL-NUMBER-TYPE:X3J13-MAR-89} \term{real} \endissue{REAL-NUMBER-TYPE:X3J13-MAR-89} number \reviewer{Barmar: I don't like the word `meets' here.} \editornote{KMP: This is all said redundantly in \secref\ComplexComputations\ below, so maybe we can merge the two, somehow.} %!!! 26-Dec-90 meets a \term{complex} number, the \issue{REAL-NUMBER-TYPE:X3J13-MAR-89} \term{real} \endissue{REAL-NUMBER-TYPE:X3J13-MAR-89} number is in effect first converted to a \term{complex} number by providing an imaginary part of {\tt $0$}.When a real and a complex are both part of a computation, the real is first converted to a complex by providing an imaginary part of 0.

12.1.5.3 Rule of Canonical Representation for Complex Rationals#

12.1.0 8If the result of any computation would be a complex number whose real part is of type rational and whose imaginary part is zero, the result is converted to the rational which is the real part. This rule does not apply to complex numbers whose parts are floats. For example, #C(5 0) and 5 are not different objects in Common Lisp (they are always the same under eql); #C(5.0 0.0) and 5.0 are always different objects in Common Lisp (they are never the same under eql, although they are the same under equalp and =).

12.1.5.3.1 Examples of Rule of Canonical Representation for Complex Rationals#
 #c(1.0 1.0) → #C(1.0 1.0)
 #c(0.0 0.0) → #C(0.0 0.0)
 #c(1.0 1) → #C(1.0 1.0)
 #c(0.0 0) → #C(0.0 0.0)
 #c(1 1) → #C(1 1)
 #c(0 0) → 0
 (typep #c(1 1) '(complex (eql 1))) → true
 (typep #c(0 0) '(complex (eql 0))) → false

12.1.5.4 Principal Values and Branch Cuts#

Many of the irrational and transcendental functions are multiply defined in the complex domain; for example, there are in general an infinite number of complex values for the logarithm function. In each such case, a principal value must be chosen for the function to return. In general, such values cannot be chosen so as to make the range continuous; lines in the domain called branch cuts must be defined, which in turn define the discontinuities in the range. 12.5.3 2 Common Lisp defines the branch cuts, principal values, and boundary conditions for the complex functions following “Principal Values and Branch Cuts in Complex APL.” The branch cut rules that apply to each function are located with the description of that function.

12.5.3 17The next figure lists the identities that are obeyed throughout the applicable portion of the complex domain, even on the branch cuts:

sin i z = i sinh z sinh i z = i sin z arctan i z = i arctanh z
cos i z = cosh z cosh i z = cos z arcsinh i z = i arcsin z
tan i z = i tanh z arcsin i z = i arcsinh z arctanh i z = i arctan z

Figure 12–9. Trigonometric Identities for Complex Domain

The quadrant numbers referred to in the discussions of branch cuts are as illustrated in the next figure.

JGA requested this. This is amazingly low-tex and the spacing of dots isn't quite right, but I think it's good enough to be intelligible and will suffice until and unless something better is devised. -kmp 3-Feb-92

PositiveImaginaryAxis II INegativeRealAxisPositiveRealAxis III IVNegativeImaginaryAxis

Quadrant Numbering for Branch Cuts

12.1.6 Interval Designators#

The compound type specifier form of the numeric type specifiers Removed per Boyer/Kaufmann/Moore #15 (by X3J13 vote at May 4-5, 1994 meeting) -kmp 9-May-94 in \thenextfigure\permit the user to specify an interval on the real number line which describe a subtype of the type which would be described by the corresponding atomic type specifier. A subtype of some type T is specified using an ordered pair of objects called interval designators for type T.

The first of the two interval designators for type T can be any of the following:

The second of the two interval designators for type T can be any of the following:

12.1.7 Random-State Operations#

The next figure lists some defined names that are applicable to random states.

*random-state*random
make-random-staterandom-state-p

Figure 12–10. Random-state defined names

Dictionary