30 #include <Base/Common/W32Compat.hh>
31 #include <Base/Debug/Error.hh>
32 #include <Base/Common/CompareFloatingPoint.hh>
43 enum ERelation { LESS, LESS_EQUAL, EQUAL, GREATER_EQUAL, GREATER };
45 ostream&
operator<<(ostream& os,
const enum ERelation& r)
48 case LESS: os <<
"<";
break;
49 case LESS_EQUAL: os <<
"<=";
break;
50 case EQUAL: os <<
"==";
break;
51 case GREATER: os <<
">";
break;
52 case GREATER_EQUAL: os <<
">=";
break;
63 TestValuePair(
const T l,
const ERelation rel,
const T r,
const T eps)
64 : left(l), right(r), epsilon(eps), relation(rel)
65 {
if (rel==LESS_EQUAL || rel==GREATER_EQUAL) { BIASABORT; } }
79 void GenTestValues(vector<TestValuePair<T> >& tv)
81 #if defined(max) || defined(min)
84 const T mini = numeric_limits<T>::min();
85 const T maxi = numeric_limits<T>::max();
87 # define max(a,b) ((a) >= (b) ? (a) : (b))
88 # define min(a,b) ((a) <= (b) ? (a) : (b))
90 const T mini = numeric_limits<T>::min();
91 const T maxi = numeric_limits<T>::max();
93 const T eps = numeric_limits<T>::epsilon();
96 tv.push_back(TestValuePair<T>(0.0, EQUAL, 0.0, 0.0));
97 tv.push_back(TestValuePair<T>(1.0, EQUAL, ((T)1.0)+eps, eps*((T)2.0)));
98 tv.push_back(TestValuePair<T>(mini, LESS, mini*((T)2.0), eps));
99 tv.push_back(TestValuePair<T>(mini, EQUAL, mini, eps));
100 tv.push_back(TestValuePair<T>(0.0, EQUAL, mini, mini*((T)2.0)));
101 tv.push_back(TestValuePair<T>(mini, EQUAL, 0.0, mini*((T)2)));
102 tv.push_back(TestValuePair<T>(((T)1e-10), EQUAL,
103 ((T)1e-10)+((T)1e-18), ((T)1e-7)));
104 tv.push_back(TestValuePair<T>(0.0, EQUAL, 0.0, mini));
105 tv.push_back(TestValuePair<T>(5.0, LESS, ((T)5.0)+eps*((T)10.0), eps));
106 tv.push_back(TestValuePair<T>(1.0, EQUAL, 1.0, eps));
107 tv.push_back(TestValuePair<T>(0.0, LESS, 1.0, eps));
108 tv.push_back(TestValuePair<T>(0.0, LESS, maxi, eps));
109 tv.push_back(TestValuePair<T>(maxi, GREATER, 0.0, eps));
110 tv.push_back(TestValuePair<T>(maxi, GREATER, 100.0, eps));
111 tv.push_back(TestValuePair<T>(maxi, GREATER, -maxi, eps));
112 tv.push_back(TestValuePair<T>(-maxi, LESS, maxi, eps));
116 void BuildMap(map<ERelation, map<ERelation, bool> >& m)
120 m[EQUAL][EQUAL] =
true;
121 m[EQUAL][LESS] =
false;
122 m[EQUAL][GREATER] =
false;
123 m[EQUAL][LESS_EQUAL] =
true;
124 m[EQUAL][GREATER_EQUAL] =
true;
126 m[LESS][EQUAL] =
false;
127 m[LESS][LESS] =
true;
128 m[LESS][GREATER] =
false;
129 m[LESS][LESS_EQUAL] =
true;
130 m[LESS][GREATER_EQUAL] =
false;
132 m[GREATER][EQUAL] =
false;
133 m[GREATER][LESS] =
false;
134 m[GREATER][GREATER] =
true;
135 m[GREATER][LESS_EQUAL] =
false;
136 m[GREATER][GREATER_EQUAL] =
true;
141 void Test(
const TestValuePair<T>& t)
143 if (t.relation==LESS_EQUAL || t.relation == GREATER_EQUAL){
144 BIASERR(
"true relation cannot be greater equal or less equal!");
149 static map<ERelation, map<ERelation, bool> > exp_res;
150 if (exp_res.empty()) BuildMap(exp_res);
152 const bool debug =
false;
153 if (debug) cout <<
"\nepsilon: "<<setprecision(30) << t.epsilon
154 <<
" true relation: "<< setprecision(30) <<t.left
155 <<
" "<<t.relation<<
" "<<setprecision(30) <<t.right<<endl;
157 res =
Equal(t.left, t.right, t.epsilon);
158 if (debug) cout <<
" "<<setprecision(30) << t.left <<
" == "<<setprecision(30)
159 << t.right <<
" = "<<boolalpha<<res<<endl;
160 if (res != exp_res[t.relation][EQUAL]) {
161 BIASERR(
"left: "<<t.left<<
" right: "<<t.right<<
" true relation: "
162 <<t.relation<<
" expected result: "<<boolalpha
163 <<exp_res[t.relation][EQUAL]
164 <<
" result: "<<boolalpha<<res<<endl);
165 cout <<
"fabs(left-right): "<<fabs(t.left-t.right)<<endl
166 <<
"eps * fabs(right): "<<t.epsilon * fabs(t.right)<<endl
167 <<
"eps * fabs(left): "<<t.epsilon * fabs(t.left)<<endl
168 <<
"right!=0.: "<<boolalpha<<(t.right!=0.) <<endl
169 <<
"left!=0.: "<<boolalpha<<(t.left!=0.) <<endl
170 <<
"right==0.: "<<boolalpha<<(t.right==0.) <<endl
171 <<
"left==0.: "<<boolalpha<<(t.left==0.) <<endl;
173 cout <<
"fabs(left-right) / fabs(right): "
174 <<fabs(t.left-t.right) / fabs(t.right)<<endl;
176 cout <<
"fabs(left-right) / fabs(left): "
177 <<fabs(t.left-t.right) / fabs(t.left)<<endl;
181 res =
Less(t.left, t.right, t.epsilon);
182 if (debug) cout <<
" "<<setprecision(30) << t.left <<
" < "<<setprecision(30)
183 << t.right <<
" = "<<boolalpha<<res<<endl;
184 if (res != exp_res[t.relation][LESS]) {
185 BIASERR(
"left: "<<t.left<<
" right: "<<t.right<<
" true relation: "
186 <<t.relation<<
" expected result: "<<boolalpha
187 <<exp_res[t.relation][LESS]
188 <<
" result: "<<boolalpha<<res<<endl);
193 res =
LessEqual(t.left, t.right, t.epsilon);
194 if (debug) cout <<
" "<<setprecision(30) << t.left <<
" <= "<<setprecision(30)
195 << t.right <<
" = "<<boolalpha<<res<<endl;
196 if (res != exp_res[t.relation][LESS_EQUAL]) {
197 BIASERR(
"left: "<<t.left<<
" right: "<<t.right<<
" true relation: "
198 <<t.relation<<
" expected result: "<<boolalpha
199 <<exp_res[t.relation][LESS_EQUAL]
200 <<
" result: "<<boolalpha<<res<<endl);
204 res =
Greater(t.left, t.right, t.epsilon);
205 if (debug) cout <<
" "<<setprecision(30) << t.left <<
" > "<<setprecision(30)
206 << t.right <<
" = "<<boolalpha<<res<<endl;
207 if (res != exp_res[t.relation][GREATER]) {
208 BIASERR(
"left: "<<t.left<<
" right: "<<t.right<<
" true relation: "
209 <<t.relation<<
" expected result: "<<boolalpha
210 <<exp_res[t.relation][GREATER]
211 <<
" result: "<<boolalpha<<res<<endl);
216 if (debug) cout <<
" "<<setprecision(30) << t.left <<
" >= "<<setprecision(30)
217 << t.right <<
" = "<<boolalpha<<res<<endl;
218 if (res != exp_res[t.relation][GREATER_EQUAL]) {
219 BIASERR(
"left: "<<t.left<<
" right: "<<t.right<<
" true relation: "
220 <<t.relation<<
" expected result: "<<boolalpha
221 <<exp_res[t.relation][GREATER_EQUAL]
222 <<
" result: "<<boolalpha<<res<<endl);
227 BIASASSERT(exp_res.size()==3u);
232 int main(
int argc,
char *argv[])
235 vector<TestValuePair<float> > tvf;
238 vector<TestValuePair<float> >::const_iterator itf;
239 for (itf=tvf.begin(); itf!=tvf.end(); itf++){
244 vector<TestValuePair<double> > tvd;
247 vector<TestValuePair<double> >::const_iterator itd;
248 for (itd=tvd.begin(); itd!=tvd.end(); itd++){
bool Less(const T left, const T right, const T eps=std::numeric_limits< T >::epsilon())
comparison function for floating point values
bool Greater(const T left, const T right, const T eps=std::numeric_limits< T >::epsilon())
comparison function for floating point values
bool GreaterEqual(const T left, const T right, const T eps=std::numeric_limits< T >::epsilon())
comparison function for floating point values
bool LessEqual(const T left, const T right, const T eps=std::numeric_limits< T >::epsilon())
comparison function for floating point values
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...