This commit is contained in:
@@ -93,7 +93,11 @@ constants. The natural logarithm function is provided separately by `DDMath.Log`
|
||||
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
|
||||
them. Exponential functions live in `DoubleDouble.ExponentialFunctions.cs`:
|
||||
`Exp`, `Exp2`, `Exp10`, `ExpM1`, `Exp2M1`, and `Exp10M1` complete
|
||||
`IExponentialFunctions<DoubleDouble>`, including cancellation-safe overrides of
|
||||
the interface's default minus-one methods. `DDMath` exposes thin forwarding
|
||||
wrappers for roots and exponentials; logarithm, power, and reciprocal kernels
|
||||
remain in `DDMath`.
|
||||
|
||||
The `DDMath` static class provides:
|
||||
@@ -163,6 +167,20 @@ The `DDMath` static class provides:
|
||||
components affect range boundaries; representable subnormals are retained.
|
||||
Either zero maps to one, negative infinity to positive zero, positive infinity
|
||||
to positive infinity, and NaN to canonical NaN.
|
||||
- `Exp2(DoubleDouble)`: reduces the argument in base two before evaluating a
|
||||
bounded natural exponential. Integer powers from -1074 through 1023 are exact.
|
||||
An exponent-tracked correction preserves sparse lows that would otherwise round
|
||||
prematurely before final scaling. The exact half-minimum-subnormal threshold
|
||||
uses both input components. Special-value behavior is the same as `Exp`.
|
||||
- `Exp10(DoubleDouble)`: subtracts three split `log10(2)` products before converting
|
||||
the bounded remainder to a natural exponent, avoiding large-argument amplification
|
||||
of a rounded `ln(10)` product. Special-value behavior is the same as `Exp`.
|
||||
- `ExpM1(DoubleDouble)`, `Exp2M1(DoubleDouble)`, and `Exp10M1(DoubleDouble)`:
|
||||
compute the corresponding exponential minus one, using a direct series near
|
||||
zero to avoid cancellation. Signed zeros are preserved, negative infinity maps
|
||||
to negative one, positive infinity to positive infinity, and NaN to canonical NaN.
|
||||
Their tested relative error is measured against the minus-one result itself,
|
||||
not against the exponential before subtraction.
|
||||
- `Log(DoubleDouble)`: natural logarithm using binary range reduction and a
|
||||
centered atanh series. The bounded mantissa avoids denominator overflow for
|
||||
large inputs; a separate near-one path retains even minimum-subnormal low
|
||||
@@ -181,7 +199,10 @@ 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);
|
||||
DoubleDouble exponential = DDMath.Exp(new DoubleDouble(1.0));
|
||||
DoubleDouble exponential = DoubleDouble.Exp(new DoubleDouble(1.0));
|
||||
DoubleDouble binaryPower = DoubleDouble.Exp2(new DoubleDouble(-1000.0));
|
||||
DoubleDouble decimalPower = DoubleDouble.Exp10(new DoubleDouble(0.5));
|
||||
DoubleDouble tinyChange = DoubleDouble.ExpM1(new DoubleDouble(1e-30));
|
||||
DoubleDouble logarithm = DDMath.Log(new DoubleDouble(10.0));
|
||||
DoubleDouble fractionalPower = DDMath.Pow(new DoubleDouble(2.0), 0.5);
|
||||
DoubleDouble preciseExponent = DoubleDouble.FromComponents(0.5, 1e-30);
|
||||
@@ -225,13 +246,17 @@ additional tests cover extreme magnitudes, near-one cancellation, sparse lows of
|
||||
either sign, and range-reduction transitions. This is sampled approximate accuracy,
|
||||
not a universal error proof or a correct-rounding guarantee.
|
||||
|
||||
Exponential tests use independent high-precision decimal references evaluated at
|
||||
Exponential-family tests use independent high-precision decimal references evaluated at
|
||||
two precisions, with exact integer comparisons of the stored component sum. They
|
||||
check `2^-100` relative error plus one minimum binary64 subnormal, with a separately
|
||||
bounded reference-rounding allowance. Integer-power tests use exact rational
|
||||
bounded reference-rounding allowance. The base-two/base-ten and minus-one fixtures
|
||||
are checked at 450/650 digits, including adjacent lows at true range boundaries,
|
||||
series transitions, and tiny inputs. Additional component checks pin sparse
|
||||
base-two corrections; constrained generic calls and facade calls match direct
|
||||
calls bit-for-bit. Integer-power tests use exact rational
|
||||
references and high-precision fixtures for large exponents; their tested absolute
|
||||
error bound is `|exact result| * (|exponent| + 1) * 2^-100 + 2^-1074`, not uniform
|
||||
relative accuracy independent of the exponent. Both functions are approximate;
|
||||
relative accuracy independent of the exponent. These functions are approximate;
|
||||
precision decreases near underflow and approximation can affect results extremely
|
||||
close to a rounding boundary. Final scaling uses the existing allocating exact
|
||||
boundary machinery where necessary. No performance measurements are claimed.
|
||||
@@ -342,9 +367,10 @@ bool success = DoubleDouble.TryParse("1.25e-2".AsSpan(), CultureInfo.InvariantCu
|
||||
|
||||
## Deferred scope
|
||||
|
||||
Natural `DDMath.Log`, `Exp`, and all three `Pow` overloads are implemented.
|
||||
Natural `DDMath.Log`, the complete exponential family on `DoubleDouble`, and all
|
||||
three `DDMath.Pow` overloads are implemented.
|
||||
Logarithms in other bases, generic-math interfaces beyond `ISignedNumber`,
|
||||
`IFloatingPointConstants`, and `IRootFunctions`, additional text formats/general
|
||||
`IFloatingPointConstants`, `IRootFunctions`, and `IExponentialFunctions`, 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
|
||||
|
||||
Reference in New Issue
Block a user