There are a number of ways we can get information about the representation of floating-point types and arrays thereof.
(MAKE-ARRAY 1000 :ELEMENT-TYPE 'DOUBLE-FLOAT)and the like for other datatypes. Many Lisps print memory usage information, which can help in deducing the size of the floating-point type and whether or not it is boxed. This information isn't standard, though, and some Lisps (e.g. ECL 0.9i) don't. (For ECL, the lack of memory usage information may have something to do with the Boehm-Weiser GC.)
(MAKE-ARRAY 1000 :ELEMENT-TYPE 'DOUBLE-FLOAT)is interesting in itself. Some Lisps fill in 0.0d0, some (ACL 8.0 and LispWorks Personal 4.4) don't initialize the doubles, and Clisp (which boxes) fills in NIL for the elements.
(UPGRADED-ARRAY-ELEMENT-TYPE 'DOUBLE-FLOAT) -> 'DOUBLE-FLOATand still box the double-floats in the array.
FLOAT-RADIX(See e.g. CLtL2
FLOAT-DIGITS(number of digits (in radix
FLOAT-RADIX) used to represent a number, including any implicit digit(s))
xLAMCH(replace x with S, D, C or Z as appropriate for the datatype) can also be used to determine floating-point properties, though the methods used are computationally expensive. LAPACK only does the computations once and then caches the results. (Vendor distributions of LAPACK are welcome to replace the reference xLAMCH routines by coding in the values if they are known.)
*features*(though there's no particular reason to trust this ;) ).
|Constant||ACL 8.0 (PPC)||Clisp 2.32 (PPC)||ECL 0.9i (PPC)||LispWorks 4.4 (PPC)||OpenMCL 1.0 (PPC)||SBCL 0.9.15 (PPC)|
|Lisp impl.||long-float||double-float||single-float||short-float||boxed reals?||boxed complex?|
|Corman Lisp 3.0 (x86)||boxed (7)||boxed|
|OpenMCL 1.0 (PPC)||IEEE double||IEEE double||IEEE single||IEEE single||boxed? (3)||boxed (4)|
|SBCL 0.9.15 (PPC)||IEEE double||IEEE double||IEEE single||IEEE single||unboxed||unboxed|
|ECLS 0.9i (PPC)||IEEE double||IEEE double||IEEE double (?)||IEEE single||unboxed||boxed (2)|
|Clisp (>= 2.32, all platforms)||bigfloat (GMP)||IEEE double||IEEE single||(1)||boxed||boxed|
|ACL 8.0 (PPC)||IEEE double||IEEE double||IEEE single||IEEE single||unboxed||unboxed (5)|
|LispWorks 4.4 (PPC)||IEEE double||IEEE double||IEEE single||(6)||unboxed||unboxed|
(TIME (MAKE-ARRAY 1000 :ELEMENT-TYPE 'SHORT-FLOAT :INITIAL-ELEMENT 1.0s0))reports 7560 space usage (Clisp 2.39 PPC). The Clisp implementation notes say that Clisp doesn't support IEEE 754 features like +-0, +-inf, Nan and gradual underflow. The aim of this is to make Clisp more "portable" -- all floating-point operations in Clisp return the same results on all platforms, whether or not their hardware supports IEEE 754. Prof. Kahan has a good rant about this, relating to Matlab's truncation of 80-bit floating-point temporaries (a feature of the x87 floating-point architecture) to 64-bit in its effort to make results consistent on all platforms. He also has a tutorial on gradual underflow which explains why gradual overflow is the default in IEEE 754. (The Clisp developers justify their lack of subnormal number by asserting that if subnorms are present, the results aren't accurate anyway, so a higher precision should be used. To their credit,
LONG-FLOATin Clisp is an arbitrary-precision type whose precision can be set by the user.) As the x87 floating-point instructions in modern Intel chips are being neglected in favor of 64-bit SSE2 instructions, this discussion is becoming somewhat academic.
short-floatarrays map to C
double-floatarrays map to C
(TIME (MAKE-ARRAY 5000 :ELEMENT-TYPE 'DOUBLE-FLOAT))uses 40008 bytes of memory, and
(TIME (LIST 1.0D0 2.0D0 3.0D0 4.0D0 5.0D0))also claims to allocate 40 bytes of memory, which is impossible if these are really 8-byte floating-point values.
(MAKE-ARRAY 1000 :ELEMENT-TYPE '(COMPLEX DOUBLE-FLOAT))only claims to allocate 4008 bytes of memory, and TYPE-OF an element returns BIT, but if you specify the :INITIAL-ELEMENT keyword to MAKE-ARRAY with an appropriate complex number like
(COMPLEX 1.0d0 2.0d0),it seems to work OK and
(TYPE-OF (AREF X 1))does what it should, though TIME still reports 4,024 bytes of memory allocated. (This probably suggests boxed complex numbers.) We should watch out for this initialization issue.
(TIME (MAKE-ARRAY 1000 :ELEMENT-TYPE 'DOUBLE-FLOAT))allocates 4 conses and 8016 "other bytes," and interestingly enough, ACL leaves the elements uninitialized rather than setting them all to zero.
(TIME (MAKE-ARRAY 1000 :ELEMENT-TYPE 'SINGLE-FLOAT))allocates 4 conses and 4016 "other bytes," and also leaves the elements uninitialized.
(TIME (MAKE-ARRAY 1000 :ELEMENT-TYPE '(COMPLEX DOUBLE-FLOAT)))allocates 18 cons cells and 16,016 "other bytes," as expected for unboxed elements. The individual elements are garbage (uninitialized).