the first optimization round
.NET Test / .NET tests (push) Successful in 1m26s

This commit is contained in:
2026-09-14 13:58:04 +04:00
parent cb2524980d
commit 08036a31d5
12 changed files with 1316 additions and 49 deletions
@@ -6,6 +6,60 @@ namespace Just.PreciseMath.Tests;
public class DoubleDoubleBoundaryTests
{
[Fact]
public void BoundarySubtractionPreservesComponentsOfTheOriginalExpression()
{
DoubleDouble[] magnitudes =
[
new(0.0), new(double.Epsilon), new(1.0),
new(Math.BitDecrement(Math.ScaleB(1.0, 1021))),
new(Math.ScaleB(1.0, 1021)),
DoubleDouble.FromComponents(Math.ScaleB(1.0, 1021), double.Epsilon),
DoubleDouble.FromComponents(Math.ScaleB(1.0, 1021), Math.ScaleB(1.0, 967)),
new(double.MaxValue),
DoubleDouble.FromComponents(double.MaxValue, Math.ScaleB(1.0, 969)),
DoubleDouble.FromComponents(double.MaxValue, -Math.ScaleB(1.0, 969))
];
foreach (DoubleDouble leftMagnitude in magnitudes)
{
foreach (DoubleDouble rightMagnitude in magnitudes)
{
// Use the original exponent-domain rule, not the production predicate.
if (Math.ILogB(leftMagnitude.High) <= 1020 && Math.ILogB(rightMagnitude.High) <= 1020)
{
continue;
}
foreach (double leftSign in new[] { -1.0, 1.0 })
{
foreach (double rightSign in new[] { -1.0, 1.0 })
{
DoubleDouble left = leftSign < 0.0 ? -leftMagnitude : leftMagnitude;
DoubleDouble right = rightSign < 0.0 ? -rightMagnitude : rightMagnitude;
DoubleDouble actual = left - right;
// Bitwise characterization of the expression being extracted,
// supplemented below by the independent exact-rational oracle.
DoubleDouble original = PreciseMathHelper.AddBoundary(left, -right);
string context = Describe(left, right, "-");
BitConverter.DoubleToInt64Bits(actual.High).ShouldBe(BitConverter.DoubleToInt64Bits(original.High), context);
BitConverter.DoubleToInt64Bits(actual.Low).ShouldBe(BitConverter.DoubleToInt64Bits(original.Low), context);
Rational expected = Exact(left) - Exact(right);
if (BelowOverflowMidpoint(expected))
{
AssertAccurate(actual, expected, context);
AssertNormalized(actual);
}
else
{
actual.High.ShouldBe(expected.CompareTo(Exact(0.0)) < 0
? double.NegativeInfinity : double.PositiveInfinity, context);
BitConverter.DoubleToInt64Bits(actual.Low).ShouldBe(0L, context);
}
}
}
}
}
}
[Theory]
[InlineData(1.0, "+")]
[InlineData(-1.0, "+")]