Function EXT:!
(
returns the
factorial of EXT:!
n
)n
, n
being a nonnegative INTEGER
.
Function EXT:EXQUO
. (
returns
the integer quotient EXT:EXQUO
x
y
)x/y
of two integers
x
,y
, and SIGNAL
s an ERROR
when the quotient is not
integer. (This is more efficient than /
.)
Function EXT:XGCD
. (
returns the values EXT:XGCD
x_{1}
... x_{n}
)l
, k_{1}
, ..., k_{n}
, where l
is the
greatest common divisor of the integers x_{1}
, ..., x_{n}
, and
k_{1}
, ..., k_{n}
are the integer coefficients such that
l
= (GCD
x_{1}
...x_{n}
) = (+ (*k_{1}
x_{1}
) ... (*k_{n}
x_{n}
))
Function EXT:MODEXPT
. (
is equivalent to EXT:MODEXPT
k
l
m
)(
except it is more efficient for very large arguments.MOD
(EXPT
k
l
) m
)
DECODEFLOAT
FLOATRADIX
always returns 2.
(
coerces
FLOATDIGITS
number
digits
)number
(a REAL
) to a floating point number with at least
digits
mantissa digits. The following always evaluates to T
:
(>=
(FLOATDIGITS
(FLOATDIGITS
number
digits
))digits
)
Byte specifiers are objects of builtin type BYTE,
not INTEGER
s.
Function EXPT
. (
is not very precise if EXPT
base
exponent
)exponent
has a large
absolute value.
Function LOG
. (
LOG
number
base
)SIGNAL
s an ERROR
if
.base
= 1
Constant PI
. The value of PI
is a LONGFLOAT
with the precision given
by (
. When this precision is changed, the value of EXT:LONGFLOATDIGITS
)PI
is
automatically recomputed. Therefore PI
is not a constant variable.
Function UPGRADEDCOMPLEXPARTTYPE
. When the argument is not a recognizable subtype or REAL
,
UPGRADEDCOMPLEXPARTTYPE
SIGNAL
s an ERROR
, otherwise it
returns its argument (even though a COMPLEX
number in CLISP can
always have REALPART
and IMAGPART
of any type) because it allows
the most precise type inference.
Variable CUSTOM:*DEFAULTFLOATFORMAT*
. When rational numbers are to be converted to floats (due to
FLOAT
, COERCE
, SQRT
or a transcendental function), the result
type is given by the variable CUSTOM:*DEFAULTFLOATFORMAT*
.
See also *READDEFAULTFLOATFORMAT*
.
Macro EXT:WITHOUTFLOATINGPOINTUNDERFLOW
. The macro (
executes the
EXT:WITHOUTFLOATINGPOINTUNDERFLOW
{form
}*)form
s, with errors of type FLOATINGPOINTUNDERFLOW
inhibited.
Floating point operations will silently return zero instead of
SIGNAL
ing an ERROR
of type FLOATINGPOINTUNDERFLOW
.
Condition FLOATINGPOINTINVALIDOPERATION
. This CONDITION
is never SIGNAL
ed by CLISP.
Condition FLOATINGPOINTINEXACT
. This CONDITION
is never SIGNAL
ed by CLISP.
Table 12.2. Fixnum limits
CPU type  32bit CPU  64bit CPU 

MOSTPOSITIVEFIXNUM  2^{24}1 = 16777215  2^{48}1 = 281474976710655 
MOSTNEGATIVEFIXNUM  2^{24} = 16777216  2^{48} = 281474976710656 
BIGNUM
s are limited in size. Their maximum size is
32*(2^{16}2)=2097088
bits.
The largest representable BIGNUM
is therefore
2^{2097088}1
.
Together with PI
, the other LONGFLOAT
constants
are recomputed whenever (
is EXT:LONGFLOATDIGITS
)SETF
ed.
They are not constant variables.
Since the exponent of a
LONGFLOAT
is a signed 32bits
integer, MOSTPOSITIVELONGFLOAT
is about
2^{231}
,
which is much larger that the largest
representable BIGNUM
, which is less than
2^{221}
.
This, obviously, means that ROUND
, TRUNCATE
, FLOOR
and CEILING
SIGNAL
s an ERROR
on large LONGFLOAT
s.
Less obviously, this means that (
also fails.FORMAT
NIL
"~E
"
MOSTPOSITIVELONGFLOAT
)
When a mathematical function may return an exact (RATIONAL
) or
inexact (FLOAT
) result, it always returns the exact result.
There are four floating point types: SHORTFLOAT
,
SINGLEFLOAT
, DOUBLEFLOAT
and LONGFLOAT
:
type  sign  mantissa  exponent  comment 

SHORTFLOAT  1 bit  16+1 bits  8 bits  immediate 
SINGLEFLOAT  1 bit  23+1 bits  8 bits  IEEE 754 
DOUBLEFLOAT  1 bit  52+1 bits  11 bits  IEEE 754 
LONGFLOAT  1 bit  >=64 bits  32 bits  variable length 
The single and double float formats are those of the IEEE 754
“Standard for Binary FloatingPoint Arithmetic”,
except that CLISP does not support features like
±0
, ±inf
,
NaN
, gradual underflow, etc.
Common Lisp does not make use of these features, so, to reduce portability
problems, CLISP by design returns the same floating point results on
all platforms (CLISP has a floatingpoint emulation built in for
platforms that do not support IEEE 754). Note that
NaN
in your program, your program is broken, so you will spend time
determining where the NaN
came from.
It is better to SIGNAL
an ERROR
in this case.LONGFLOAT
s of
variable precision  it does not
need unnormalized floats.
This is why *FEATURES*
does not contain the
:IEEEFLOATINGPOINT
keyword.
Arbitrary Precision Floats. LONGFLOAT
s have variable mantissa length, which is a
multiple of 16 (or 32, depending on the word size of the processor).
The default length used when LONGFLOAT
s are READ
is given by the
place (
. It can be set by EXT:LONGFLOATDIGITS
)(
,
where SETF
(EXT:LONGFLOATDIGITS
) n
)n
is a positive INTEGER
. E.g., (
sets the default precision of SETF
(EXT:LONGFLOATDIGITS
)
3322)LONGFLOAT
s to about
1000 decimal digits.
The floating point contagion is controlled by the variable
CUSTOM:*FLOATINGPOINTCONTAGIONANSI*
. When it is nonNIL
, contagion is done as per the
[ANSI CL standard]: SHORTFLOAT
→ SINGLEFLOAT
→
DOUBLEFLOAT
→ LONGFLOAT
.
1.5
is actually 1.5±0.05
.
Consider adding 1.5
and 1.75
.
[ANSI CL standard] requires that (+
1.5 1.75)
return 3.25, while traditional CLISP
would return 3.3.
The implied random variables are: 3.25±0.005
and 3.3±0.05
.
Note that the traditional CLISP way does
lie about the mean: the mean is 3.25
and
nothing else, while the standard way
could be lying about the deviation
(accuracy): if the implied accuracy of 1.5
(i.e., 0.05)
is its actual accuracy, then the accuracy of the result cannot be
smaller that that. Therefore, since Common Lisp has no way of knowing the
actual accuracy, [ANSI CL standard] (and all the other standard engineering
programming languages, like C, Fortran
etc) decided that keeping the accuracy correct is the business of the
programmer, while the language should preserve what it can  the precision.
E(x^{2}) 
E(x)^{2}
can be negative!)
The user should not mix floats of different precision (that's what
CUSTOM:*WARNONFLOATINGPOINTCONTAGION*
is for), but one should not be penalized for this too
harshly.When CUSTOM:*FLOATINGPOINTCONTAGIONANSI*
is NIL
, the traditional CLISP method is used,
namely the result of an arithmetic operation whose arguments are of
different float types is rounded to the float format of the shortest
(least precise) of the arguments: RATIONAL
→
LONGFLOAT
→ DOUBLEFLOAT
→ SINGLEFLOAT
→ SHORTFLOAT
(in contrast to
[sec_12144]!)
{1.0 ± 1e8} + {1.0 ± 1e16} = {2.0 ±
1e8}
. So, if we add 1.0s0
and
1.0d0
, we should get 2.0s0
.
(
(+
1.7 PI
) PI
)
should not return 1.700000726342836417234L0,
it should return 1.7f0 (or
1.700001f0 if there were rounding errors).
SHORTFLOAT
s,
a LONGFLOAT
(like PI
) happens to be used, the long precision
should not propagate throughout all the intermediate values.
Otherwise, the long result would look precise, but its accuracy is
only that of a SHORTFLOAT
; furthermore much computation time
would be lost by calculating with LONGFLOAT
s when only
SHORTFLOAT
s would be needed.If the variable CUSTOM:*WARNONFLOATINGPOINTCONTAGION*
is nonNIL
, a WARNING
is emitted for
every coercion involving different floatingpoint types.
As explained above, float precision contagion is not a good idea.
You can avoid the contagion by doing all your computations with the
same floatingpoint type (and using FLOAT
to convert all constants,
e.g., PI
, to your preferred type).
This variable helps you eliminate all occurrences of float
precision contagion: set it to T
to have CLISP SIGNAL
a
WARNING
on float precision contagion; set it to ERROR
to have
CLISP SIGNAL
an ERROR
on float precision contagion, so that you
can look at the stack backtrace.
The contagion between floating point and rational numbers is controlled
by the variable CUSTOM:*FLOATINGPOINTRATIONALCONTAGIONANSI*
. When it is nonNIL
, contagion is done as per
the [ANSI CL standard]: RATIONAL
→ FLOAT
.
When CUSTOM:*FLOATINGPOINTRATIONALCONTAGIONANSI*
is NIL
, the traditional CLISP method is used,
namely if the result is mathematically an exact rational number, this
rational number is returned (in contrast to
[sec_12141]!)
CUSTOM:*FLOATINGPOINTRATIONALCONTAGIONANSI*
has an effect only in those few cases when the mathematical
result is exact although one of the arguments is a floatingpoint number,
such as (
, *
0 1.618)(
,
/
0 1.618)(
, ATAN
0 1.0)(
,
EXPT
2.0 0)(
.PHASE
2.718)
If the variable CUSTOM:*WARNONFLOATINGPOINTRATIONALCONTAGION*
is nonNIL
, a WARNING
is emitted for
every avoidable coercion from a rational number to a floatingpoint number.
You can avoid such coercions by calling FLOAT
to convert the particular
rational numbers to your preferred floatingpoint type.
This variable helps you eliminate all occurrences of avoidable
coercions to a floatingpoint number when a rational number result
would be possible: set it to T
to have CLISP SIGNAL
a WARNING
in such situations; set it to ERROR
to have CLISP SIGNAL
an
ERROR
in such situations, so that you can look at the stack
backtrace.
CUSTOM:*PHASEANSI*
A similar variable, CUSTOM:*PHASEANSI*
, controls the return
value of PHASE
when the argument is an exact nonnegative REAL
.
Namely, if CUSTOM:*PHASEANSI*
is nonNIL
, it returns a floatingpoint zero;
if CUSTOM:*PHASEANSI*
is NIL
, it returns an exact zero. Example:
(
PHASE
2/3)
Complex numbers can have a real part and an imaginary part of
different types. For example, (
evaluates to
the number SQRT
9.0)
,
which has a real part of exactly #C
(0 3.0)0
,
not only 0.0
(which would mean “approximately 0”).
The type specifier for this is (
, and COMPLEX
INTEGER
SINGLEFLOAT
)(
in general.COMPLEX
typeofrealpart
typeofimaginarypart
)
The type specifier (
is equivalent to COMPLEX
type
)(
.COMPLEX
type
type
)
Complex numbers can have a real part and an imaginary part of
different types. If the imaginary part is EQL
to 0
,
the number is automatically converted to a real number.
This has the advantage that
(
 instead of
evaluating to LET
((x (SQRT
9.0))) (* x x))
,
with #C
(9.0 0.0)x
=

evaluates to #C
(0.0 3.0)
=
#C
(9.0 0)9.0
,
with x
=
.#C
(0 3.0)
To ease reproducibility, the variable *RANDOMSTATE*
is
initialized to the same value on each invocation, so that
$
clisp norcx
'(RANDOM
1s0)'
will always print the same number.
If you want a new random state on each invocation, you can arrange for that by using init function:
$
clisp norcx
'(EXT:SAVEINITMEM
"foo" :initfunction (LAMBDA
() (SETQ
*RANDOMSTATE*
(MAKERANDOMSTATE
T
))))'$
clisp norcM
foo.memx
'(RANDOM
1s0)'
or by placing (
into your RC file.SETQ
*RANDOMSTATE*
(MAKERANDOMSTATE
T
))
These notes document CLISP version 2.49  Last modified: 20100707 