Double-word and multi-double arithmetic
- Cost
- double operations for a product of -term expansions, for a long division with tapered remainders; about fused multiply-adds dominate.
A floating-point expansion represents a real number as an unevaluated sum of machine doubles, each much smaller than the previous one. With (double-word or double-double arithmetic) this gives about 106 bits of precision, with (quad-double) about 212 bits, using only hardware floating-point operations. The idea goes back to Møller [Mol1965] and Dekker [Dek1971]; general expansions are due to Priest [Pri1991] and Shewchuk [She1997], the classical quad-double library is that of Hida, Li and Bailey [HLB2001], and tight error bounds for double-word operations were proved by Joldes, Muller and Popescu [JMP2017]. A comprehensive treatment is in [MBD2018, chapters 4 and 14].
FLINT implements expansions with in the dfloat module. Its kernels are designed for ball arithmetic: every operation computes the exact terms of the result with error-free transformations, keeps of them, and returns the magnitude of everything it dropped, which becomes the radius of a ball.
Throughout, doubles are IEEE 754 binary64 numbers with round-to-nearest (), is the unit roundoff, and is the weight of the last bit of the double . For any real such that is a normal double, with .
Error-free transformations#
The sum and the product of two doubles are not doubles in general, but their rounding errors are, and can be computed exactly.
Lemma 1 (Sterbenz). If and are doubles with , then is a double, so it is computed exactly [Ste1974].
Theorem 2. If does not overflow, TwoSum returns and with exactly, using six operations and no branch. FastTwoSum gives the same result in three operations if the exponent of is at least that of (in particular if ) or . In both cases .
Proof. For FastTwoSum with , we first show that is computed exactly. If and have the same sign, then with of the sign of , so this follows from Lemma 1. If they have opposite signs and , then is exact by the same lemma, so and . If they have opposite signs and , then (rounding is monotone and is a double), and again Lemma 1 applies. Now is the rounding error of a nearest-rounded sum of two doubles, which is itself a double (its magnitude is at most and it is a multiple of the ulp of the operand with the smaller exponent), so it is also computed exactly. TwoSum reconstructs the same quantities without knowing which operand is larger; see [MBD2018, §4.3] for the complete proof. Sums are exact in the subnormal range, so no underflow condition is needed.
TwoProd: , computed with one fused multiply-add.
Theorem 3. If does not overflow and or , TwoProd returns exactly.
Proof. The exact product has at most 106 significant bits and is a multiple of . Its rounding error is at most in magnitude and is a multiple of the same quantity, so it fits in 53 bits; the condition on ensures that this multiple is not below the subnormal range. An FMA rounds the exact once, which is exact for a double.
Without an FMA, TwoProd can be computed with Dekker's product, which splits each operand into two 26-bit halves (Veltkamp splitting) and costs 17 operations [Dek1971]; _d_vec_dot_thrice uses this form. In C, all of these transformations break if the compiler contracts a separate multiplication and addition into an FMA, or evaluates intermediate results in extended precision (x87). The dfloat module is therefore compiled with -ffp-contract=off and with SSE2 arithmetic, and dfloat_is_supported reports whether these requirements hold.
Expansions and renormalisation#
An expansion is nonoverlapping if for all with , and canonical if in addition zeros occur only at the end. A canonical expansion is obtained from a real number by rounding term by term, , , and so on; it is unique up to ties.
Arithmetic produces a list of terms, ordered by decreasing magnitude but overlapping, which must be converted to nonoverlapping components.
Input: doubles , roughly decreasing in magnitude.
Output: with the same exact sum.
- For : .
Since each step is error-free, the sum is preserved exactly, and after the pass each is the rounding error of a sum whose rounded value is , so . The result is not necessarily canonical: a cancellation in the sum that produced can leave larger than . FLINT calls this weak normalisation. It is all that the error analysis needs, and it is what the dfloat kernels produce; a second, top-down pass of TwoSums (VecSumErr) followed by a check makes the expansion canonical (dN_canonicalise, or every result in a context with DFLOAT_STRONG). For weak normalisation is already canonical. The general renormalisation _dfloat_renorm of an arbitrary number of terms adds a branchy pass (VecSumErrBranch of [JMPT2016]) that removes zero components before nonzero ones.
Addition and multiplication#
The kernels organise the exact terms of a result by order: a term of order has magnitude about times that of the head.
- For : .
- . For : accumulate with TwoSums, keeping their residuals as terms of order .
- Renormalise with Algorithm 3.
- The dropped part is plus the residuals of order .
- For : .
- . For : accumulate with TwoSums .
- Renormalise with Algorithm 3.
- The dropped part consists of the residuals of order , the low parts with , and the products with , which are not computed exactly and are bounded by .
The products need TwoProds, each a multiplication and an FMA. Squaring uses the symmetry (doubling is exact). The product with a single double needs TwoProds.
Theorem 4. Let be the renormalised result and the sum of the absolute values of the dropped terms of Algorithm 4 or Algorithm 5. If no product of nonzero components has magnitude below and nothing overflows, then , where is the exact operation.
Proof. Every step is an error-free transformation by Theorem 2 and Theorem 3, so equals the sum of the kept and the dropped terms exactly, except for the products of order , whose exact values satisfy ; the factor and the rounding errors in forming itself are absorbed by the slack factor of Lemma 5.
For the plain formats, is not computed, and the error is of the order of times the magnitude of the result, with small constants [HLB2001; JMP2017]. In the ball formats, is added to the radius. When the inputs are not exact, tracking the last-order residuals exactly costs as much as the product itself for , so the ball products then accumulate the last order with plain additions and bound their rounding errors by times the accumulated magnitudes; this loses only a constant factor in a radius that is nonzero anyway, and keeps exact products of exact balls exact.
Radius arithmetic#
The radius of a ball is a double computed in round-to-nearest arithmetic from nonnegative quantities, and is made an upper bound by a single multiplication at the end.
Lemma 5. Let be a nonnegative real number obtained from nonnegative doubles by at most additions and multiplications, and the result of performing the same operations in round-to-nearest arithmetic, where no operation has an inexact subnormal result. Then .
Proof. Each operation on nonnegative numbers satisfies , so by induction . On the other hand , which is larger. Sums of doubles in the subnormal range are exact, and products and quotients that could underflow are bumped up by (_dfloat_rad_mul), which preserves the inequality.
The ball operations then use the standard propagation bounds. For the product, for and , with bounded by the sum of the absolute values of the components. For the quotient:
Proposition 6. Let be any number and . For all and with and ,
Proof. , with and .
The residual for the computed quotient is enclosed with the tracked kernels, so that an exact quotient of exact balls gets radius zero. For the reciprocal square root, with for the computed , the series has positive coefficients and for , so that .
Division and square root#
Input: expansions , with .
Output: .
- , .
For :
- (for the last digit, ).
- If : , (exact), and , kept with components.
- Renormalise .
The digit is within a relative of , so that is within a factor 2 of and is exact by Lemma 1: the cancellation of the heads loses no information, and the next remainder absorbs the error of the digit. After step the remainder is about and is only needed to absolute precision , so it is kept with fewer components (tapered precision); the remainder update is a three-term sum of expansions of the size of the new remainder. A Newton–Karp–Markstein division [KM1997] (a reciprocal at half precision, one product and a correction) turned out to be slower at every , because the steps of the long division are cheap products of a double with the divisor and the divisions are off the critical path.
The square root is the Newton iteration from , doubling the number of correct components per step. The residual is computed as with the head exact (TwoProd and Lemma 1), and the correction is a long division producing only the digits it needs. The reciprocal square root iterates in the same way.
Use in FLINT#
dfloat: the plain formatsdNuse Algorithm 4, Algorithm 5, Algorithm 6 and the Newton iterations; the ball formatsdNbadd the dropped terms of Theorem 4 to the radius with Lemma 5, and use Proposition 6 fordNb_divand the bound above fordNb_rsqrt. The kernels are written once (src/dfloat/kernels.inc) and instantiated for doubles and for four-lane SIMD vectors, which the vector functions_dN_vec_mul,_dN_vec_dot, etc. use. The error-free transformations are exposed as the macrosDFLOAT_TWO_SUM,DFLOAT_FAST_TWO_SUMandDFLOAT_TWO_PROD.- The elementary functions of
dfloatare built on these kernels; see Elementary functions in double-word to quad-double precision. _dfloat_platt_smkcomputes the moments of Platt's multi-evaluation in plain double-double arithmetic with the algorithms DWTimesDW1 and AccurateDWPlusDW of [JMP2017], using their proven error bounds a priori._d_vec_dot_thriceind_vecis the compensated dot product of Ogita, Rump and Oishi [ORO2005], built on TwoSum and Dekker's product.
void d2b_mul(d2b_t res, d2b_srcptr x, d2b_srcptr y)void _d2_mul_tracked(double * res, double * err, const double * x, const double * y)void _dfloat_renorm(double * res, int n, double * err, double * t, int len)void d2_canonicalise(d2_t res, d2_srcptr x)Referenced from#
- Elementary functions in double-word to quad-double precision (algorithm)
- Floating-point arithmetic in FLINT (overview)
_d_vec_dot_thrice- dfloat.h (module)
d1_add,d2_add,d3_add,d4_add,d1_sub,d2_sub,d3_sub,d4_sub,d1_mul,d2_mul,d3_mul,d4_mul,d1_sqr,d2_sqr,d3_sqr,d4_sqr,d1_mul_d,d2_mul_d,d3_mul_d,d4_mul_d,d1_div,d2_div,d3_div,d4_div,d1_inv,d2_inv,d3_inv,d4_inv,d1_sqrt,d2_sqrt,d3_sqrt,d4_sqrt,d1_rsqrt,d2_rsqrt,d3_rsqrt,d4_rsqrt,d1_mul_2exp_si,d2_mul_2exp_si,d3_mul_2exp_si,d4_mul_2exp_siDFLOAT_TWO_SUM,DFLOAT_FAST_TWO_SUM,DFLOAT_TWO_PROD- Sieved power sums with dfloat balls
References#
- [Mol1965] O. Møller. Quasi double-precision in floating point addition. BIT 5 (1965), 37–50.
- [Dek1971] T. J. Dekker. A floating-point technique for extending the available precision. Numerische Mathematik 18 (1971), 224–242. https://doi.org/10.1007/BF01397083
- [Pri1991] D. M. Priest. Algorithms for arbitrary precision floating point arithmetic. Proceedings of the 10th IEEE Symposium on Computer Arithmetic (ARITH-10), 1991, 132–143.
- [She1997] J. R. Shewchuk. Adaptive precision floating-point arithmetic and fast robust geometric predicates. Discrete & Computational Geometry 18 (1997), 305–363. https://doi.org/10.1007/PL00009321
- [HLB2001] Y. Hida, X. S. Li and D. H. Bailey. Algorithms for quad-double precision floating point arithmetic. Proceedings of the 15th IEEE Symposium on Computer Arithmetic (ARITH-15), 2001, 155–162.
- [JMP2017] M. Joldes, J.-M. Muller and V. Popescu. Tight and rigorous error bounds for basic building blocks of double-word arithmetic. ACM Transactions on Mathematical Software 44:2 (2017), 15:1–15:27. https://doi.org/10.1145/3121432
- [MBD2018] J.-M. Muller, N. Brunie, F. de Dinechin, C.-P. Jeannerod, M. Joldes, V. Lefèvre, G. Melquiond, N. Revol and S. Torres, Handbook of Floating-Point Arithmetic, second edition, Birkhäuser (2018), https://doi.org/10.1007/978-3-319-76526-6
- [Ste1974] P. H. Sterbenz. Floating-Point Computation. Prentice-Hall, 1974.
- [Knu1997] Knuth, D. E. The Art of Computer Programming, volume 2: Seminumerical algorithms, 1997
- [JMPT2016] M. Joldes, O. Marty, J.-M. Muller and V. Popescu. Arithmetic algorithms for extended precision using floating-point expansions. IEEE Transactions on Computers 65:4 (2016), 1197–1210. https://doi.org/10.1109/TC.2015.2441714
- [KM1997] A. H. Karp and P. Markstein, "High-precision division and square root", ACM Transactions on Mathematical Software 23:4 (1997), 561–589
- [ORO2005] T. Ogita, S. M. Rump and S. Oishi. Accurate sum and dot product. SIAM Journal on Scientific Computing 26:6 (2005), 1955–1988. https://doi.org/10.1137/030601818
The FLINT team, “Double-word and multi-double arithmetic,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/floating-point/double-word.html (generated 2026-11-02).
@misc{flint-doc-algorithms-floating-point-double-word,
author = {{The FLINT team}},
title = {{Double-word and multi-double arithmetic}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/floating-point/double-word.html},
note = {Generated 2026-11-02}
}