在 C# 中哪里可以找到机器 epsilon?

发布于 2025-01-08 03:52:34 字数 239 浏览 0 评论 0原文

机器 epsilon 被规范地定义为与 1 相加得到的结果与 1 不同的最小数字。

有一个 Double.Epsilon 但名称非常具有误导性:它是可表示的最小(非规范化)Double 值,因此对于任何类型的数字编程都是无用的。

我想获得 Double 类型的 true epsilon,这样就不必将容差硬编码到我的程序中。我该怎么做?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏雨凉 2025-01-15 03:52:34

它(在我的机器上):

   1.11022302462516E-16

您可以轻松计算它:

        double machEps = 1.0d;

        do {
           machEps /= 2.0d;
        }
        while ((double)(1.0 + machEps) != 1.0);

        Console.WriteLine( "Calculated machine epsilon: " + machEps );

编辑:

我计算了 2 倍 epsilon,现在它应该是正确的。

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.

寒尘 2025-01-15 03:52:34

Math.NET 库定义了一个 Precision 类,具有 DoubleMachineEpsilon 属性。

你可以查一下他们是怎么做的。

根据它是:

    /// <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);

所以根据这个来源,它是1,11022302462516E-16

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.

执手闯天涯 2025-01-15 03:52:34

只需对值进行硬编码:

const double e1 = 2.2204460492503131e-16;

或使用二的幂:

static readonly double e2 = Math.Pow(2, -52);

或使用您的定义(或多或少):

static readonly double e3 = BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(1.0) + 1L) - 1.0;

并参见 维基百科:机器 epsilon

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.

旧人 2025-01-15 03:52:34

LAPACK + DLAMCH,64 位 INTEL 处理器,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

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
樱花坊 2025-01-15 03:52:34

参考号Meonester 的惯例:
实际上,退出 do ... while 循环时 machEps 的值是 1+machEps == 1。
要获得机器 epsilon,我们必须通过在循环后添加以下内容来返回到先前的值:
machEps *= 2.0D;
这将返回 2.2204460492503131e-16,与 Microsoft 文档中有关 Double.Epsilon 的建议一致。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文