Reputation: 56976
The machine epsilon is canonically defined as the smallest number which added to one, gives a result different from one.
There is a Double.Epsilon
but the name is very misleading: it is the smallest (denormalized) Double
value representable, and thus useless for any kind of numeric programming.
I'd like to get the true epsilon for the Double
type, so that not to have to hardcode tolerances into my program. How do I do this ?
Upvotes: 16
Views: 6992
Reputation: 954
LAPACK + DLAMCH, 64-bit INTEL processor, C#:
var pp = double.Epsilon; // pp = 4.94065645841247E-324
double p = NativeMethods.MachinePrecision('S'); // =DLAMCH('S')
p = 2.2250738585072014E-308
double.MinValue = -1.7976931348623157E+308
double.MaxValue = 1.7976931348623157E+308
Upvotes: 0
Reputation: 1
Ref. the routine in Meonester's: Actually the value of machEps on exit from the do ... while loop is such that 1+machEps == 1. To obtain the machine epsilon we must go back to the previous value, by adding the following after the loop: machEps *= 2.0D; This will return 2.2204460492503131e-16 in agreement with the recommendation in Microsoft's documentation for Double.Epsilon.
Upvotes: -2
Reputation: 61982
Just hard-code the value:
const double e1 = 2.2204460492503131e-16;
or use the power of two:
static readonly double e2 = Math.Pow(2, -52);
or use your definition (more or less):
static readonly double e3 = BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(1.0) + 1L) - 1.0;
And see Wikipedia: machine epsilon.
Upvotes: 3
Reputation: 220
It's(on my machine):
1.11022302462516E-16
You can easily calculate it:
double machEps = 1.0d;
do {
machEps /= 2.0d;
}
while ((double)(1.0 + machEps) != 1.0);
Console.WriteLine( "Calculated machine epsilon: " + machEps );
Edited:
I calcualted 2 times epsilon, now it should be correct.
Upvotes: 9
Reputation: 49280
The Math.NET library defines a Precision class, which has a DoubleMachineEpsilon property.
You could check how they do it.
According to that it is:
/// <summary>
/// The base number for binary values
/// </summary>
private const int BinaryBaseNumber = 2;
/// <summary>
/// The number of binary digits used to represent the binary number for a double precision floating
/// point value. i.e. there are this many digits used to represent the
/// actual number, where in a number as: 0.134556 * 10^5 the digits are 0.134556 and the exponent is 5.
/// </summary>
private const int DoublePrecision = 53;
private static readonly double doubleMachinePrecision = Math.Pow(BinaryBaseNumber, -DoublePrecision);
So it is 1,11022302462516E-16
according to this source.
Upvotes: 8