This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
namespace Just.PreciseMath.Tests;
|
||||
|
||||
public class DoubleDoubleNumberTests
|
||||
{
|
||||
[Fact]
|
||||
public void NumberDefaultsUseBothComponents()
|
||||
{
|
||||
DoubleDouble lower = new(1.0, -double.Epsilon);
|
||||
DoubleDouble upper = new(1.0, double.Epsilon);
|
||||
AssertBits(Max(lower, upper), upper);
|
||||
AssertBits(Max(upper, lower), upper);
|
||||
AssertBits(MaxNumber(lower, upper), upper);
|
||||
AssertBits(Min(lower, upper), lower);
|
||||
AssertBits(Min(upper, lower), lower);
|
||||
AssertBits(MinNumber(lower, upper), lower);
|
||||
AssertBits(Clamp(DoubleDouble.Zero, lower, upper), lower);
|
||||
AssertBits(Clamp(DoubleDouble.One, lower, upper), DoubleDouble.One);
|
||||
AssertBits(Clamp(new DoubleDouble(2.0), lower, upper), upper);
|
||||
Should.Throw<ArgumentException>(() => Clamp(DoubleDouble.One, upper, lower));
|
||||
AssertBits(CopySign(upper, DoubleDouble.NegativeZero), new DoubleDouble(-1.0, -double.Epsilon));
|
||||
AssertBits(CopySign(-upper, DoubleDouble.Zero), upper);
|
||||
Sign(lower).ShouldBe(1);
|
||||
Sign(-upper).ShouldBe(-1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NumberDefaultsHandleSpecialValuesAndSignedZeros()
|
||||
{
|
||||
double[] values = [0.0, -0.0, 1.0, -1.0, double.Epsilon, -double.Epsilon,
|
||||
double.MaxValue, double.PositiveInfinity, double.NegativeInfinity, double.NaN];
|
||||
foreach (double left in values)
|
||||
{
|
||||
DoubleDouble x = new(left);
|
||||
foreach (double right in values)
|
||||
{
|
||||
DoubleDouble y = new(right);
|
||||
AssertBits(Max(x, y), new DoubleDouble(double.Max(left, right)));
|
||||
AssertBits(Min(x, y), new DoubleDouble(double.Min(left, right)));
|
||||
AssertBits(MaxNumber(x, y), new DoubleDouble(double.MaxNumber(left, right)));
|
||||
AssertBits(MinNumber(x, y), new DoubleDouble(double.MinNumber(left, right)));
|
||||
AssertBits(CopySign(x, y), new DoubleDouble(double.CopySign(left, right)));
|
||||
}
|
||||
AssertBits(Clamp(x, DoubleDouble.NegativeOne, DoubleDouble.One), new DoubleDouble(double.Clamp(left, -1.0, 1.0)));
|
||||
if (double.IsNaN(left))
|
||||
{
|
||||
Should.Throw<ArithmeticException>(() => Sign(x));
|
||||
Should.Throw<ArithmeticException>(() => DoubleDouble.Sign(x));
|
||||
}
|
||||
else
|
||||
{
|
||||
Sign(x).ShouldBe(double.Sign(left));
|
||||
DoubleDouble.Sign(x).ShouldBe(double.Sign(left));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if NET10_0_OR_GREATER
|
||||
[Fact]
|
||||
public void NativeDefaultsRetainFullComponentOrdering()
|
||||
{
|
||||
DoubleDouble lower = new(1.0, -double.Epsilon);
|
||||
DoubleDouble upper = new(1.0, double.Epsilon);
|
||||
AssertBits(MaxNative(lower, upper), upper);
|
||||
AssertBits(MinNative(lower, upper), lower);
|
||||
AssertBits(ClampNative(DoubleDouble.Zero, lower, upper), lower);
|
||||
AssertBits(ClampNative(DoubleDouble.One, lower, upper), DoubleDouble.One);
|
||||
AssertBits(ClampNative(new DoubleDouble(2.0), lower, upper), upper);
|
||||
Should.Throw<ArgumentException>(() => ClampNative(DoubleDouble.One, upper, lower));
|
||||
}
|
||||
#endif
|
||||
|
||||
private static T Clamp<T>(T value, T min, T max) where T : INumber<T> => T.Clamp(value, min, max);
|
||||
|
||||
private static T CopySign<T>(T value, T sign) where T : INumber<T> => T.CopySign(value, sign);
|
||||
|
||||
private static T Max<T>(T x, T y) where T : INumber<T> => T.Max(x, y);
|
||||
|
||||
private static T MaxNumber<T>(T x, T y) where T : INumber<T> => T.MaxNumber(x, y);
|
||||
|
||||
private static T Min<T>(T x, T y) where T : INumber<T> => T.Min(x, y);
|
||||
|
||||
private static T MinNumber<T>(T x, T y) where T : INumber<T> => T.MinNumber(x, y);
|
||||
|
||||
private static int Sign<T>(T value) where T : INumber<T> => T.Sign(value);
|
||||
|
||||
#if NET10_0_OR_GREATER
|
||||
private static T ClampNative<T>(T value, T min, T max) where T : INumber<T> => T.ClampNative(value, min, max);
|
||||
|
||||
private static T MaxNative<T>(T x, T y) where T : INumber<T> => T.MaxNative(x, y);
|
||||
|
||||
private static T MinNative<T>(T x, T y) where T : INumber<T> => T.MinNative(x, y);
|
||||
#endif
|
||||
|
||||
private static void AssertBits(DoubleDouble actual, DoubleDouble expected)
|
||||
{
|
||||
BitConverter.DoubleToInt64Bits(actual.High).ShouldBe(BitConverter.DoubleToInt64Bits(expected.High));
|
||||
BitConverter.DoubleToInt64Bits(actual.Low).ShouldBe(BitConverter.DoubleToInt64Bits(expected.Low));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user