Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Floating point comparison in STL, BOOST

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)

like image 938
fulmicoton Avatar asked May 14 '10 09:05

fulmicoton


People also ask

What is a better way to compare floating point values?

To compare two floating point values, we have to consider the precision in to the comparison. For example, if two numbers are 3.1428 and 3.1415, then they are same up to the precision 0.01, but after that, like 0.001 they are not same.

Are floats or doubles faster?

Floats are faster than doubles when you don't need double's precision and you are memory-bandwidth bound and your hardware doesn't carry a penalty on floats. They conserve memory-bandwidth because they occupy half the space per number. There are also platforms that can process more floats than doubles in parallel.

Are floats or doubles bigger?

We talked about three differences: byte size, precision, and usage. We also learned that doubles have twice the byte size of floats. Also, doubles are more accurate when dealing with large decimal values.

Are doubles or floats more precise?

double has 2x more precision than float. float is a 32-bit IEEE 754 single precision Floating Point Number – 1 bit for the sign, 8 bits for the exponent, and 23* for the value. float has 7 decimal digits of precision.


1 Answers

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.

like image 67
Matthieu M. Avatar answered Oct 11 '22 06:10

Matthieu M.