Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / ETL / tags / ETL_0_04_10_rc2 / test / fixed.cpp
1 /*! ========================================================================
2 ** Extended Template and Library Test Suite
3 ** Fixed-Point Math Test
4 ** $Id$
5 **
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 **
8 ** This package is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License as
10 ** published by the Free Software Foundation; either version 2 of
11 ** the License, or (at your option) any later version.
12 **
13 ** This package is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ** General Public License for more details.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #define ETL_FIXED_BITS          12
25
26 #include <ETL/fixed>
27 #include <stdio.h>
28 #include <ETL/clock>
29
30 /* === M A C R O S ========================================================= */
31
32 #ifndef PI
33 # define PI (3.1415926535897932384626433832795029L)
34 #endif
35
36 #define ADD_SUB_TEST    20000000
37 #define MUL_TEST                10000000
38 #define DIV_TEST                10000000
39 using namespace etl;
40
41 /* === C L A S S E S ======================================================= */
42
43 template <class value_type>
44 struct speed_test
45 {
46         double add_sub_test(void)
47         {
48                 value_type a=1;
49                 value_type b=2;
50                 value_type c=3;
51                 int i;
52                 etl::clock MyTimer;
53                 MyTimer.reset();
54                 for(i=0;i<ADD_SUB_TEST;i++)
55                 {
56                         a+=a;
57                         a+=b;
58                         a-=c;
59                         a-=a;
60
61                         a+=a;
62                         a+=b;
63                         a-=c;
64                         a-=a;
65
66                         a+=a;
67                         a+=b;
68                         a-=c;
69                         a-=a;
70
71                         a+=a;
72                         a+=b;
73                         a-=c;
74                         a-=a;
75
76                         a+=a;
77                         a+=b;
78                         a-=c;
79                         a-=a;
80
81                         a+=a;
82                         a+=b;
83                         a-=c;
84                         a-=a;
85
86                         a+=a;
87                         a+=b;
88                         a-=c;
89                         a-=a;
90
91                 }
92
93
94                 return MyTimer();
95         }
96
97         double mul_test(void)
98         {
99                 value_type a,b,c,d;
100                 a=value_type(0.25);
101                 b=value_type(2);
102                 c=value_type(4.5);
103                 const value_type half(static_cast<value_type>(0.5));
104                 int i;
105                 etl::clock MyTimer;
106                 MyTimer.reset();
107                 for(i=0;i<MUL_TEST;i++)
108                 {
109                         d*=a;d*=b;d*=c;d*=3;d*=i;
110                         b*=c;b*=d;b*=d;b*=3;
111                         c*=d;c*=half;c*=a;c*=b;c*=3;
112                         a*=c;a*=b;a*=3;
113
114                         d*=a;d*=b;d*=c;d*=3;d*=i;
115                         b*=c;b*=d;b*=d;b*=3;
116                         c*=d;c*=half;c*=a;c*=b;c*=3;
117                         a*=c;a*=b;a*=3;
118
119                         d*=a;d*=b;d*=c;d*=3;d*=i;
120                         b*=c;b*=d;b*=d;b*=3;
121                         c*=d;c*=half;c*=a;c*=b;c*=3;
122                         a*=c;a*=b;a*=3;
123
124                         d*=a;d*=b;d*=c;d*=3;d*=i;
125                         b*=c;b*=d;b*=d;b*=3;
126                         c*=d;c*=half;c*=a;c*=b;c*=3;
127                         a*=c;a*=b;a*=3;
128
129                         d*=a;d*=b;d*=c;d*=3;d*=i;
130                         b*=c;b*=d;b*=d;b*=3;
131                         c*=d;c*=half;c*=a;c*=b;c*=3;
132                         a*=c;a*=b;a*=3;
133
134                         d*=a;d*=b;d*=c;d*=3;d*=i;
135                         b*=c;b*=d;b*=d;b*=3;
136                         c*=d;c*=half;c*=a;c*=b;c*=3;
137                         a*=c;a*=b;a*=3;
138
139                         d*=a;d*=b;d*=c;d*=3;d*=i;
140                         b*=c;b*=d;b*=d;b*=3;
141                         c*=d;c*=half;c*=a;c*=b;c*=3;
142                         a*=c;a*=b;a*=3;
143
144                 }
145                 return MyTimer();
146         }
147
148         double div_test(void)
149         {
150                 value_type a(30);
151                 value_type b(40);
152                 int i;
153                 etl::clock MyTimer;
154                 MyTimer.reset();
155                 for(i=1;i<DIV_TEST;i++)
156                 {
157                         a=3+i;
158                         b=40+i;
159                         b/=a;
160                         a/=(i%20)+1;
161
162                         a=3+i;
163                         b=40+i;
164                         b/=a;
165                         a/=(i%20)+1;
166
167                         a=3+i;
168                         b=40+i;
169                         b/=a;
170                         a/=(i%20)+1;
171
172                         a=3+i;
173                         b=40+i;
174                         b/=a;
175                         a/=(i%20)+1;
176
177                         a=3+i;
178                         b=40+i;
179                         b/=a;
180                         a/=(i%20)+1;
181
182                         a=3+i;
183                         b=40+i;
184                         b/=a;
185                         a/=(i%20)+1;
186
187                 }
188
189
190                 return MyTimer();
191         }
192 };
193
194 /* === P R O C E D U R E S ================================================= */
195
196 int basic_test(void)
197 {
198         int ret=0;
199
200         fixed a,b,c;
201         double d;
202
203         a=-1;
204         a=std::abs(a);
205         if(a!=fixed(1))
206         {
207                 fprintf(stderr,"fixed: abs() failure on line %d in "__FILE__".\n",__LINE__);
208                 ret++;
209         }
210
211         d=(double)(fixed(2.5)*fixed(3.0f)/7)-(2.5f*3.0f/7.0f);
212         fprintf(stderr,"fixed: 2.5 * 2 / 7 --- Difference: %f\n",d);
213         if(d<0.0)d=-d;
214         if( d>0.0005)
215         {
216                 fprintf(stderr,"fixed: Failed test on line %d in "__FILE__".\n",__LINE__);
217                 ret++;
218         }
219
220         a=1043;d=1043;
221         a/=27;d/=27;
222         a+=10.42;d+=10.42;
223         a/=6;d/=6;
224         a*=PI;d*=PI;
225         d-=(double)a;
226         fprintf(stderr,"fixed: ( 1043 / 27 + 10.42 ) / 6 * PI --- Difference: %f\n",d);
227         if(d<0.0)d=-d;
228         if( d>0.0005)
229         {
230                 fprintf(stderr,"fixed: Failed test on line %d in "__FILE__".\n",__LINE__);
231                 ret++;
232         }
233
234         return ret;
235 }
236
237 int char_test(void)
238 {
239         int ret=0;
240
241         fixed_base<unsigned char,8> fix;
242         double flt;
243
244         if(sizeof(fix)!=sizeof(unsigned char))
245         {
246                 ret++;
247                 fprintf(stderr,"fixed: Size of fixed_base<unsigned char,8> is wrong!\n");
248         }
249
250         flt=1.0;
251         fix=1.0;
252         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
253
254         flt*=0.7;
255         fix*=0.7;
256         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
257
258         flt*=0.7;
259         fix*=0.7;
260         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
261
262         flt*=0.7;
263         fix*=0.7;
264         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
265
266         flt*=0.7;
267         fix*=0.7;
268         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
269
270         flt*=0.7;
271         fix*=0.7;
272         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
273
274         //flt/=0.7;
275         //fix/=0.7;
276         //fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
277
278         flt+=0.3;
279         fix+=0.3;
280         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
281
282         flt*=2;
283         fix*=2;
284         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
285
286
287         return ret;
288 }
289
290 /* === E N T R Y P O I N T ================================================= */
291
292 int main()
293 {
294         int error=0;
295
296         error+=basic_test();
297         error+=char_test();
298
299         speed_test<float> float_test;
300         speed_test<int> int_test;
301         speed_test<fixed> fixed_test;
302
303         {
304                 double flt,fix,inte;
305                 fprintf(stderr,"Addition/subtraction test...");
306
307                 fprintf(stderr,"calculating float...");
308                 flt=float_test.add_sub_test();
309                 fprintf(stderr,"float time: %fsec\n",flt);
310
311                 fprintf(stderr,"calculating fixed...");
312                 fix=fixed_test.add_sub_test();
313                 fprintf(stderr,"fixed time: %fsec\n",fix);
314
315                 fprintf(stderr,"calculating integer...");
316                 inte=int_test.add_sub_test();
317                 fprintf(stderr,"integer time: %fsec\n",inte);
318
319                 if(flt>fix)
320                         fprintf(stderr,"Fixed point wins by %f seconds! (%f%% faster)\n",flt-fix,flt/fix*100.0f-100.0f);
321                 else
322                         fprintf(stderr,"Floating point wins by %f seconds! (%f%% faster)\n",fix-flt,fix/flt*100.0f-100.0f);
323
324         }
325
326         {
327                 double flt,fix,inte;
328                 fprintf(stderr,"Product test...");
329                 fprintf(stderr,"calculating float...");
330                 flt=float_test.mul_test();
331                 fprintf(stderr,"float time: %fsec\n",flt);
332                 fprintf(stderr,"calculating fixed...");
333                 fix=fixed_test.mul_test();
334                 fprintf(stderr,"fixed time: %fsec\n",fix);
335                 fprintf(stderr,"calculating integer...");
336                 inte=int_test.mul_test();
337                 fprintf(stderr,"integer time: %fsec\n",inte);
338                 if(flt>fix)
339                         fprintf(stderr,"Fixed point wins by %f seconds! (%f%% faster)\n",flt-fix,flt/fix*100.0f-100.0f);
340                 else
341                         fprintf(stderr,"Floating point wins by %f seconds! (%f%% faster)\n",fix-flt,fix/flt*100.0f-100.0f);
342
343         }
344
345         {
346                 double flt,fix,inte;
347                 fprintf(stderr,"Division test...");
348                 fprintf(stderr,"calculating float...");
349                 flt=float_test.div_test();
350                 fprintf(stderr,"float time: %fsec\n",flt);
351                 fprintf(stderr,"calculating fixed...");
352                 fix=fixed_test.div_test();
353                 fprintf(stderr,"fixed time: %fsec\n",fix);
354                 fprintf(stderr,"calculating integer...");
355                 inte=int_test.div_test();
356                 fprintf(stderr,"integer time: %fsec\n",inte);
357                 if(flt>fix)
358                         fprintf(stderr,"Fixed point wins by %f seconds! (%f%% faster)\n",flt-fix,flt/fix*100.0f-100.0f);
359                 else
360                         fprintf(stderr,"Floating point wins by %f seconds! (%f%% faster)\n",fix-flt,fix/flt*100.0f-100.0f);
361
362         }
363
364         return error;
365 }