Oct
A Lisp Implementation of QuadDouble Float
Introduction
Oct is a portable Lisp implementation of quaddouble arithmetic. This gives about 65 digits of precision. Quaddouble arithmetic uses four doublefloat numbers to represent an extended precision number.
The implementation is modeled on the quaddouble package by Yozo Hida. This package is in C++, but we have translated parts of it and extended it to use Lisp. The intent is to provide all of the CL arithmetic functions with a quaddouble implementation.
Further information will be provided at a later date. This is currently a work in progress, but the current code has the basic functionality implemented and includes all of the special functions specified by CL. There are, undoubtedly, many bugs.
Supported Lisps
This package has been tested with CMUCL, SBCL, Clisp, and Allegro. All tests pass. Note that development is primarily done using CMUCL.
What's New
20181120
 Copied the original html pages to this wiki. Some links point to the old trac and stuff, but for the most part, the pages are correct.
20110304
 Oct now has a wiki and ticket system. You can browse the sources there (or using gitweb).
20110209
 For Lisp's that support signed zeros for floating point (like cmucl and sbcl), Oct now correctly handles signed quaddouble zeroes.
 The CVS repository has been moved to Git. The CVS repository is still available but will not be updated. Use Git to obtain the latest versions. (See Oct gitweb for more links.)
20071128
 Oct now passes all of the tests on Allegro/x86. The main change was not to compile with safety 0. This messes up Allegro's tracking of the precision.
 To help implementations (like Allegro or Clisp) that use arrays for storing
%quaddouble
numbers, many functions now support an optional third arg which is where the result should be written. This is like how bitand works. This should work correctly with both an array or (complex doubledoublefloat) implementation, but perhaps some care is needed to make sure it works for both.  CMUCL can use either an
array
or a(complex doubledoublefloat)
to store a%quaddouble
. However, simple timing measurements indicate that arrays are slightly slower to much slower than using(complex doubledoublefloat)
.
20071026
 A Pade approximation for exp has been added. This is currently not used, but tests show that it is 25% faster than the current method, but it loses about 3 bits of precision. This was contributed by Richard Fateman.
20071015
 The
OCT
package has been renamed. The package is nowNET.COMMONLISP.OCT
, with a nickname ofOCT
. 
QD
is no longer a nickname forOCT

QUADDOUBLEINTERNAL
has been renamed toOCTINTERNAL
, with a nickname ofOCTI
. The old nicknameQDI
has been removed  Oct has a more accurate argument reduction for the trig functions. This allows Oct to compute
cos(2^120)
correctly (which is about 0.925879).
20071010
 Oct now has print/read consistency, thanks to Richard Fateman, who provided a very nice method to convert bignums to quaddouble.
Building Oct
 Obtain a copy of Oct. Currently that means from the git repository http://commonlisp.net/r/projects/oct/oct.git, but also see the Oct gitweb for more links. The CVS repository is still available, but it is no longer used.
 Get a copy of MK:DEFSYS from clocc, if you don't already have a copy. Or you can also use ASDF. Note that this might be outofdate compared to the mk:defsys version.

(mk:oos "oct" :compile)
will compile up everything. Or use(asdf:oos 'asdf:loadop :oct)

(mk:oos "octtest" :compile)
will compile up some simple tests.(qdi::alltests)
will run a series of tests. The accuracy of the results should be on the order of about 200 bits or more. There are a few cases where accuracy is much less than this, but that is due to the algorithm. If you have a copy of RT, you should run(rt:dotests)
to run the tests. All tests should pass.
Using Oct
Everything in Oct resides in the NET.COMMONLISP.OCT
package, with a nickname of OCT
. The basic arithmetic operations of CL are shadowed in this package so you can use natural Lisp expressions to operate on quaddoubles. Special functions are included.
There are two types added:

QDREAL
A quaddouble type. This has about 65 digits of precision, or about 212 bits.

QDCOMPLEX
A complex type consisting of two
QDREAL
values. The reader is also modified to make it easier to enter quaddouble values.#q
is used to enter bothQDREAL
andQDCOMPLEX
types. For example#q1.25q5
is theQDREAL
with the value 125000. The exponent marker isq
. To enter aQDCOMPLEX
value, use#q(r i)
wherer
andi
are the real and imaginary parts. The parts will be coerced toQDREAL
type if necessary.
Examples
Here are a few examples:
QD> (/ (sqrt #q3) 2)
#q0.866025403784438646763723170752936183471402626905190314027903489696q0
QD> (sin (/ +pi+ 3))
#q0.86602540378443864676372317075293618347140262690519031402790348972q0
QD> (sqrt #q1)
#q(#q0.0q0 #q1.0q0)
QD> (coerce 7 'qdcomplex)
#q(#q7.0q0 #q0.0q0)
QD> (integerdecodefloat +pi+)
165424160919322423196824703508232170249081435635340508251270944637
215
1
QD> +pi+
#q3.1415926535897932384626433832795028841971693993751058209749445923q0
QD> (* 4 (atan #q1))
#q3.1415926535897932384626433832795028841971693993751058209749445923q0
Note that +pi+
is the QDREAL
value for pi.
Performance
Here are some simple benchmarks on the performance of this quaddouble implementation. These benchmarks were run using CMUCL on a 1.42 GHz PPC. The columns are times relative to a doublefloat. The %quaddouble
represents the time using the internal implementaiton, without the overhead of CLOS. The QDREAL column shows the effect of CLOS dispatch.
Operation  %quaddouble  QDREAL  Notes 

Addition  36  73  
Multiplication  420  950  
Division  900  1200  
Square root  125  133  There is no FP sqrt instruction on a PPC 
Here are some timing results using CMUCL on a 1.5 GHz UltraSparc IIIi
Operation  %quaddouble  QDREAL  Notes 

Addition  120  240  
Multiplication  390  660  
Division  1100  1450  
Square root  13400  13600  UltraSparc has a FP sqrt instruction 
Here are some timing results using CMUCL with SSE2 support on a 3.06 GHz Core i3
Operation  %quaddouble  QDREAL  Notes 

Addition  288  390  
Multiplication  536  673  
Division  2528  2785  
Square root  3572  3739 
Hida's QD package has a few timing tests. The lisp equivalent was written and here are the timing results. Note that the Lisp equivalent tried to be exactly the same as the QD reference, but no guarantees on that.
Test  QD  Oct  Relative speed Oct/QD 

add  0.236  1.16  4.91 
mul  0.749  1.54  2.06 
div  3.00  3.11  1.03 
sqrt  10.57  12.2  1.15 
sin  57.33  64.5  1.12 
log  194  119  0.613 
The second and third columns are microsec per operation. The last column is the relative time of Oct vs QD. All of these were run on a 1.5 GHz Ultrasparc III. Sun Studio 11 was used to compile the C code. CMUCL 200710 was used for the Lisp code.
It's surprising that Oct does as well as it does. To be fair, the times for Oct include the cost of CLOS dispatch since QD uses templates and classes in the tests. Except for add and mul, QD and Oct are within a few percent. The sin test is a bit slower in Oct. I don't know why, but the test did include the accurate argument reduction. The log test is quite a bit faster for Oct. This is probably due to using a different algorithm. QD uses a Newton iteration to compute the log. Oct uses Halley's iteration.
Mailing Lists
 Octdevel for developers
 Octcvs CVS log feed.
 Octannounce for announcements.
Download
Currently, there are no official releases. However, you may find occasional snapshots of the sources here.
Known Issues

There is a known issue with Oct on x86 machines. Some Lisp's set up the FPU to use a rounding mode of 64bits. That is, it sets the rounding assuming all arithmetic is using double extended floatingpoint registers (80bits). However, since Oct is using double precision floats, this will cause bad things to happen. Rounding will be done incorrectly so incorrect result may be returned. The rounding mode must be set to 53 bits (double precision floats). It is known that CMUCL and SBCL have the desired rounding by default. Allegro works fine on ppc and x86 now.

When the Oct system is loaded, it always adds the #q reader macro. This may interfere with other systems that want to use #q.
Git
You can browse our git repository or clone it if desired.