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

When you got a 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.

When you got unnormalized floats in your program,
your results will have a greatly reduced accuracy anyway.
Since CLISP has the means to cope with this - LONG-FLOATs of
variable precision - it does not
need unnormalized floats.

This is why *FEATURES* does not contain the
:IEEE-FLOATING-POINT keyword.

See it pragmatically: save what you can and let
others worry about the rest.

Brief:

Common Lisp knows the number's precision,
not accuracy, so preserving the precision can be
accomplished reliably, while anything relating to the accuracy is
just a speculation - only the user (programmer) knows what it is in
each case.

Detailed:

A computer float is an approximation of a real number.
One can think of it as a random variable with the mean equal to
itself and standard deviation equal to half the last significant digit.
E.g., 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 is3.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.

Experience:

Rounding errors accumulate, and if a computation
is conducted with insufficient precision, an outright incorrect
result can be returned.
(E.g., 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.

Do not suggest high accuracy of a result by giving
it a precision that is greater than its accuracy.

Example:

(- (+ 1.7 PI) PI)
should not return 1.700000726342836417234L0,
it should return 1.7f0 (or
1.700001f0 if there were rounding errors).

Experience:

If in a computation using thousands of 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 CLISPSIGNAL a
WARNING on float precision contagion; set it to ERROR to have
CLISPSIGNAL an ERROR on float precision contagion, so that you
can look at the stack backtrace.

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 CLISPSIGNAL a WARNING
in such situations; set it to ERROR to have CLISPSIGNAL an
ERROR in such situations, so that you can look at the stack
backtrace.

Complex numbers can have a real part and an imaginary part of
different types. For example, (SQRT -9.0) evaluates to
the number #C(0 3.0),
which has a real part of exactly 0,
not only 0.0
(which would mean “approximately 0”).