00001 /* $Id: CoinFloatEqual.hpp 1215 2009-11-05 11:03:04Z forrest $ */ 00002 // Copyright (C) 2000, International Business Machines 00003 // Corporation and others. All Rights Reserved. 00004 #ifndef CoinFloatEqual_H 00005 #define CoinFloatEqual_H 00006 00007 #include <algorithm> 00008 # 00009 #include <cmath> 00010 00011 #include "CoinFinite.hpp" 00012 00045 class CoinAbsFltEq 00046 { 00047 public: 00048 00050 00051 inline bool operator() (const double f1, const double f2) const 00052 00053 { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; 00054 if (f1 == f2) return true ; 00055 return (fabs(f1-f2) < epsilon_) ; } 00056 00059 00061 00062 CoinAbsFltEq () : epsilon_(1.e-10) {} 00063 00065 00066 CoinAbsFltEq (const double epsilon) : epsilon_(epsilon) {} 00067 00069 00070 virtual ~CoinAbsFltEq () {} 00071 00073 00074 CoinAbsFltEq (const CoinAbsFltEq& src) : epsilon_(src.epsilon_) {} 00075 00077 00078 CoinAbsFltEq& operator= (const CoinAbsFltEq& rhs) 00079 00080 { if (this != &rhs) epsilon_ = rhs.epsilon_ ; 00081 return (*this) ; } 00082 00084 00085 private: 00086 00089 00091 00092 double epsilon_ ; 00093 00095 00096 } ; 00097 00098 00099 00106 class CoinRelFltEq 00107 { 00108 public: 00109 00111 00112 inline bool operator() (const double f1, const double f2) const 00113 00114 { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; 00115 if (f1 == f2) return true ; 00116 if (!CoinFinite(f1) || !CoinFinite(f2)) return false ; 00117 00118 double tol = (fabs(f1)>fabs(f2))?fabs(f1):fabs(f2) ; 00119 00120 return (fabs(f1-f2) <= epsilon_*(1+tol)) ; } 00121 00124 00126 00127 #ifndef COIN_FLOAT 00128 CoinRelFltEq () : epsilon_(1.e-10) {} 00129 #else 00130 CoinRelFltEq () : epsilon_(1.e-6) {} ; // as float 00131 #endif 00132 00134 00135 CoinRelFltEq (const double epsilon) : epsilon_(epsilon) {} 00136 00138 00139 virtual ~CoinRelFltEq () {} 00140 00142 00143 CoinRelFltEq (const CoinRelFltEq & src) : epsilon_(src.epsilon_) {} 00144 00146 00147 CoinRelFltEq& operator= (const CoinRelFltEq& rhs) 00148 00149 { if (this != &rhs) epsilon_ = rhs.epsilon_ ; 00150 return (*this) ; } 00151 00153 00154 private: 00155 00158 00160 00161 double epsilon_ ; 00162 00164 00165 } ; 00166 00167 #endif