Star Sapphire Common LISP Home

Download Star Saphire
Index

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.