diff options
Diffstat (limited to 'thirdparty/linux/include/coin1/CoinFloatEqual.hpp')
-rw-r--r-- | thirdparty/linux/include/coin1/CoinFloatEqual.hpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/thirdparty/linux/include/coin1/CoinFloatEqual.hpp b/thirdparty/linux/include/coin1/CoinFloatEqual.hpp new file mode 100644 index 0000000..d5edfff --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinFloatEqual.hpp @@ -0,0 +1,177 @@ +/* $Id: CoinFloatEqual.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinFloatEqual_H +#define CoinFloatEqual_H + +#include <algorithm> +#include <cmath> + +#include "CoinFinite.hpp" + +/*! \file CoinFloatEqual.hpp + \brief Function objects for testing equality of real numbers. + + Two objects are provided; one tests for equality to an absolute tolerance, + one to a scaled tolerance. The tests will handle IEEE floating point, but + note that infinity == infinity. Mathematicians are rolling in their graves, + but this matches the behaviour for the common practice of using + <code>DBL_MAX</code> (<code>numeric_limits<double>::max()</code>, or similar + large finite number) as infinity. + + <p> + Example usage: + @verbatim + double d1 = 3.14159 ; + double d2 = d1 ; + double d3 = d1+.0001 ; + + CoinAbsFltEq eq1 ; + CoinAbsFltEq eq2(.001) ; + + assert( eq1(d1,d2) ) ; + assert( !eq1(d1,d3) ) ; + assert( eq2(d1,d3) ) ; + @endverbatim + CoinRelFltEq follows the same pattern. */ + +/*! \brief Equality to an absolute tolerance + + Operands are considered equal if their difference is within an epsilon ; + the test does not consider the relative magnitude of the operands. +*/ + +class CoinAbsFltEq +{ + public: + + //! Compare function + + inline bool operator() (const double f1, const double f2) const + + { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; + if (f1 == f2) return true ; + return (fabs(f1-f2) < epsilon_) ; } + + /*! \name Constructors and destructors */ + //@{ + + /*! \brief Default constructor + + Default tolerance is 1.0e-10. + */ + + CoinAbsFltEq () : epsilon_(1.e-10) {} + + //! Alternate constructor with epsilon as a parameter + + CoinAbsFltEq (const double epsilon) : epsilon_(epsilon) {} + + //! Destructor + + virtual ~CoinAbsFltEq () {} + + //! Copy constructor + + CoinAbsFltEq (const CoinAbsFltEq& src) : epsilon_(src.epsilon_) {} + + //! Assignment + + CoinAbsFltEq& operator= (const CoinAbsFltEq& rhs) + + { if (this != &rhs) epsilon_ = rhs.epsilon_ ; + return (*this) ; } + + //@} + + private: + + /*! \name Private member data */ + //@{ + + //! Equality tolerance. + + double epsilon_ ; + + //@} + +} ; + + + +/*! \brief Equality to a scaled tolerance + + Operands are considered equal if their difference is within a scaled + epsilon calculated as epsilon_*(1+CoinMax(|f1|,|f2|)). +*/ + +class CoinRelFltEq +{ + public: + + //! Compare function + + inline bool operator() (const double f1, const double f2) const + + { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; + if (f1 == f2) return true ; + if (!CoinFinite(f1) || !CoinFinite(f2)) return false ; + + double tol = (fabs(f1)>fabs(f2))?fabs(f1):fabs(f2) ; + + return (fabs(f1-f2) <= epsilon_*(1+tol)) ; } + + /*! \name Constructors and destructors */ + //@{ + +#ifndef COIN_FLOAT + /*! Default constructor + + Default tolerance is 1.0e-10. + */ + CoinRelFltEq () : epsilon_(1.e-10) {} +#else + /*! Default constructor + + Default tolerance is 1.0e-6. + */ + CoinRelFltEq () : epsilon_(1.e-6) {} ; // as float +#endif + + //! Alternate constructor with epsilon as a parameter + + CoinRelFltEq (const double epsilon) : epsilon_(epsilon) {} + + //! Destructor + + virtual ~CoinRelFltEq () {} + + //! Copy constructor + + CoinRelFltEq (const CoinRelFltEq & src) : epsilon_(src.epsilon_) {} + + //! Assignment + + CoinRelFltEq& operator= (const CoinRelFltEq& rhs) + + { if (this != &rhs) epsilon_ = rhs.epsilon_ ; + return (*this) ; } + + //@} + +private: + + /*! \name Private member data */ + //@{ + + //! Base equality tolerance + + double epsilon_ ; + + //@} + +} ; + +#endif |