ported legacy DoubleDouble with tests
.NET Test / .NET tests (push) Successful in 1m14s

This commit is contained in:
2026-09-13 22:19:23 +04:00
parent ec609b26f7
commit 082fd84c87
17 changed files with 2891 additions and 26 deletions
@@ -5,6 +5,28 @@ namespace Just.PreciseMath.Tests;
public class DoubleDoubleTests
{
[Theory]
[InlineData("PI", 3.141592653589793, 1.2246467991473532e-16)]
[InlineData("E", 2.718281828459045, 1.4456468917292502e-16)]
[InlineData("LN2", 0.6931471805599453, 2.3190468138462996e-17)]
public void ConstantsHaveNearestBinary64Residuals(string name, double high, double low)
{
// Each residual is round_binary64(constant - exact_binary64(high)).
// Reproduced with Python decimal at precision 90: e = Decimal(1).exp(),
// ln(2) = Decimal(2).ln(), pi = 16*atan(1/5) - 4*atan(1/239), using
// atan(x) = sum((-1)^k*x^(2k+1)/(2k+1)) until |term| < 1e-95.
// low = float(reference - Decimal.from_float(float(reference))).
DoubleDouble value = name switch
{
"PI" => DoubleDouble.PI,
"E" => DoubleDouble.E,
"LN2" => DoubleDouble.LN2,
_ => throw new ArgumentOutOfRangeException(nameof(name)),
};
value.High.ShouldBe(high);
value.Low.ShouldBe(low);
}
[Fact]
public void OneHasExpectedComponents()
{
@@ -13,4 +35,52 @@ public class DoubleDoubleTests
value.High.ShouldBe(1.0);
value.Low.ShouldBe(0.0);
}
[Theory]
[InlineData(1.0, 0.0)]
[InlineData(10.0, 0.0)]
[InlineData(100.0, 0.0)]
[InlineData(-1.0, 0.0)]
[InlineData(-10.0, 0.0)]
[InlineData(-100.0, 0.0)]
[InlineData(3.141592653589793, 1.2246467991473532e-16)]
[InlineData(2.718281828459045, 1.4456468917292502e-16)]
[InlineData(0.6931471805599453, 2.3190468138462996e-17)]
public void AdditiveIdentity(double high, double low)
{
DoubleDouble value = new(high, low);
DoubleDouble result = value + DoubleDouble.AdditiveIdentity;
DoubleDouble resultInversedOrder = DoubleDouble.AdditiveIdentity + value;
result.High.ShouldBe(high);
result.Low.ShouldBe(low);
resultInversedOrder.High.ShouldBe(high);
resultInversedOrder.Low.ShouldBe(low);
}
[Theory]
[InlineData(1.0, 0.0)]
[InlineData(10.0, 0.0)]
[InlineData(100.0, 0.0)]
[InlineData(-1.0, 0.0)]
[InlineData(-10.0, 0.0)]
[InlineData(-100.0, 0.0)]
[InlineData(3.141592653589793, 1.2246467991473532e-16)]
[InlineData(2.718281828459045, 1.4456468917292502e-16)]
[InlineData(0.6931471805599453, 2.3190468138462996e-17)]
public void MultiplicativeIdentity(double high, double low)
{
DoubleDouble value = new(high, low);
DoubleDouble result = value * DoubleDouble.MultiplicativeIdentity;
DoubleDouble resultInversedOrder = DoubleDouble.MultiplicativeIdentity * value;
result.High.ShouldBe(high);
result.Low.ShouldBe(low);
resultInversedOrder.High.ShouldBe(high);
resultInversedOrder.Low.ShouldBe(low);
}
}