使用Contains方法检查List <float>中的float时的C#精度

时间:2017-03-08 00:37:33

标签: c# list contains floating-accuracy

我有一个float列表,想要检查它是否已包含List.Contains()方法的特定值。我知道,对于float平等测试,您通常无法使用==,但需要myFloat - value < 0.001

我的问题是,Contains方法是否考虑到这个或我需要使用一个方法来解释float精度错误,以便测试浮点数是否在列表中?

3 个答案:

答案 0 :(得分:8)

来自https://code.google.com/p/android/issues/detail?id=233942的文档:

  

此方法通过使用默认的相等比较器来确定相等性,由对象的T List(T).Contains方法的实现(列表中的值类型)定义。

因此,您需要自己处理与阈值的比较。例如,您可以使用自己的自定义相等比较器。像这样:

public class FloatThresholdComparer : IEqualityComparer<float>
{
    private readonly float _threshold;
    public FloatThresholdComparer(float threshold)
    {
        _threshold = threshold;
    }

    public bool Equals(float x, float y)
    {
        return Math.Abs(x-y) < _threshold;
    }

    public int GetHashCode(float f)
    {
        throw new NotImplementedException("Unable to generate a hash code for thresholds, do not use this for grouping");
    }
}

并使用它:

var result = floatList.Contains(100f, new FloatThresholdComparer(0.01f))

答案 1 :(得分:2)

它只使用列表中包含的对象的默认相等比较。这相当于在执行比较时调用object.Equals()

如果需要不同的相等实现,可以使用接受相等比较器的linq Contains()重载。然后你只需要实现那个比较并传递它。这应该执行大致相同但最终更慢。

答案 2 :(得分:1)

其他答案是正确的,但是如果你想要一个替代的快速解决方案而不编写新的相等比较器,你可以使用List.Exists方法:

bool found = list.Exists(num => Math.Abs(num - valueToFind) < 0.001);

修改:     我的原始答案说上面是Linq,但是Exists方法是List类的一部分。使用Linq的相同概念如下,使用IEnumerable.Any:

bool found = list.Any(num => Math.Abs(num - valueToFind) < 0.001);