Where do I find the machine epsilon in C#?

百般思念 提交于 2019-12-30 00:58:10

问题


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 ?


回答1:


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.




回答2:


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.




回答3:


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.




回答4:


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



回答5:


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.



来源:https://stackoverflow.com/questions/9392869/where-do-i-find-the-machine-epsilon-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!