views:

291

answers:

3

Is there in the STL or in Boost a set of generic simple comparison functions?

The one I found are always requiring template parameters, and/or instantiation of a struct template.

I'm looking for something with a syntax like :

if ( is_equal(x,y) )
{
   ...
}

Which could be implemented as :

template <typename T>
bool is_equal(const T& x, const T& y)
{
    return ( fabs(x - y) < Precision<T>::eps );
}

EDIT: I changed the operator to equal. (see comments below)

A: 

From the comment of Marcelo Cantos:

...then you also need a < test that returns false, even if the first number is ever-so-slightly smaller than the second.

I would imagine the implementation would be:

return !roughly_equal(a, b) && a < b;
visitor
That's not answering my question.Anyway why is it better to implement greater and less from equal by opposition to defining greater and then defining less and equal via?x<y <=> y<xx==y <=> ! ( (y>x) or (x>y) )Is there some performance issue?
poulejapon
It's not. In general you define `<` and `==` separately even though `==` could be derived (in theory) from `<` because of performance. What is important is to preserve the logical relationship though...
Matthieu M.
+1  A: 

You could find some reasons of "complex" comparation logic here, in the documentation of boost test library.

Cătălin Pitiș
+1  A: 

I don't know of any library that does it, perhaps because it is as simple as a one-liner or perhaps because it was forgotten...

As generality goes though, are you sure you'd like to set up the epsilon for one given type at a given value... throughout the application ? Personally I'd like to customize it depending on the operations I am doing (even though a default would be nice).

As for your operators, why not devising them yourself ?

template <class T>
bool rough_eq(T lhs, T rhs, T epsilon = Precision<T>::epsilon) // operator==
{ 
  return fabs(lhs - rhs) < epsilon;
}

template <class T>
bool rough_lt(T lhs, T rhs, T epsilon = Precision<T>::epsilon) // operator<
{
  return rhs - lhs >= epsilon;
       // tricky >= because if the difference is equal to epsilon
       // then they are not equal per the rough_eq method
}

template <class T>
bool rough_lte(T lhs, T rhs, T epsilon = Precision<T>::epsilon) // operator<=
{
  return rhs - lhs > -epsilon;
}

The inequality and greater than methods can be trivially derived from this.

The additional parameter means that you may wish to specify another value for a given set of computations... an application-wide setting is too strict.

Matthieu M.
roughlte can also be derived viaa<=b <=> !(a>b) <=> !(b<a)
poulejapon
Yes, I just wanted to show the difference in comparing with epsilon :)
Matthieu M.