This commit is contained in:
@@ -91,7 +91,10 @@ public readonly partial struct DoubleDouble :
|
||||
}
|
||||
|
||||
/// <summary>Multiplies expansions using an FMA product residual and cross terms.</summary>
|
||||
/// <remarks>Results are approximate double-double values, not universally correctly rounded.</remarks>
|
||||
/// <remarks>
|
||||
/// Swapping operands preserves both result components bit-for-bit.
|
||||
/// Results are approximate double-double values, not universally correctly rounded.
|
||||
/// </remarks>
|
||||
public static DoubleDouble operator *(DoubleDouble left, DoubleDouble right)
|
||||
{
|
||||
if (!IsFinite(left) || !IsFinite(right) || left._high == 0.0 || right._high == 0.0)
|
||||
@@ -103,6 +106,14 @@ public readonly partial struct DoubleDouble :
|
||||
return PreciseMathHelper.MultiplyBoundary(left, right);
|
||||
}
|
||||
|
||||
// Sequential cross-term FMAs round in order. Use the same operand order
|
||||
// in both directions, including when highs tie. Inputs here are finite
|
||||
// and nonzero with canonical lows; the exact boundary path is symmetric.
|
||||
if (left._high > right._high || (left._high == right._high && left._low > right._low))
|
||||
{
|
||||
(left, right) = (right, left);
|
||||
}
|
||||
|
||||
(double product, double error) = PreciseMathHelper.TwoMultiply(left._high, right._high);
|
||||
error = Math.FusedMultiplyAdd(left._high, right._low, error);
|
||||
error = Math.FusedMultiplyAdd(left._low, right._high, error);
|
||||
|
||||
Reference in New Issue
Block a user