Help us shape the future of Go! Take the 2026 Go Developer Survey

dd

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: BSD-3-Clause Imports: 1 Imported by: 0

Documentation

Overview

Package dd is a minimal double-double ("float128-lite") arithmetic used where a special function must carry more than 53 bits through an intermediate step: the argument of an exponential, a long product, a cancellation. A value is Hi + Lo with |Lo| <= ulp(Hi)/2.

The error-free transformations are the classical ones: TwoSum (Knuth, TAOCP vol. 2, 4.2.2), Fast2Sum (Dekker 1971) and TwoProd through a fused multiply-add (Ogita, Rump and Oishi, "Accurate sum and dot product", SIAM J. Sci. Comput. 26(6), 2005). Algorithms for the compound operations follow Joldes, Muller and Popescu, "Tight and rigorous error bounds for basic building blocks of double-word arithmetic", ACM TOMS 44(2), 2017 (DWPlusDW: Algorithm 6, DWTimesDW: Algorithm 12, DWDivDW: Algorithm 18).

This package is a copy of go-numerics/special's internal/dd (BSD-3-Clause), which an internal package cannot share across modules.

Index

Constants

View Source
const (
	Ln2Hi = 6.93147180559945286227e-01
	Ln2Lo = 2.31904681384629955842e-17
)

ln2 split as a double-double: Ln2Hi + Ln2Lo = ln 2 to 106 bits.

Variables

This section is empty.

Functions

func Exp

func Exp(a DD) float64

Exp returns exp(a.Hi + a.Lo) rounded to float64: the double-double mantissa from ExpMant is accurate to about 2^-76, so the result is correctly rounded except in cases closer to a rounding boundary than that.

func FastTwoSum

func FastTwoSum(a, b float64) (s, e float64)

FastTwoSum requires |a| >= |b| (or a == 0).

func TwoProd

func TwoProd(a, b float64) (p, e float64)

TwoProd returns p, e with p = fl(a*b) and p + e = a*b exactly (barring underflow).

The explicit float64 conversion is load-bearing: the Go specification allows a*b to be fused with a later addition (an FMA on arm64, ppc64le, s390x, riscv64, loong64), which would break every error-free transformation built on p. A conversion forces the rounding.

func TwoSum

func TwoSum(a, b float64) (s, e float64)

TwoSum returns s, e with s = fl(a+b) and s + e = a + b exactly.

Types

type DD

type DD struct{ Hi, Lo float64 }

DD is an unevaluated sum Hi + Lo.

func Add

func Add(a, b DD) DD

Add returns a + b (DWPlusDW, relative error <= 3u^2).

It is written out (rather than through TwoSum/FastTwoSum) to stay within the inliner's budget: it is the most frequent operation in the package.

func AddF

func AddF(a DD, b float64) DD

AddF returns a + b for a float64 b (DWPlusFP, relative error <= 2u^2).

func Div

func Div(a, b DD) DD

Div returns a / b (DWDivDW, relative error <= 15u^2 + 56u^3).

func DivF

func DivF(a DD, b float64) DD

DivF returns a / b for float64 b.

func ExpMant

func ExpMant(a DD) (m DD, k int)

ExpMant returns m, k with exp(a) = m * 2^k, m in about [0.99, 2.02] as a double-double accurate to about 2^-76 relative, so that a caller can multiply further factors in before the single final rounding. k is not limited to the float64 exponent range: a scaled result may be combined with others before math.Ldexp decides overflow or underflow. For |a.Hi| > 1e7 it returns m = +Inf or m = 0 with k = 0 (NaN for NaN).

Method (Tang, "Table-driven implementation of the exponential function in IEEE floating-point arithmetic", ACM TOMS 15(2), 1989, carried to double-double): a = (64k + j) ln2/64 + r, |r| <= ln2/128, the reduction exact (ln2/64 split in three parts, the first with 32 significant bits so that n times it is exact for |n| < 2^21, the second through TwoProd); exp(r) = 1 + r + r²/2 + r³ P(r) with 1 + r + r²/2 in double-double and P (to r^9/9!, truncation below 2^-86) in float64; 2^(j/64) from a 300-bit mpmath table (zz_exptable.go).

func F

func F(x float64) DD

F returns x as a DD.

func Ldexp

func Ldexp(a DD, k int) DD

Ldexp returns a * 2^k for a double-double (both parts scaled).

func Log

func Log(x float64) DD

Log returns log(x) for finite x > 0 as a double-double accurate to about 2^-72 relative (measured 2^-72.9; the float64 tail limits it).

Method (table-driven, after Tang, "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic", ACM TOMS 16(4), 1990): x = 2^k m with m in [1/sqrt2, sqrt2); c = j/128 is the grid point nearest m, and log m = log c + 2 atanh(s), s = (m-c)/(m+c). m-c is exact (Sterbenz), s is formed in double-double, |s| < 1/360, and 2 atanh(s) = 2s + s³ (2/3 + 2s²/5 + 2s⁴/7) with the second part (below 2^-16 of the first) in float64. log c comes from a 300-bit mpmath table (zz_logtable.go); k ln2 is added exactly.

Log(0) = -Inf, Log(+Inf) = +Inf, NaN for x < 0 or NaN (as math.Log).

func LogAccurate

func LogAccurate(x float64) DD

LogAccurate is Log carried further, to about 2^-104 relative: the atanh series keeps its terms through s⁴/5 in double-double and the quotient s comes from a full double-double division. It costs about five times Log and is for the few places where the result is a difference of logarithms that cancel to below 2^-30 of their size (Digamma near its zeros).

func Mul

func Mul(a, b DD) DD

Mul returns a * b (DWTimesDW with FMA, relative error <= 5u^2).

func MulF

func MulF(a DD, b float64) DD

MulF returns a * b for a float64 b (DWTimesFP, relative error <= 2u^2).

func MulFF

func MulFF(a, b float64) DD

MulFF returns the exact product a*b of two float64.

func Neg

func Neg(a DD) DD

Neg returns -a.

func Sqrt

func Sqrt(a DD) DD

Sqrt returns sqrt(a) (one Newton step from the float64 root).

func Sub

func Sub(a, b DD) DD

Sub returns a - b.

func (DD) Float

func (a DD) Float() float64

Float rounds to the nearest float64.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL