When comparing vary large doubles it happens that the following test fails:
[Test]
public void DoubleMaxValueTest()
{
double val = Double.MaxValue;
double epsilon = 10000.0;
Assert.IsTrue(val > (Double.MaxValue - epsilon));
}
Being aware that doubles are represented as mantissa, exponent and a sign bit it is due to the fact that the value Double.MaxValue - 10000 is actually represented the same way as Double.MaxValue (these values are equal).
The question is: How to get the smallest epsilon for which this test returns true?
To answer the final question, as it sounds like you actually understand why the test fails...
IEEE-754 has a neat property that if you take adjacent bitwise values, those end up being adjacent representable double
values. So you can find the "second highest" representable double
by treating the bit pattern for MaxValue
as an integer, subtracting 1, and turning the result back into a double
:
using System;
class Test
{
static void Main()
{
long maxDoubleBits = BitConverter.DoubleToInt64Bits(Double.MaxValue);
double nextLargestDouble = BitConverter.Int64BitsToDouble(maxDoubleBits - 1);
double difference = double.MaxValue - nextLargestDouble;
Console.WriteLine(difference);
}
}
The result is 1.99584030953472E+292
Now, that difference is the actual difference between MaxValue
and the next highest value. So the smallest amount that you can subtract from double.MaxValue
to get a value which isn't MaxValue
is actually difference / 2
.
See more on this question at Stackoverflow