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 SIGNALs an ERROR when the quotient is not
integer. (This is more efficient than /.)
Function EXT:XGCD. (
returns the values EXT:XGCD x1 ... xn)l, k1, ..., kn, where l is the
greatest common divisor of the integers x1, ..., xn, and
k1, ..., kn are the integer coefficients such that
l= (GCDx1...xn) = (+ (*k1x1) ... (*knxn))
Function EXT:MOD-EXPT. (
is equivalent to EXT:MOD-EXPT k l m)(
except it is more efficient for very large arguments.MOD (EXPT k l) m)
DECODE-FLOAT FLOAT-RADIX always returns 2.
( coerces
FLOAT-DIGITS number digits)number (a REAL) to a floating point number with at least
digits mantissa digits. The following always evaluates to T:
(>=(FLOAT-DIGITS(FLOAT-DIGITSnumberdigits))digits)
Table 12.1. Boolean operations
| constant | value |
|---|---|
BOOLE-CLR | 0 |
BOOLE-SET | 15 |
BOOLE-1 | 10 |
BOOLE-2 | 12 |
BOOLE-C1 | 5 |
BOOLE-C2 | 3 |
BOOLE-AND | 8 |
BOOLE-IOR | 14 |
BOOLE-XOR | 6 |
BOOLE-EQV | 9 |
BOOLE-NAND | 7 |
BOOLE-NOR | 1 |
BOOLE-ANDC1 | 4 |
BOOLE-ANDC2 | 2 |
BOOLE-ORC1 | 13 |
BOOLE-ORC2 | 11 |
Byte specifiers are objects of built-in type BYTE,
not INTEGERs.
Function EXPT. (
is not very precise if EXPT base exponent)exponent has a large
absolute value.
Function LOG. ( LOG number base)SIGNALs an ERROR if
.base = 1
Constant PI. The value of PI is a LONG-FLOAT with the precision given
by (. When this precision is changed, the value of EXT:LONG-FLOAT-DIGITS)PI is
automatically recomputed. Therefore PI is not a constant variable.
Function UPGRADED-COMPLEX-PART-TYPE. When the argument is not a recognizable subtype or REAL,
UPGRADED-COMPLEX-PART-TYPE SIGNALs 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:*DEFAULT-FLOAT-FORMAT*. 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:*DEFAULT-FLOAT-FORMAT*.
See also *READ-DEFAULT-FLOAT-FORMAT*.
Macro EXT:WITHOUT-FLOATING-POINT-UNDERFLOW. The macro ( executes the
EXT:WITHOUT-FLOATING-POINT-UNDERFLOW {form}*)forms, with errors of type FLOATING-POINT-UNDERFLOW inhibited.
Floating point operations will silently return zero instead of
SIGNALing an ERROR of type FLOATING-POINT-UNDERFLOW.
Condition FLOATING-POINT-INVALID-OPERATION. This CONDITION is never SIGNALed by CLISP.
Condition FLOATING-POINT-INEXACT. This CONDITION is never SIGNALed by CLISP.
Table 12.2. Fixnum limits
| CPU type | 32-bit CPU | 64-bit CPU |
|---|---|---|
MOST-POSITIVE-FIXNUM | 224-1 = 16777215 | 248-1 =わ 281474976710655 |
MOST-NEGATIVE-FIXNUM | -224 = -16777216 | -248 = -281474976710656 |
BIGNUMs are limited in size. Their maximum size is
32*(216-2)=2097088 bits.
The largest representable BIGNUM is therefore
22097088-1.
Together with PI, the other LONG-FLOAT constants
are recomputed whenever ( is EXT:LONG-FLOAT-DIGITS)SETFed.
They are not constant variables.
Since the exponent of a
LONG-FLOAT is a signed 32-bits
integer, MOST-POSITIVE-LONG-FLOAT is about
2231,
which is much larger that the largest
representable BIGNUM, which is less than
2221.
This, obviously, means that ROUND, TRUNCATE, FLOOR and CEILING
SIGNALs an ERROR on large LONG-FLOATs.
Less obviously, this means that ( also fails.FORMAT NIL "~E"
MOST-POSITIVE-LONG-FLOAT)
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: SHORT-FLOAT,
SINGLE-FLOAT, DOUBLE-FLOAT and LONG-FLOAT:
| type | sign | mantissa | exponent | comment |
|---|---|---|---|---|
SHORT-FLOAT | 1 bit | 16+1 bits | 8 bits | immediate |
SINGLE-FLOAT | 1 bit | 23+1 bits | 8 bits | IEEE 754 |
DOUBLE-FLOAT | 1 bit | 52+1 bits | 11 bits | IEEE 754 |
LONG-FLOAT | 1 bit | >=64 bits | 32 bits | variable length |
The single and double float formats are those of the IEEE 754
"Standard for Binary Floating-Point 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 floating-point 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.LONG-FLOATs of
variable precision - it does not
need unnormalized floats.
This is why *FEATURES* does not contain the
:IEEE-FLOATING-POINT keyword.
Arbitrary Precision Floats. LONG-FLOATs 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 LONG-FLOATs are READ is given by the
place (. It can be set by EXT:LONG-FLOAT-DIGITS)(,
where SETF (EXT:LONG-FLOAT-DIGITS) n)n is a positive INTEGER. E.g., ( sets the default precision of SETF (EXT:LONG-FLOAT-DIGITS)
3322)LONG-FLOATs to about
1000 decimal digits.
The floating point contagion is controlled by the variable
CUSTOM:*FLOATING-POINT-CONTAGION-ANSI*. When it is non-NIL, contagion is done as per the
[ANSI CL standard ]: SHORT-FLOAT → SINGLE-FLOAT →
DOUBLE-FLOAT → LONG-FLOAT.
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(x2) -
E(x)2 can be negative!)
The user should not mix floats of different precision (that's what
CUSTOM:*WARN-ON-FLOATING-POINT-CONTAGION* is for), but one should not be penalized for this too
harshly.When CUSTOM:*FLOATING-POINT-CONTAGION-ANSI* 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 →
LONG-FLOAT → DOUBLE-FLOAT → SINGLE-FLOAT
→ SHORT-FLOAT (in contrast to
[sec_12-1-4-4]!)
{1.0 ± 1e-8} + {1.0 ± 1e-16} = {2.0 ±
1e-8}. 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).
SHORT-FLOATs,
a LONG-FLOAT (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 SHORT-FLOAT; furthermore much computation time
would be lost by calculating with LONG-FLOATs when only
SHORT-FLOATs would be needed.If the variable CUSTOM:*WARN-ON-FLOATING-POINT-CONTAGION* is non-NIL, a WARNING is emitted for
every coercion involving different floating-point 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 floating-point 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:*FLOATING-POINT-RATIONAL-CONTAGION-ANSI*. When it is non-NIL, contagion is done as per
the [ANSI CL standard ]: RATIONAL → FLOAT.
When CUSTOM:*FLOATING-POINT-RATIONAL-CONTAGION-ANSI* 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_12-1-4-1]!)
CUSTOM:*FLOATING-POINT-RATIONAL-CONTAGION-ANSI* has an effect only in those few cases when the mathematical
result is exact although one of the arguments is a floating-point number,
such as (, * 0 1.618)(,
/ 0 1.618)(, ATAN 0 1.0)(,
EXPT 2.0 0)(.PHASE 2.718)
If the variable CUSTOM:*WARN-ON-FLOATING-POINT-RATIONAL-CONTAGION* is non-NIL, a WARNING is emitted for
every avoidable coercion from a rational number to a floating-point number.
You can avoid such coercions by calling FLOAT to convert the particular
rational numbers to your preferred floating-point type.
This variable helps you eliminate all occurrences of avoidable
coercions to a floating-point 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:*PHASE-ANSI* A similar variable, CUSTOM:*PHASE-ANSI*, controls the return
value of PHASE when the argument is an exact nonnegative REAL.
Namely, if CUSTOM:*PHASE-ANSI* is non-NIL, it returns a floating-point zero;
if CUSTOM:*PHASE-ANSI* 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 SINGLE-FLOAT)( in general.COMPLEX
type-of-real-part
type-of-imaginary-part)
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 *RANDOM-STATE* is
initialized to the same value on each invocation, so that
$clisp -norc-x'(RANDOM1s0)'
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 -norc-x'(EXT:SAVEINITMEM"foo" :init-function (LAMBDA() (SETQ*RANDOM-STATE*(MAKE-RANDOM-STATET))))'$clisp -norc-Mfoo.mem-x'(RANDOM1s0)'
or by placing ( into your RC file.SETQ *RANDOM-STATE*
(MAKE-RANDOM-STATE T))
| These notes document CLISP version 2.49 | Last modified: 2010年07月07日 |