我在哪里可以找到C#中的机器epsilon?
机器epsilon规范地定义为添加到一个的最小数字,给出不同于一个的结果。
有一个Double.Epsilon
但名称非常具有误导性:它是可表示的最小(非规范化) Double
值,因此对任何类型的数字编程都没用。
我想为Double
类型获得真正的 epsilon,这样就不必将容差硬编码到我的程序中。 我该怎么做呢 ?
它(在我的机器上):
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,现在应该是正确的。
Math.NET库定义了一个Precision类,它具有DoubleMachineEpsilon属性。
你可以检查他们是如何做到的。
根据它是:
/// /// The base number for binary values /// private const int BinaryBaseNumber = 2; /// /// The number of binary digits used to represent the binary number for a double precision floating /// point value. ie 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. /// private const int DoublePrecision = 53; private static readonly double doubleMachinePrecision = Math.Pow(BinaryBaseNumber, -DoublePrecision);
所以根据这个来源是1,11022302462516E-16
。
只需硬编码值:
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 。
参考。 Meonester中的例程:实际上,从do … while循环退出时machEps的值是1 + machEps == 1.要获得机器epsilon,我们必须回到之前的值,通过在循环:machEps * = 2.0D; 这将返回2.2204460492503131e-16,与微软Double.Epsilon文档中的建议一致。