This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user