9

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)

Donal Fellows
  • 120,022
  • 18
  • 134
  • 199
fulmicoton
  • 13,826
  • 7
  • 50
  • 71
  • 1
    Why would you use an epsilon for comparing greater or less? – AshleysBrain May 14 '10 at 09:47
  • 3
    The only time when a epsilon comparison is need for floating point or double types is for the equality '==' comparison. greater or less do not really have any meaning with epsilon, because what do you expect the answer to be when they are equal? if greater or lesser are both defined in the way you mention, then in the case when they are equal, you will get ab = true and a==b = true, which is incorrect. The correct behaviour is that iff a==b then a>b = false, and a – Akanksh May 14 '10 at 09:55
  • 5
    @Akanksh, The implementation above may not be right, but epsilon-based inequalities are meaningful and important for precisely the scenario you highlight. If two numbers are equal according to an epsilon-based `==` test, then you also need a ` – Marcelo Cantos May 14 '10 at 10:00
  • 1
    I sometimes need to keep coherence between order relationship and equality. I am not to sure about implementation though. Anyway I changed my question to equality and I'm still waiting for an answer. – fulmicoton May 14 '10 at 11:39
  • 1
    Hope is not to late, but here is a post with some floating-point comparison algorithms, as shown in The Art of Computer Programming... http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison/253874#253874 – YuppieNetworking May 14 '10 at 14:01
  • Floating-point comparisons can get you in hot water quickly. Please note that is_equal(a,b) and is_equal(a,c) does not mean is_equal(b,c). For Paul, this means that you can't used an epsilon-based comparison for ordering. When (a – MSalters May 14 '10 at 14:15
  • @MSalters Good point, we lose transitivity. @YuppieNetworking Thanks a bunch. Knuth is everywhere. – fulmicoton May 14 '10 at 14:49

3 Answers3

10

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.
  • 251,718
  • 39
  • 369
  • 642
1

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

Cătălin Pitiș
  • 13,509
  • 2
  • 37
  • 61
0

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
  • 7,738
  • 2
  • 24
  • 15
  • 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>x) or (x>y) ) Is there some performance issue? – fulmicoton May 14 '10 at 11:42
  • It's not. In general you define ` – Matthieu M. May 14 '10 at 12:22