C # precision when checking float in List <float> using the Contains method
I have a float
list and want to check if it already contains a specific value using the List.Contains()
method. I know that in float
equality tests you often cannot use ==
, but something like myFloat - value < 0.001
.
My question is, does the account use the Contains
method for this, or should I use a method that takes into account float
precision errors to check if the float is in the list?
From the docs for List(T).Contains
:
This method determines equality by default equality mapping, as defined by the implementation of the
IEquatable<T>.Equals
method object for T (the type of the values ββin the list).
So, you will need to handle the comparison with the threshold yourself. For example, you can use your own comparison mapper. Something like that:
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(xy) < _threshold; } public int GetHashCode(float f) { throw new NotImplementedException("Unable to generate a hash code for thresholds, do not use this for grouping"); } }
And use it:
var result = floatList.Contains(100f, new FloatComparer(0.01f))
It just uses the default equality comparison for the objects contained in the list. This will be the equivalent of calling object.Equals()
when doing comparisons.
If you need a different equality implementation, you can use the linq Contains()
overload, which accepts an equality resolver. Then you just need to implement this comparison and pass it on. This should do the same, but ultimately slower.
Other answers are correct, but if you want an alternative quick and dirty solution without writing a new equality mapping, you can use the List.Exists method:
bool found = list.Exists(num => Math.Abs(num - valueToFind) < 0.001);
Edit : My original answer said Linq was above, however the Exists method is part of the List class. The same concept using Linq is given below using IEnumerable.Any:
bool found = list.Any(num => Math.Abs(num - valueToFind) < 0.001);