Search code examples
c#listcontainsfloating-accuracy

C# accuracy when checking float in List<float> with Contains method


I have a list of floats and want to check if it already contains a particular value with the List.Contains() method. I know that for float equality tests you often can't use == but something like myFloat - value < 0.001.

My question is, does the Contains method account for this or I do I need to use a method that accounts for float precision errors for testing if the float is in the list?


Solution

  • From the docs for 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).

    So you will need to handle comparison with a threshold yourself. For example, you can use your own custom equality comparer. Something like this:

    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");
        }
    }
    

    And use it:

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