@@ -90,6 +90,12 @@ constants. The natural logarithm function is provided separately by `DDMath.Log`
|
||||
|
||||
## Mathematical functions
|
||||
|
||||
Root functions are implemented on `DoubleDouble` in `DoubleDouble.RootFunctions.cs`:
|
||||
`Sqrt`, `Cbrt`, `Hypot`, and `RootN` complete `IRootFunctions<DoubleDouble>`.
|
||||
The additional `InvSqrt` helper and three-argument `Hypot` overload live alongside
|
||||
them. `DDMath` exposes thin forwarding wrappers; the other mathematical kernels
|
||||
remain in `DDMath`.
|
||||
|
||||
The `DDMath` static class provides:
|
||||
|
||||
- `Abs(DoubleDouble)`: preserves both components, maps either signed zero to
|
||||
@@ -112,6 +118,34 @@ The `DDMath` static class provides:
|
||||
with FMA. Signed zeros map to correspondingly signed infinities; positive infinity
|
||||
maps to positive zero; negative nonzero inputs and NaN return canonical NaN.
|
||||
This is a dedicated algorithm, not a claim of measured speedup over `1.0 / Sqrt(x)`.
|
||||
- `Cbrt(DoubleDouble)`: real cube root using a scaled binary64 seed and compensated
|
||||
Newton corrections. Signed zeros and infinities are preserved; NaN is canonical.
|
||||
An exponent-tracked low-component correction avoids losing representable sparse
|
||||
residuals during scaling.
|
||||
- `Hypot(DoubleDouble, DoubleDouble)`: computes `sqrt(x²+y²)` with bounded scaled
|
||||
squares and complete-expansion rescaling at exponent boundaries. Widely separated
|
||||
operands use a small correction without squaring an underflow-prone ratio.
|
||||
Results are nonnegative, including positive zero. Either infinity takes precedence
|
||||
over NaN; otherwise NaN propagates. At the upper boundary, exact squared-input
|
||||
comparisons determine overflow; an overflowing approximation of a finite root
|
||||
is clamped to the largest finite component pair. Overflow produces positive infinity.
|
||||
- `Hypot(DoubleDouble, DoubleDouble, DoubleDouble)`: the 3D Euclidean norm
|
||||
`sqrt(x²+y²+z²)`, with the same special-value and approximate-accuracy contracts.
|
||||
Coordinates are ordered by magnitude before evaluating scaled squares, so signs
|
||||
and permutations give identical component bits. Widely separated coordinates
|
||||
contribute combined corrections without prematurely underflowing their squares.
|
||||
A zero coordinate reduces to the two-argument overload; exact overflow checks
|
||||
include all three original inputs. This overload is a convenience API, not an
|
||||
additional member of `IRootFunctions`.
|
||||
- `RootN(DoubleDouble, int)`: real nth root for positive degrees, reciprocal root
|
||||
for negative degrees, supporting the complete `int` range. Degree zero always
|
||||
returns NaN; negative nonzero inputs require an odd degree. Odd degrees retain
|
||||
the input sign, while even degrees map either signed zero to positive zero for
|
||||
positive degrees and positive infinity for negative degrees. Negative degrees
|
||||
exchange zero and infinity. Unlike `Sqrt(-0)`, `RootN(-0, 2)` is positive zero.
|
||||
Degrees ±1, ±2 and ±3 reuse identity/reciprocal and existing root kernels; other
|
||||
degrees refine a binary64 seed using integer powers with separately tracked
|
||||
exponents, then incorporate the input low without premature underflow.
|
||||
- `Pow(DoubleDouble, int)`: exponentiation by squaring with a separately tracked
|
||||
binary exponent. Supports the full `int` domain, including `int.MinValue`, and
|
||||
reciprocates a bounded significand before final scaling for negative exponents.
|
||||
@@ -138,8 +172,12 @@ The `DDMath` static class provides:
|
||||
```csharp
|
||||
using Just.PreciseMath;
|
||||
|
||||
DoubleDouble root = DDMath.Sqrt(new DoubleDouble(2.0));
|
||||
DoubleDouble inverseRoot = DDMath.InvSqrt(new DoubleDouble(2.0));
|
||||
DoubleDouble root = DoubleDouble.Sqrt(new DoubleDouble(2.0));
|
||||
DoubleDouble inverseRoot = DoubleDouble.InvSqrt(new DoubleDouble(2.0));
|
||||
DoubleDouble cubeRoot = DoubleDouble.Cbrt(new DoubleDouble(-8.0));
|
||||
DoubleDouble distance = DoubleDouble.Hypot(new DoubleDouble(3.0), new DoubleDouble(4.0));
|
||||
DoubleDouble norm3D = DoubleDouble.Hypot(new DoubleDouble(2.0), new DoubleDouble(3.0), new DoubleDouble(6.0));
|
||||
DoubleDouble fifthRoot = DoubleDouble.RootN(new DoubleDouble(2.0), 5);
|
||||
DoubleDouble reciprocal = DDMath.Reciprocal(new DoubleDouble(3.0));
|
||||
DoubleDouble magnitude = DDMath.Abs(-root);
|
||||
DoubleDouble smallPower = DDMath.Pow(new DoubleDouble(2.0), -1024);
|
||||
@@ -165,6 +203,20 @@ both suites exercise half-ulp low-component normalization boundaries.
|
||||
This is a tested approximate-accuracy contract, not exhaustive coverage
|
||||
of all component pairs or a guarantee of correctly rounded results.
|
||||
|
||||
Cube-root and nth-root tests check `2^-100` relative error for finite nonzero
|
||||
inputs with degree magnitude at least two. Small degrees use exact integer-power
|
||||
inequalities; large degrees use independently generated decimal references checked
|
||||
at 450 and 650 digits, including `int.MinValue` and `int.MaxValue`.
|
||||
`RootN(x, -1)` retains the reciprocal contract, including its subnormal error floor.
|
||||
Hypotenuse tests use exact squared inequalities with `2^-100` relative error plus
|
||||
one minimum binary64 subnormal. Tests also check exact binary cases, sparse lows,
|
||||
special-value signs, facade component-bit agreement, and constrained generic dispatch.
|
||||
The 2D and 3D hypotenuse overflow tests bracket the exact threshold, including scaled
|
||||
55/48/73 and 1/2/2/3 Pythagorean cases at the midpoint. Three-coordinate tests include
|
||||
all signs and permutations of boundary cases and sparse corrections, including
|
||||
corrections that only become representable when combined. Finite components remain approximate,
|
||||
not universally correctly rounded, including near underflow.
|
||||
|
||||
Logarithm tests compare exact component sums with independently generated
|
||||
120-digit decimal references, requiring agreement at 450 and 650 digits. They
|
||||
check `2^-100` relative error plus one minimum binary64 subnormal, with an explicit
|
||||
@@ -291,9 +343,9 @@ bool success = DoubleDouble.TryParse("1.25e-2".AsSpan(), CultureInfo.InvariantCu
|
||||
## Deferred scope
|
||||
|
||||
Natural `DDMath.Log`, `Exp`, and all three `Pow` overloads are implemented.
|
||||
Logarithms in other bases, generic-math interfaces beyond `ISignedNumber` and
|
||||
`IFloatingPointConstants`, additional text formats/general round-trip formatting,
|
||||
and non-arithmetic performance benchmarks remain deferred.
|
||||
Logarithms in other bases, generic-math interfaces beyond `ISignedNumber`,
|
||||
`IFloatingPointConstants`, and `IRootFunctions`, additional text formats/general
|
||||
round-trip formatting, and non-arithmetic performance benchmarks remain deferred.
|
||||
Replacing allocating arithmetic boundary fallbacks is also deferred; the current
|
||||
`BigInteger` paths remain in place. That optimization does not require removing
|
||||
`BigInteger` from conversions, parsing, formatting, or independent test oracles.
|
||||
|
||||
Reference in New Issue
Block a user