12. NUMBERS
This chapter contains the following sections:
12.0 Introduction to Common LISP numbers
12.1 Numeric conversion
12.2 Predicates on Numbers
12.3 Comparisons on Numbers
12.4 Arithmetic Operations
12.5 Irrational and Transcendental Functions
12.6 Type Conversions and Component Extractions on Numbers
12.7 Logical Operations on Numbers
12.8 Random Numbers
12.9 Implementation Parameters
12.0 Introduction to Common LISP numbers
Common LISP provides several different representations for numbers. These representations may be divided into three categories: integers, ratios, and numbers. Many numeric functions will accept any kind of number; they are generic. Other functions accept only certain kinds of numbers.
In general, numbers in Common LISP are no true objects; eq cannot be counted upon to operate on them reliably. In particular, it is possible that the expression
(let ((x z) (y z)) (eq x y))
may be false rather than true if the value of z is a number.
If two objects are to be compared for "identity," but either might be a number, then the predicate eq1 is probably appropriate; if both objects are known to be numbers, then = may be preferable.
12.1 Numeric conversion
Rational computations cannot overflow in the usual sense (though of course there may not be enough storage to represent one), as integers and ratios may in principle be of any magnitude. Floating-point computations may get exponent overlow or underflow; this is an error. When rational and floating-point numbers are compared or combined by a numerical function, the rule of floating-point contagion is followed: When a rational meets a floating-point number, the rational is first converted to a floating-point number of the same format. For functions such as + that take more than two arguments, it may be that part of the operation is carried out exactly using rationals and then the rest is done using floating-point arithmetic.
The arguments in numeric expressions are processed from left to right. Types of intermediate results are based on a comparison of the type of the next argument.
In general, then, the type of the result of a numerical function is a floating-point number if there are floating-point arguments; but if the arguments are all rational, then the result is rational.
If any computation produces a result that is a ratio of two integers such that the denominator evenly divides the numerator, then the result is immediately converted to the equivalent integer. This is called the rule of rational canonicalization.
12.2 Predicates on Numbers
Each of the following functions tests a single number for a specific property. Each function requires that its argument be a number; to call one with a non-number is an error.
zerop
plusp
minusp
oddp
evenp
12.3 Comparisons on Numbers
Each of the functions in this section requires that its arguments all be numbers; to call one with a non-number is an error. Unless otherwise specified, each works on all types of numbers, automatically performing any required coercions when arguments are of different types.
=
/=
<
>
<=
>=
max
min
12.4 Arithmetic Operations
Each of the functions in this section requires that its arguments all be numbers; to call one with a non-number is an error. Unless otherwise specified, each works on all types of numbers, automatically performing any required coercions when arguments are of different types.
+
-
*
/
1+
1-
incf
decf
gcd
lcm
12.5 Irrational and Transcendental Functions
For information on functions related to irrational and transcendental numbers refer to the following topics:
12.5.1 Exponential and Logarithmic Functions
12.5.2 Trigonometric and Related Functions
Common LISP provides no data type that can accurately represent irrational numerical values. The functions in this section are described as if the results were mathematically accurate, but actually they all produce floating-point approximations to the true mathematical result in the general case. In some places mathematical identities are set forth that are intended to elucidate the meanings of the functions; however, two mathematically identical expressions may be computationally different because of errors inherent in the floating-point approximation process.
When the arguments to a function in this section 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 result of type rational or a single-precision floating-point approximation. If the arguments are all rational but the result cannot be expressed as a rational number, then a single-precision floating-point approximation is always returned.
The rules of floating-poin contagion are effectively obeyed by all the functions in this section except expt, which treats some cases of rational exponents specially.
12.5.1 Exponential and Logarithmic Functions
Along with the usual one-argument and two-argument exponential and logarithm functions, sqrt is considered to be an exponential function, because it raises a number to the power 1/2.
exp
expt
log
sqrt
isqrt
12.5.2 Trigonometric and Related Functions
The following trigonometric functions are provided in Star Sapphire:
sin
sinh
cos
cosh
tan
tanh
asin
asinh
acos
atan
atanh
pi
The following two functions may be useful in this connection:
abs
signum
12.6 Type Conversions and Component Extractions on Numbers
While most arithmetic functions will operate on any kind of number, coercing types if necessary, the following functions are provided to allow specific conversions of data types to be forced when desired.
float
numerator
denominator
In Common LISP there are several ways to convert non-integral values to integers. These are provided by the functions below, which perform not only type-conversion but also some non-trivial calculations as well.
floor
ceiling
truncate
round
mod
rem
ffloor
fceiling
ftruncate
fround
12.7 Logical Operations on Numbers
The logical operations in this section require integers as arguments; it is an error to supply a non-integer as an argument. The functions all treat integers as if they were represented in two's-complement notation.
The logical operations provide a convenient way to represent an infinite vector of bits. Let such a conceptual vector be indexed by the non-negative integers. Then bit j is assigned a weight 2j. Assume that only a finite number of bits are ones or only a finite number of bits are zeros. A vector with only a finite number of one-bits is represented as the sum of the weights of the one-bits, a positive integer. A vector with only a finite number of zero-bits is represented as -1 minus the sum of the weights of the zero-bits, a negative integer.
This method of using integers to represent bit-vectors can in turn be used to represent sets. Suppose that some (possibly countably infinite) universe of discourse for sets is mapped into the non-negative integers. Then a set can be represented as a bit vector; an element is in the set if the bit whose index corresponds to that element is a one-bit. In this way all finite sets can be represented (by positive integers), as well as all sets whose complements are finite (by negative integers). The functions logior, logand, and logxor defind below then compute the union, intersection, and symmetric difference operations on sets represented in this way.
The following functions support the bitwise logical operations:
logand
logior
logxor
logeqv
lognand
lognor
logandc1
logandc2
logorc1
logorc2
The ten bit-wise logical operations on two integers are summarized in this table:
Argument 1 |
0 |
0 |
1 |
1 |
|
Argument 2 |
0 |
1 |
0 |
1 |
Operation Name |
logand |
0 |
0 |
0 |
1 |
and |
logior |
0 |
1 |
1 |
1 |
inclusive or |
logxor |
0 |
1 |
1 |
0 |
exclusive or |
logec |
1 |
0 |
0 |
1 |
equivalence (exclusive nor) |
lognand |
1 |
1 |
1 |
0 |
not-and |
lognor |
1 |
0 |
0 |
0 |
not-or |
logandc1 |
0 |
1 |
0 |
0 |
and complement of arg1 with arg2 |
Argument 1 |
0 |
0 |
1 |
1 |
|
Argument 2 |
0 |
1 |
0 |
1 |
Operation Name |
logandc2 |
0 |
0 |
1 |
0 |
and arg1 with complement of arg2 |
logorc1 |
1 |
1 |
0 |
1 |
or complement of arg1 with arg2 |
logorc2 |
1 |
0 |
1 |
1 |
or argl with complement of arg2 |
The boole function performs a logical operation on its arguments,based on the value of its 'operation' argument:
boole
The following constants, defined in init0.lsp, can be used with boole:
boole-clr
boole-set
boole-1
boole-2
boole-c1
boole-c2
boole-and
boole-ior
boole-xor
boole-eqv
boole-nand
boole-nor
boole-andc1
boole-andc2
boole-orc1
boole-orc2
The following functions also perform bit operations on integers:
ash
logcount
integer-length
12.8 Random Numbers
Common LISP has a random number facility. Refer to the entries for:
random
make-random-state
random-state-p
12.9 Implementation Parameters
The values of the named constants defined in this section are implementation-dependent. They may be useful for parameterizing code in some situations.
In general, these and other constants are defined in init0.lsp. To use their definitions, you can extract the required defconstant declaration from that file.
most-positive-fixnum
most-negative-fixnum
The value of most-positive-fixnum is that fixnum closest in value to positive infinity provided by the implementation. The value of most-negative-fixnum is that fixnum closest in value to negative infinity provided by the implementation.
most-positive-short-float
least-positive-short-float
least-negative-short-float
most-negative-short-float
The value of most-positive-short-float is that short-format floating-point number closest in value to (but not equal to) positive infinity provided by the implementation.
The value of least-positive-short-float is that positive short-format floating-point number closest in value to (but not equal to) zero provided by the implementation.
The value of least-negative-short-float is that negative short-format floating-point number closest in value to (but not equal to) zero provided by the implementation.
The value of most-negative-short-float is that short-format floating-point number closest in value to (but not equal to) negative infinity provided by the implementation.
most-positive-single-float
least-positive-single-float
least-negative-single-float
most-negative-single-float
most-positive-double-float
least-positive-double-float
least-negative-double-float
most-negative-double-float
most-positive-long-float
least-positive-long-float
least-negative-long-float
most-negative-long-float
These are analogous to the constants defined above for short-format floating-point numbers.
short-float-epsilon
single-float-epsilon
double-float-epsilon
long-float-epsilon
These constants have as value, for each floating-point format, the smallest positive floating-point number e of that format such that the expression
(not (= (float 1 e) (+ (float 1 e) e)))
is true when actually evaluated.
short-float-negative-epsilon
single-float-negative-epsilon
double-float-negative-epsilon
long-float-negative-epsilon
These constants have as value, for each floating-point format, the smallest positive floating-point number e of that format such that the expression
(not (= (float 1 e) (- (float 1 e) e)))
is true when actually evaluated.