不检查浮点平等/不等式

时间:2016-11-04 10:20:20

标签: c#

我们正在使用一个代码分析器,它具有这样的规则"不检查浮点数等式/不等式" .Below是给出的示例。

float f = 0.100000001f; // 0.1
double d = 0.10000000000000001; // 0.1



  float myNumber = 3.146f;
    if ( myNumber == 3.146f ) //Noncompliant. Because of floating point imprecision, this will be false
    {
      ////
     }
    else
      {
        ////
      }

    if (myNumber <= 3.146f && mNumber >= 3.146f) // Noncompliant indirect equality test
    {
      // ...
    }

    if (myNumber < 4 || myNumber > 4) // Noncompliant indirect inequality test
    {
      // ...
    }

当我测试此代码时,如果(myNumber == 3.146f)为真,那么我无法理解这条规则试图说的是什么。

此规则所需的解决方案或代码更改是什么?

此规则适用于C#吗?当我用Google搜索时,我会看到更多关于此规则的C / C ++示例

2 个答案:

答案 0 :(得分:2)

浮点不准确。在某些情况下,结果是意外的,因此将浮点数等同于没有一些容差的相等性是不好的做法。

可以用简单的例子来证明。

if(0.1 + 0.2 == 0.3)
{
    Console.WriteLine("Equal");
}
else
{
    Console.WriteLine("Not Equal");
}

它会打印Not Equal

演示:https://dotnetfiddle.net/ltAFWe

解决方案是添加一些容差,例如:

if(Math.Abs((0.1 + 0.2) - 0.3) < 0.0001)
{
    Console.WriteLine("Equal");
}
else
{
    Console.WriteLine("Not Equal");
}

现在它将打印Equal

答案 1 :(得分:2)

一个相当可读的解决方案是为double定义一个扩展方法,如下所示:

public static class FloatAndDoubleExt
{
    public static bool IsApproximately(this double self, double other, double within)
    {
        return Math.Abs(self - other) <= within;
    }

    public static bool IsApproximately(this float self, float other, float within)
    {
        return Math.Abs(self - other) <= within;
    }
}

然后像这样使用它:

float myNumber = 3.146f;

if (myNumber.IsApproximately(3.146f, within:0.001f))
{
    ////
}
else
{
    ////
}

另请参阅the documentation for Double.Equals()了解详情。