使用 Contains 方法检查 List<float> 中的浮点数时的 C# 准确性
C# accuracy when checking float in List<float> with Contains method
我有一个 float
的列表,想用 List.Contains()
方法检查它是否已经包含特定值。我知道对于 float
等式测试,您通常不能使用 ==
,而是使用 myFloat - value < 0.001
.
之类的东西
我的问题是,Contains
方法是否说明了这一点,或者我是否需要使用说明 float
精度错误的方法来测试浮点数是否在列表中?
来自 List(T).Contains
的文档:
This method determines equality by using the default equality comparer, as defined by the object's implementation of the IEquatable<T>.Equals
method for T (the type of values in the list).
因此您需要自己处理与阈值的比较。例如,您可以使用自己的自定义相等比较器。像这样:
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))
它只是对列表中包含的对象使用默认的相等比较。这相当于在执行比较时调用 object.Equals()
。
如果您需要不同的相等性实现,您可以使用接受相等性比较器的 linq Contains()
重载。然后你只需要实现那个比较并将它传递进去。这应该执行大致相同但最终更慢。
其他答案是正确的,但如果您想要一个替代的快速解决方案而不编写新的相等比较器,您可以使用 List.Exists 方法:
bool found = list.Exists(num => Math.Abs(num - valueToFind) < 0.001);
编辑:
我原来的回答说上面是 Linq,但是 Exists 方法是列表 class 的一部分。下面是使用 Linq 的相同概念,使用 IEnumerable.Any:
bool found = list.Any(num => Math.Abs(num - valueToFind) < 0.001);
我有一个 float
的列表,想用 List.Contains()
方法检查它是否已经包含特定值。我知道对于 float
等式测试,您通常不能使用 ==
,而是使用 myFloat - value < 0.001
.
我的问题是,Contains
方法是否说明了这一点,或者我是否需要使用说明 float
精度错误的方法来测试浮点数是否在列表中?
来自 List(T).Contains
的文档:
This method determines equality by using the default equality comparer, as defined by the object's implementation of the
IEquatable<T>.Equals
method for T (the type of values in the list).
因此您需要自己处理与阈值的比较。例如,您可以使用自己的自定义相等比较器。像这样:
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))
它只是对列表中包含的对象使用默认的相等比较。这相当于在执行比较时调用 object.Equals()
。
如果您需要不同的相等性实现,您可以使用接受相等性比较器的 linq Contains()
重载。然后你只需要实现那个比较并将它传递进去。这应该执行大致相同但最终更慢。
其他答案是正确的,但如果您想要一个替代的快速解决方案而不编写新的相等比较器,您可以使用 List.Exists 方法:
bool found = list.Exists(num => Math.Abs(num - valueToFind) < 0.001);
编辑: 我原来的回答说上面是 Linq,但是 Exists 方法是列表 class 的一部分。下面是使用 Linq 的相同概念,使用 IEnumerable.Any:
bool found = list.Any(num => Math.Abs(num - valueToFind) < 0.001);