C#与.Equals()比较两个double

Leo*_*eon 5 c# double compare

我使用ReShaper,当我用==比较两个double值时,它表明我应该使用Math.具有公差的ABS方法.请参阅:https://www.jetbrains.com/help/resharper/2016.2/CompareOfFloatsByEqualityOperator.html

这个例子

double d = 0.0;
double d2 = 0.0;
if (d == d2)
{
    /* some code */
}
Run Code Online (Sandbox Code Playgroud)

然后转换为

double d = 0.0;
double d2 = 0.0;
if (Math.Abs(d - d2) < TOLERANCE)
{
    /* some code */
}
Run Code Online (Sandbox Code Playgroud)

但我认为开发人员考虑正确的容忍度确实很复杂.所以我认为这可以在Double.Equals()方法中实现.

但是这种方法是这样实现的

public override bool Equals(Object obj) {
    if (!(obj is Double)) { 
        return false;
    } 
    double temp = ((Double)obj).m_value; 
    // This code below is written this way for performance reasons i.e the != and == check is intentional.
    if (temp == m_value) { 
        return true;
    }
    return IsNaN(temp) && IsNaN(m_value);
}

public bool Equals(Double obj)
{ 
    if (obj == m_value) {
        return true; 
    } 
    return IsNaN(obj) && IsNaN(m_value);
}
Run Code Online (Sandbox Code Playgroud)

这是为什么?什么是比较双值的正确方法?

Jan*_*kke 9

您可以创建一个扩展方法

public static class DoubleExtension 
{
    public static bool AlmostEqualTo(this double value1, double value2)
    {
        return Math.Abs(value1 - value2) < 0.0000001; 
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它

doubleValue.AlmostEqualTo(doubleValue2)
Run Code Online (Sandbox Code Playgroud)

  • 对于每个人都使用此扩展方法的大项目,此方法可能非常危险。想象一下 `value1.EqualDouble(value2) == true` 的情况,所以如果 `value1.EqualDouble(value3) == true` 也很容易假设 `value2.EqualDouble(value3) == true` - 但它不是在某些情况下。因此,建议至少将名称更改为内容更丰富的“CloseTo”示例 (8认同)