This commit is contained in:
@@ -89,6 +89,38 @@ public class DoubleDoubleRepresentationTests
|
||||
(value != DoubleDouble.NaN).ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FiniteNormalizationPreservesOrderingResidualsAndZeroSigns()
|
||||
{
|
||||
// Exact dyadic sums, independent of the public factory. Include both
|
||||
// magnitude orders, cancellation, subnormals, and signed zero lows.
|
||||
double unit = Math.ScaleB(1.0, 970);
|
||||
(double High, double Low, double ExpectedHigh, double ExpectedLow)[] cases =
|
||||
[
|
||||
(-0.0, 0.0, -0.0, 0.0), (-0.0, -0.0, -0.0, 0.0),
|
||||
(0.0, -0.0, 0.0, 0.0), (1.0, -1.0, 0.0, 0.0),
|
||||
(-1.0, 1.0, 0.0, 0.0), (double.Epsilon, -double.Epsilon, 0.0, 0.0),
|
||||
(double.Epsilon, double.Epsilon, 2 * double.Epsilon, 0.0),
|
||||
(0.0, double.Epsilon, double.Epsilon, 0.0),
|
||||
(double.Epsilon, -1.0, -1.0, double.Epsilon),
|
||||
(1.0, double.Epsilon, 1.0, double.Epsilon),
|
||||
(double.Epsilon, 1.0, 1.0, double.Epsilon),
|
||||
(-1.0, -double.Epsilon, -1.0, -double.Epsilon),
|
||||
(-double.Epsilon, -1.0, -1.0, -double.Epsilon),
|
||||
(double.MaxValue, 0.0, double.MaxValue, 0.0),
|
||||
// MaxValue - 3*2^970 = (MaxValue - 2^971) - 2^970.
|
||||
// An unordered TwoSum would overflow an intermediate in the reversed case.
|
||||
(double.MaxValue, -3.0 * unit, Math.BitDecrement(double.MaxValue), -unit),
|
||||
(-3.0 * unit, double.MaxValue, Math.BitDecrement(double.MaxValue), -unit)
|
||||
];
|
||||
foreach ((double high, double low, double expectedHigh, double expectedLow) in cases)
|
||||
{
|
||||
DoubleDouble actual = PreciseMathHelper.NormalizeFinite(high, low);
|
||||
BitConverter.DoubleToInt64Bits(actual.High).ShouldBe(BitConverter.DoubleToInt64Bits(expectedHigh));
|
||||
BitConverter.DoubleToInt64Bits(actual.Low).ShouldBe(BitConverter.DoubleToInt64Bits(expectedLow));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ZeroSignsArePreservedButEqual()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user