http://msdn.microsoft.com/en-我们/库/ system.double.epsilon.aspx

  

如果您创建一个自定义算法   确定是否两个浮点   数字可以认为是平等的,你   必须使用的值大于   小量不断建立   的可接受的绝对余量   为两个值差为   认为是相等的。 (典型地,   差的利润率是多少次   大于小量。)

因此,这是不是真的可能被用于比较的埃普西隆?我真的不明白MSDN措辞。

是否可以用作这里的实施例中的ε? - 什么是float和double比较最有效的方法?

最后这似乎真的很重要,所以我想确保我有平等扎实实施,大于,小于,小于或等于和大于或等于。

有帮助吗?

解决方案

我不知道的什么的他们时,他们写道,吸烟。 Double.Epsilon是表示的最小非非标准浮点值不为0。所有你知道的是,如果有一个截断误差,它总是会的的超过此值。大得多。

System.Double类型可以表示的值精确到最多15个位数。因此,一个简单的一阶估计如果使用双值x等于某一常数是使用恒定的ε* 1E-15

public static bool AboutEqual(double x, double y) {
    double epsilon = Math.Max(Math.Abs(x), Math.Abs(y)) * 1E-15;
    return Math.Abs(x - y) <= epsilon;
}

您必须虽然看出来,截断误差可以累积。如果两个xy计算值,则必须增加的ε。

其他提示

  

我想确保我有相等固体实施方案中,大于,小于,小于或等于,和大于或等于

您正在使用二进制浮点算术。

二进制浮点运算的目的是要表示的物理量,例如,长度,质量,电荷,时间,等等。

据推测则您使用的,因为它是旨在用于二进制浮点算术:做就物理量运算

的物理量的测量总是具有特定的精度,这取决于用来测量它们的设备的精确度。

既然你是一个对你操纵的数量提供的值,你是谁知道什么是“误差条”是对数量的一个。例如,如果您提供的数量“的建筑高度为123.56米”,那么你知道这是精确到厘米,但不是到微米。

因此,在比较两个量相等时,所需的语义是说“是这两个量由每个测量指定的误差范围内相等?”

所以,现在我们有一个回答你的问题。你必须做什么是跟踪误差上的每个数量的东西;例如,建筑物的高度是“内123.56米0.01”,因为你知道那是测量的精确度如何。如果再得到另一个测量,这是123.5587,想知道这两个测量是否允许误差范围内的“平等”,然后做减法,看看它是否落入误差容限。在这种情况下它。如果测量实际上是精确到微米,那么他们是不相等的。

在短:你在这里的唯一的人谁知道什么有意义的错误公差,因为你是谁,知道你在哪里操纵人物在首位来的唯一的人。使用任何容错有意义的测量给出你被用来制造它们的设备的精度。

如果您有接近1.0两个双值,但他们只在他们的至少显著位不同,那么它们之间的差别将是数量级比Double.Epsilon更大的许多订单。事实上,不同的是大小的324个小数订单。这是因为指数部分的效果。 Double.Epsilon上有一个巨大的负指数,而1.0具有零指数(该偏压移除之后,当然)。

如果您想比较平等的两个相似值,那么你需要选择一个自定义的小量值适合于订单数量级大小的值来进行比较。

如果您要比较的双值是接近1.0。那么至少siginificant位的值将接近0.0000000000000001。如果您要比较的双值在quadrillions,那么至少显著位的值可能多达上千人。对于小量没有单一的值可以在两个那些情况下使用的相等比较。

我只是做这个 - 使用肯特Bogarts想法

private bool IsApproximatelyEqual(double x, double y, double acceptableVariance)
{
     double variance = x > y ? x - y : y - x;
     return variance < acceptableVariance;

     //or
     //return Math.Abs(x - y) < acceptableVariance;
}

它可以被用于比较,假设要确保这两个值要么完全相等,或具有用于双类型的表示的最小差。一般来说,你会想使用一些比double.Epsilon更大检查两个双打是否大致相等。

为什么.NET框架没有定义类似

bool IsApproximatelyEqual(double value, double permittedVariance);

超出我

我想在您发布的MSDN链接相关的位是这些:

  

然而,小量属性不是   的精度大体测量   Double类型;它仅适用于双   具有零值的实例。

     

注:小量的值   产权不等同于机器   ε,其表示在上   结合的相对误差的由于   舍入在浮点运算。

     

此值没有被定义为最小的   正数的x,使得x + 1.0   不等于1.0,所以Double.Epsilon   不能用于“几乎相等”。   存在于没有固定   框架,其值是最小   正数的x,使得x + 1.0   不等于1.0。

我不得不说,这令我感到奇怪。我也曾经认为Double.Epsilon是DBL_EPSILON的C /相当于C ++ - 显然不是!

从我可以阅读的链接似乎在说“你需要自己找出一个像样的值进行比较”,这是相当惊人的,至少可以说的。结果 也许有人更见地可以澄清:)

我使用以下

public static class MathUtil {
    /// <summary>
    /// smallest such that 1.0+EpsilonF != 1.0
    /// </summary>
    public const float EpsilonF = 1.192092896e-07F;

    /// <summary>
    /// smallest such that 1.0+EpsilonD != 1.0
    /// </summary>
    public const double EpsilonD = 2.2204460492503131e-016;

    [MethodImpl( MethodImplOptions.AggressiveInlining )]
    public static bool IsZero( this double value ) {
        return value < EpsilonD && value > -EpsilonD;
    }

    [MethodImpl( MethodImplOptions.AggressiveInlining )]
    public static int Sign( this double value ) {
        if ( value < -EpsilonD ) {
            return -1;
        }
        if ( value > EpsilonD )
            return 1;
        return 0;
    }

如果你要检查的两个双打“a”和“B”平等,你可以使用

(a-b).IsZero();

如果你想要得到的比较结果,使用

(a-b).Sign();

与比较双打的问题是,当你做两个不同的数学成绩是平等的,但其由于舍入误差,不评估为相同的值进行比较,就会有一些差异......这是比的ε-较大,除了在边缘情况。并使用可靠的小量值也是困难的。有些人认为两个双打相等,如果它们之间的差值小于某个百分比值,因为使用一个静态的最小差值小量可能意味着你的差异太大或太小当双本身是高还是低。

这里的一些代码,Silverlight的控制工具包内包含了两次:

    public static bool AreClose(double value1, double value2)
    {
        //in case they are Infinities (then epsilon check does not work)
        if(value1 == value2) return true;
        // This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < DBL_EPSILON
        double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON;
        double delta = value1 - value2;
        return(-eps < delta) && (eps > delta);
    }

在一个地方,他们使用1e-6为小量;在另一他们使用1.192093E-07。您将要选择适合自己的小量。

有没有选择,你必须自己进行计算或定义自己的常量。

double calculateMachineEpsilon() {
    double result = 1.0;
    double one = 1.0/256;

    while(one + result/2.0 != 1.0) {
        result/=2.0;
    }
    return result;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top