2016-11-17 291 views
4

我使用ReShaper,当我用==比较两个double值时,它表明我应该使用Math。具有公差的ABS方法。请参阅:https://www.jetbrains.com/help/resharper/2016.2/CompareOfFloatsByEqualityOperator.htmlC#将两个double与.Equals()进行比较

这个例子

double d = 0.0; 
double d2 = 0.0; 
if (d == d2) 
{ 
    /* some code */ 
} 

然后被转换到

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

但我认为这是非常复杂的开发者认为有关的权利的宽容。所以我认为这可以在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); 
} 

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

+1

为什么不使用十进制?如果(double1 mybirthname

+1

如果你觉得*开发人员很难获得宽容,那么* .NET框架*应该如何决定它,因为它知识少得多你认为是平等的。 – HimBromBeere

+0

@HimBromBeere我以为他们可能会使用double.Epsilon作为默认宽容或者这是一个坏主意? –

回答

3

您可以创建一个扩展方法

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

而且使用这样的

doubleValue.AlmostEqualTo(doubleValue2) 
+8

对于每个人都使用此扩展方法的大型项目,此方法可能非常危险。想象一下'value1.EqualDouble(value2)== true'的情况,那么如果'value1.EqualDouble(value3)== true',很容易假设'value2.EqualDouble(value3)== true' - 但它不是在某些情况下。因此,建议至少将名称更改为更具信息性的“关闭”范例 – Fabio