DoubleDouble.java


DoubleDouble.java is a JavaTM API which uses the DoubleDouble technique to provide twice the precision of IEEE-754 floating point numbers. It implements a floating-point representation which maintains 106 bits (approximately 30 decimal digits) of precision.

The range of values which can be represented is the same as in IEEE-754. (i.e. ~10-323 to ~10308) The precision of the representable numbers is twice as great as IEEE-754 double precision (i.e. approximately 30 digits of precision versus 15 digits)

The implementation uses a representation containing two double-precision values. A number x is represented as a pair of doubles, x.hi and x.lo, such that the number represented by x is x.hi + x.lo, where

   |x.lo| <= 0.5*ulp(x.hi),  (*)
and ulp(y) means "unit in the last place of y".

Arithmetic operations are implemented using convenient properties of IEEE-754 floating-point arithmetic. The correctness of the arithmetic algorithms relies on operations being performed with standard IEEE-754 double precision and rounding. This is the standard floating point behaviour in Java. However, for performance reasons Java implementations are not constrained to use this standard. Some processors (notably the Intel Pentium architecure) perform floating point operations in extended precision (e.g. 80 bits for Intel FP). To ensure that DoubleDouble operations are computed using the correct arithmetic mode, the Java strictfp modifier is used.

Use Cases

DoubleDouble has been used for:
  • Computing more accurate points of intersection between line segments with endpoints in double precision
  • Verifying the results of other algorithms for line segment intersection
Many other uses are possible.

Examples

(The following examples are computed by sample applications provided with the software distribution)
  • Pi computed to 32 significant digits using Machin's arctangent formula: 3.1415926535897932384626433832794
  • e computed to 33 significant digits using the well-known Taylor series: 2.7182818284590452353602874713526

See Also

  • Bailey and others have developed a QuadDouble implementation, which uses the same approach as DoubleDouble but provides four times the precision of IEEE-754 floating-point.

  • Java provides the BigDecimal API, which also provides extended precison. Some reasons for using DoubleDouble rather than BigDecimal are:
    • DoubleDouble is floating-point, whereas BigDecimal is fixed-point. Floating-point is easier to use in situations where magnitudes can vary widely
    • DoubleDouble is several times faster than BigDecimal
    • DoubleDouble is simpler to use than BigDecimal, since it does not require extra parameters such as desired precision and rounding behaviour for division

Credits

This implementation uses algorithms originally designed variously by Knuth, Kahan, Dekker, and Linnainmaa. Douglas Priest developed the first C implementation of these techniques. Other more recent C++ implementation are due to Keith M. Briggs and David Bailey et al.

References

  1. Priest, D., Algorithms for Arbitrary Precision Floating Point Arithmetic, in P. Kornerup and D. Matula, Eds., Proc. 10th Symposium on Computer Arithmetic, IEEE Computer Society Press, Los Alamitos, Calif., 1991.
  2. Yozo Hida, Xiaoye S. Li and David H. Bailey, Quad-Double Arithmetic: Algorithms, Implementation, and Application, manuscript, Oct 2000; Lawrence Berkeley National Laboratory Report BNL-46996.
  3. David Bailey, High Precision Software Directory; http://crd.lbl.gov/~dhbailey/mpdist/

Software

The DoubleDouble source code can be downloaded from here.

JavaTM is a trademark of Sun Microsystems, Inc. in the United States and other countries.