Zetalisp includes several types of numbers, with different
characteristics. Most numeric functions accept any type of numbers as
arguments and do the right thing. That is to say, they are

The types of numbers in Zetalisp are:

Fixnums are 25-bit twos-complement binary integers. These are the preferred, most efficient type of number. | |

Bignums are arbitrary-precision binary integers. | |

Ratios represent rational numbers exactly as the quotient of two integers, each of which can be a fixnum or a bignum. Ratios with a denominator of one are not normally created, as an integer is returned instead. | |

Full size floats are floating-point numbers. They have a mantissa of 31 bits and an exponent of 11 bits, providing a precision of about 9 digits and a range of about 10^300. Stable rounding is employed. | |

Short floats are another form of floating-point number, with a mantissa of 17 bits and an exponent of 8 bits, providing a precision of about 5 digits and a range of about 10^38. Stable rounding is employed. Short floats are useful because, like fixnums, and unlike full-size floats, they don't require any storage. Computing with short floats is more efficient than with full-size floats because the operations are faster and consing overhead is eliminated. | |

Complexnums represent complex numbers with a real part and an imaginary
part, which can be any type of number except complexnums. (They must be
both rational or both floats of the same type). It is impossible to
make a complexnum whose real part is rational and whose imaginary part
is the intreger zero; it is always changed into a real number. However, it |

Generally, Lisp objects have a unique identity; each exists, independent
of any other, and you can use the

Conversely, fixnums and short floats have the unusual property that
they are always

The distinction between fixnums and bignums is largely transparent to
the user. The user simply computes with integers, and the system
represents some as fixnums and the rest (less efficiently) as bignums.
The system automatically converts back and forth between fixnums and
bignums based solely on the size of the integer. There are a few low
level functions which only work on fixnums; this fact is noted in
their documentation. Also, when using

Integer computations cannot overflow, except for division by zero,
since bignums can be of arbitrary size. Floating-point computations
can get exponent overflow or underflow, if the result is too large or small
to be represented. Exponent overflow always signals an error.
Exponent underflow normally signals an error, and assumes

When an arithmetic function of more than one argument is given arguments
of different numeric types, uniform

If any argument of the arithmetic function is complex, the other arguments are converted to complex. The components of a complex result must be both full-size floats, both small-floats, or both rational; if they differ, the one whose type comes last in that list is converted to match the other. Finally, if the components of the result are rational and the imaginary part is zero, the result is simply the real part. If, however, the components are floats, the value is always complex even if the imaginary part is zero.

Thus if the constants in a numerical algorithm are written as short floats (assuming this provides adequate precision), and if the input is a short float, the computation is done with short floats and the result is a short float, while if the input is a full-size float the computation is done in full precision and the result is a full-size float.

Zetalisp never automatically converts between full-size floats and short floats in the same way as it automatically converts between fixnums and bignums since this would lead either to inefficiency or to unexpected numerical inaccuracies. (When a short float meets a full-size float, the result is a full-size float, but if you use only one type, all the results are of the same type too.) This means that a short float computation can get an exponent overflow error even when the result could have been represented as a full-size float.

Floating-point numbers retain only a certain number of bits of precision; therefore, the results of computations are only approximate. Full-size floats have 31 bits and short floats have 17 bits, not counting the sign. The method of approximation is ``stable rounding''. The result of an arithmetic operation is the float which is closest to the exact value. If the exact result falls precisely halfway between two representable floats, the result is rounded down if the least-significant bit is 0, or up if the least-significant bit is 1. This choice is arbitrary but insures that no systematic bias is introduced.

Unlike Maclisp, Zetalisp does not have number declarations in the compiler. Note that because fixnums and short floats require no associated storage they are as efficient as declared numbers in Maclisp. Bignums and full-size floats are less efficient; however, bignum and float intermediate results are garbage-collected in a special way that avoids the overhead of the full garbage collector.

The different types of numbers can be distinguished by their printed
representations. If a number has an exponent separated by `

x < 0 | |

x | |

x = 0 | |

x | |

x | |

x > 0 |

See also the data-type predicates

All of these functions require that their arguments be numbers; they signal an error if given a non-number. Equality tests work on all types of numbers, automatically performing any required coercions (as opposed to Maclisp in which generally only the spelled-out names work for all kinds of numbers). Ordering comparisons allow only real numbers, since they are meaningless on complex numbers.

See also

All of these functions require that their arguments be numbers, and signal
an error if given a non-number. They work on all types of numbers,
automatically performing any required coercions (as opposed to Maclisp,
in which generally only the spelled-out versions work for all kinds
of numbers, and the `

There are four functions for ``integer division'', the sort which produces a quotient and a remainder. They differ in how they round the quotient to an integer, and therefore also in the sign of the remainder. The arguments must be real, since ordering is needed to compute the value. The quotient is always an integer, but the arguments and remainder need not be.

Here is a table which clarifies the meaning of

There are two kinds of remainder function, which differ in the treatment of negative numbers. The remainder can also be obtained as the second value of one of the integer division functions above, but if only the remaineder is desired it is simpler to use these functions.

There are four ``floating point integer division'' functions. These produce a result which is a floating point number whose value is exactly integral.

See also the predicates

These functions are only for floating-point arguments; if given an integer they convert it to a float. If given a short float, they return a short float.

These functions are provided to allow specific conversions of data types to be forced, when desired.

Except for

Non-associative bitwise operations take only two arguments:

Several functions are provided for dealing with an arbitrary-width field of
contiguous bits appearing anywhere in an integer (a fixnum or a bignum).
Such a contiguous set of bits is called a

The maximum value of the size is 24, since a byte must fit in a fixnum although bytes can be loaded from and deposited into bignums. (Bytes are always positive numbers.)

Byte specifiers are represented as fixnums whose two lowest octal digits
represent the

Much old code contains byte specifiers written explicitly as octal numbers.
It is cleaner to construct byte specifiers using

The behavior of the following two functions depends on the size of
fixnums, and so functions using them may not work the same way
on future implementations of Zetalisp. Their names start
with

The functions in this section provide a pseudo-random number generator
facility. The basic function you use is

A

A random-state actually consists of an array of numbers and two pointers
into the array. The pointers circulate around the array; each time a
random number is requested, both pointers are advanced by one, wrapping
around at the end of the array. Thus, the distance forward from the
first pointer to the second pointer stays the same, allowing for
wraparound. Let the length of the array be

This algorithm produces well-distributed random numbers if

The contents of the array of numbers should be initialized to anything
moderately random, to make the algorithm work. The contents get
initialized by a simple random number generator, based on a
number called the

Common Lisp defines some constants whose values give information in a standard way about the ranges of numbers representable in the individual Lisp implementation.

Sometimes it is desirable to have a form of arithmetic which has no overflow checking (that would produce bignums), and truncates results to the word size of the machine.

Sometimes it is useful to have a form of truncating arithmetic with a strictly specified field width which is independent of the range of fixnums permissible on a particular machine. In Zetalisp, this is provided by the following set of functions. Their answers are correct only modulo 2^24.

These functions should

These peculiar functions are useful in programs that don't want to use bignums for one reason or another. They should usually be avoided, as they are difficult to use and understand, and they depend on special numbers of bits and on the use of twos-complement notation.

A double-precision number has 50 bits, of which one is the sign bit. It
is represented as two fixnums. The less signficant fixnum conveys 25
signficant bits and is regarded as unsigned (that is, what is normally
the sign bit is treated as an ordinary data bit); the more significant
fixnum has the same sign as the double-precision number. Only