Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) AllAboutEqual

 

AllAboutEqual is a std::vector checking code snippet to check if all doubles in a std::vector are about equal.

 

 

#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>
#include <boost/numeric/conversion/cast.hpp>

///fuzzy_equal_to is a predicate to test two doubles for equality
///with a certain tolerance. A tolerance of 0.0 denotes that
///an exact match is requested. Note that the value of 0.0 cannot
///be compared fuzzily.
struct fuzzy_equal_to : public std::binary_function<double,double,bool>
{
  fuzzy_equal_to(const double tolerance = 0.01)
    : m_tolerance(tolerance)
  {
    assert(tolerance >= 0.0);
  }
  bool operator()(const double lhs, const double rhs) const
  {
    const double d = std::abs(m_tolerance * lhs);
    return rhs > lhs - d
        && rhs < lhs + d;
  }
  const double m_tolerance;
};

///AllAboutEqual tests if all values in a std::vector are about equal.
///From http://www.richelbilderbeek.nl/CppAllAboutEqual.htm
bool AllAboutEqual(
  const std::vector<double>& v,
  const double tolerance = 0.01)
{
  assert(!v.empty());
  return std::count_if(
    v.begin(),
    v.end(),
    std::bind2nd(fuzzy_equal_to(tolerance),v[0]))
    == boost::numeric_cast<int>(v.size());
}

int main()
{
  //C++11 initializer list
  assert( AllAboutEqual( {  0.999,  1.0,  1.001  } ));
  assert( AllAboutEqual( { -0.999, -1.0, -1.001  } ));
  assert(!AllAboutEqual( {  0.999, -1.0, -1.001  } ));
  assert(!AllAboutEqual( { -0.999,  1.0, -1.001  } ));
  assert(!AllAboutEqual( { -0.999, -1.0,  1.001  } ));
  assert(!AllAboutEqual( {  0.98 ,  1.0,  1.02   } ));
  assert(!AllAboutEqual( {  0.9  ,  1.0,  1.1    } ));
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict