Search code examples
c++doublecomparisonprecision

C++ float comparison


I want to compare floats. I had a problem when comparing equality so I used epsilon and it was solved

inline bool isEqual(float x, float y)
{
  const float epsilon = 1e-5;
  return abs(x - y) <= epsilon * abs(x);
}

but I also want to compare other comparisons such as '>' and '<='

I have two floats = 49 but when executing f1 > f2 it returns true.

I have tried this function:

inline bool isSmallerOrEqual(float x, float y)
{
  const float epsilon = 0.01;
  return epsilon * abs(x) <= epsilon * abs(y);
}

It worked but not for all values. Any ideas ?


Solution

  • First, your isEquals function may be wrong, you're using the relative epsilon version. This version is works better with extremely large numbers, but breaks down when using extremely small numbers. The other version would be to use absolute epsilon. This version works well with small numbers (including extremely small numbers), but breaks down with extremely large numbers.

    inline bool epsilonEquals(const float x, const float y, const float epsilon = 1E-5f)
    {
        return abs(x - y) <= epsilon;
    }
    

    Second, calling it isEquals is inaccurate, the function is generally known as Epsilon Equals because it doesn't validate that 2 numbers are equal, it validates that they are reasonably close to each other within a small margin of error (epsilon).

    Third, if you want to check that 2 numbers are less than or equal to each other then you generally don't need or even want an epsilon equals function involved, doing so only increases the likelihood of false positive. If you do want to use epsilon comparison you can take advantage of paulmckenzie's method:

    inline bool epsilonLessThanOrEqualTo(const float x, const float y, const float epsilon = 1E-5f)
    {
        return x <= y || epsilonEquals(x, y, epsilon);
    }
    

    If you want to have an epsilon not-equals method you can simply check that the absolute difference between the 2 numbers is larger than epsilon.