This commit is contained in:
@@ -22,20 +22,37 @@ already-normalized results. Mathematical constants use precomputed high/low pair
|
||||
checked against independently computed high-precision values; accessing them does
|
||||
not perform double-double arithmetic or allocate on the heap.
|
||||
|
||||
- Arithmetic: static `Add`, `Subtract`, `Multiply`, and `Divide` methods accept
|
||||
- Arithmetic: static `Add`, `Subtract`, `Multiply`, `Divide`, and `Modulus` methods accept
|
||||
`DoubleDouble` pairs and both operand orders with a `double`. `Plus` and `Negate`
|
||||
provide unary operations. The arithmetic operators (`+`, `-`, `*`, `/`, unary
|
||||
provide unary operations. The arithmetic operators (`+`, `-`, `*`, `/`, `%`, unary
|
||||
`+`/`-`, and `++`/`--`) are thin wrappers around these methods.
|
||||
Addition retains residuals under cancellation; multiplication uses
|
||||
fused multiply-add; division uses residual corrections. Mixed `double` operators
|
||||
fused multiply-add; division uses residual corrections. Mixed `double` overloads
|
||||
use specialized scalar paths rather than promoting the scalar to `DoubleDouble`.
|
||||
Division retains the complete first remainder and applies two quotient corrections,
|
||||
normalizing before the final correction. Mixed addition and subtraction also retain
|
||||
intermediate sum residuals through final normalization. Mixed addition, subtraction,
|
||||
and division produce the same component bits as their `DoubleDouble` operations
|
||||
with the scalar represented as a zero-low pair.
|
||||
- Remainder: `Modulus` and `%` use C# truncation-toward-zero semantics, not
|
||||
Euclidean modulo or IEEE nearest-integer remainder. Both components determine
|
||||
the exact integer quotient; the remainder is then rounded to a normalized pair.
|
||||
Its sign, including zero, follows the dividend. A zero divisor, infinite dividend,
|
||||
or NaN operand produces canonical NaN; a finite dividend modulo infinity is
|
||||
unchanged. Zero-low operands use binary64 `%`; smaller dividends and equal-high
|
||||
operands also have non-allocating shortcuts. The general finite path uses FMA
|
||||
residuals and stack-based error-free sums to verify the exact integer quotient
|
||||
before rounding the remainder. Its initial quotient estimate is limited to
|
||||
`2^52` and the dividend's high exponent to 1020, leaving safe transform headroom.
|
||||
Outside those bounds, or if quotient correction cannot be certified, bounded
|
||||
`BigInteger` arithmetic is the fallback. Warmed allocation tests pin zero managed
|
||||
allocations for representative two-component cases in all three overloads;
|
||||
no timing improvement is claimed. Mixed overloads retain the component bits of the
|
||||
equivalent DD/DD operation. Exact-dyadic tests and independent rational checks
|
||||
cover sparse lows, quotient boundaries, subnormals and extreme exponents; this
|
||||
does not promise universally correctly rounded component pairs.
|
||||
- Exponent boundaries: bounded `BigInteger` calculations avoid intermediate
|
||||
overflow and underflow on the exceptional finite path. Ordinary arithmetic uses
|
||||
overflow and underflow on the exceptional finite path. Ordinary `+`, `-`, `*`, `/` use
|
||||
floating-point transforms without allocations, although sparse division correction
|
||||
products can also reach a boundary path. The stored value remains two
|
||||
doubles; this is not an arbitrary-precision API.
|
||||
@@ -389,13 +406,22 @@ sampled error bounds does not guarantee correct range decisions for every input.
|
||||
to recover the components. This is not a shortest-round-trip format and does not
|
||||
change the standard formats' 999-digit precision limit or the parser's length limit.
|
||||
|
||||
`DoubleDouble` implements `ISignedNumber<DoubleDouble>`, including the inherited
|
||||
`DoubleDouble` implements `INumber<DoubleDouble>` and `ISignedNumber<DoubleDouble>`, including the inherited
|
||||
`INumberBase` contracts: binary radix, classification, absolute value, magnitude
|
||||
selection, increment/decrement, and generic numeric conversions. Integer/parity
|
||||
tests and magnitude comparisons retain both components. Magnitude ties prefer
|
||||
positive values for maximum and negative values for minimum, including signed zero;
|
||||
the `Number` variants prefer a number over NaN.
|
||||
|
||||
`INumber` provides comparison and remainder dispatch as well as constrained generic
|
||||
access to `Clamp`, `CopySign`, `Max`, `Min`, `MaxNumber`, and `MinNumber` through
|
||||
the interface defaults. The .NET 10 native variants also use their defaults.
|
||||
These defaults do not create directly callable static methods on `DoubleDouble`.
|
||||
`DoubleDouble.Sign` is explicitly implemented: it returns -1, 0, or 1 and throws
|
||||
`ArithmeticException` for NaN consistently on both target frameworks (unlike the
|
||||
.NET 8 interface default). Comparisons and sign copying preserve low components
|
||||
and signed-zero behavior; NaN results retain the library's canonical representation.
|
||||
|
||||
`CreateChecked`, `CreateSaturating`, and `CreateTruncating` support built-in numeric
|
||||
types and `BigInteger`. Floating overflow produces signed infinity in all modes.
|
||||
Finite integer output truncates the exact sum, then throws on overflow, clamps,
|
||||
@@ -459,7 +485,7 @@ bool success = DoubleDouble.TryParse("1.25e-2".AsSpan(), CultureInfo.InvariantCu
|
||||
|
||||
The complete logarithmic and exponential families on `DoubleDouble`, and all
|
||||
three `DoubleDouble.Pow` overloads are implemented.
|
||||
Generic-math interfaces beyond `ISignedNumber`, `IFloatingPointConstants`,
|
||||
Generic-math interfaces beyond `INumber`, `ISignedNumber`, `IFloatingPointConstants`,
|
||||
`IRootFunctions`, `IExponentialFunctions`, `ILogarithmicFunctions`, and `IPowerFunctions`, additional text formats/shortest-
|
||||
round-trip formatting, and non-arithmetic performance benchmarks remain deferred.
|
||||
Replacing allocating arithmetic boundary fallbacks is also deferred; the current
|
||||
|
||||
Reference in New Issue
Block a user