This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Numerics;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
@@ -5,6 +6,71 @@ namespace Just.PreciseMath.Tests;
|
||||
|
||||
public class DoubleDoubleTests
|
||||
{
|
||||
[Fact]
|
||||
public void EpsilonIsTheMinimumPositiveBinary64Subnormal()
|
||||
{
|
||||
// Each finite component is an integer multiple of 2^-1074, so their
|
||||
// exact sum cannot have a smaller positive quantum. This is not a
|
||||
// relative-error tolerance or a fixed significand spacing near one.
|
||||
DoubleDouble value = DoubleDouble.Epsilon;
|
||||
BitConverter.DoubleToInt64Bits(value.High).ShouldBe(1L);
|
||||
BitConverter.DoubleToInt64Bits(value.Low).ShouldBe(0L);
|
||||
DoubleDouble.IsCanonical(value).ShouldBeTrue();
|
||||
DoubleDouble.IsFinite(value).ShouldBeTrue();
|
||||
DoubleDouble.IsSubnormal(value).ShouldBeTrue();
|
||||
DoubleDouble.IsNormal(value).ShouldBeFalse();
|
||||
DoubleDouble.IsPositive(value).ShouldBeTrue();
|
||||
(value > DoubleDouble.Zero).ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("NegativeZero", -0.0)]
|
||||
[InlineData("PositiveInfinity", double.PositiveInfinity)]
|
||||
[InlineData("NegativeInfinity", double.NegativeInfinity)]
|
||||
[InlineData("NaN", double.NaN)]
|
||||
public void SpecialConstantsHaveCanonicalComponentBits(string name, double expectedHigh)
|
||||
{
|
||||
DoubleDouble value = name switch
|
||||
{
|
||||
"NegativeZero" => DoubleDouble.NegativeZero,
|
||||
"PositiveInfinity" => DoubleDouble.PositiveInfinity,
|
||||
"NegativeInfinity" => DoubleDouble.NegativeInfinity,
|
||||
"NaN" => DoubleDouble.NaN,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(name)),
|
||||
};
|
||||
BitConverter.DoubleToInt64Bits(value.High).ShouldBe(BitConverter.DoubleToInt64Bits(expectedHigh));
|
||||
BitConverter.DoubleToInt64Bits(value.Low).ShouldBe(0L);
|
||||
DoubleDouble.IsCanonical(value).ShouldBeTrue();
|
||||
DoubleDouble.IsNaN(value).ShouldBe(double.IsNaN(expectedHigh));
|
||||
DoubleDouble.IsFinite(value).ShouldBe(double.IsFinite(expectedHigh));
|
||||
DoubleDouble.IsPositiveInfinity(value).ShouldBe(double.IsPositiveInfinity(expectedHigh));
|
||||
DoubleDouble.IsNegativeInfinity(value).ShouldBe(double.IsNegativeInfinity(expectedHigh));
|
||||
DoubleDouble.IsNegative(value).ShouldBe(double.IsNegative(expectedHigh));
|
||||
DoubleDouble.IsZero(value).ShouldBe(expectedHigh == 0.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NegativeZeroConstantPreservesZeroEqualityAndHashing()
|
||||
{
|
||||
DoubleDouble value = DoubleDouble.NegativeZero;
|
||||
(value == DoubleDouble.Zero).ShouldBeTrue();
|
||||
value.Equals(DoubleDouble.Zero).ShouldBeTrue();
|
||||
value.CompareTo(DoubleDouble.Zero).ShouldBe(0);
|
||||
value.GetHashCode().ShouldBe(DoubleDouble.Zero.GetHashCode());
|
||||
BitConverter.DoubleToInt64Bits((-value).High).ShouldBe(0L);
|
||||
BitConverter.DoubleToInt64Bits((-value).Low).ShouldBe(0L);
|
||||
BitConverter.DoubleToInt64Bits(DoubleDouble.Zero.High).ShouldBe(0L);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FloatingPointConstantsSupportGenericDispatch()
|
||||
{
|
||||
(DoubleDouble e, DoubleDouble pi, DoubleDouble tau) = GetFloatingPointConstants<DoubleDouble>();
|
||||
e.ShouldBe(DoubleDouble.E);
|
||||
pi.ShouldBe(DoubleDouble.Pi);
|
||||
tau.ShouldBe(DoubleDouble.Tau);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Pi", 3.141592653589793, 1.2246467991473532e-16)]
|
||||
[InlineData("E", 2.718281828459045, 1.4456468917292502e-16)]
|
||||
@@ -184,4 +250,9 @@ public class DoubleDoubleTests
|
||||
result.High.ShouldBe(high);
|
||||
result.Low.ShouldBe(low);
|
||||
}
|
||||
|
||||
private static (T E, T Pi, T Tau) GetFloatingPointConstants<T>() where T : IFloatingPointConstants<T>
|
||||
{
|
||||
return (T.E, T.Pi, T.Tau);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user