Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / ETL / tags / stable / 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 ** Copyright (c) 2007 Chris Moore
8 **
9 ** This package is free software; you can redistribute it and/or
10 ** modify it under the terms of the GNU General Public License as
11 ** published by the Free Software Foundation; either version 2 of
12 ** the License, or (at your option) any later version.
13 **
14 ** This package is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ** General Public License for more details.
18 **
19 ** === N O T E S ===========================================================
20 **
21 ** ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #define ETL_FIXED_BITS          12
26
27 #include <ETL/fixed>
28 #include <stdio.h>
29 #include <ETL/clock>
30
31 /* === M A C R O S ========================================================= */
32
33 #ifndef PI
34 # define PI (3.1415926535897932384626433832795029L)
35 #endif
36
37 #define ADD_SUB_TEST    20000000
38 #define MUL_TEST                10000000
39 #define DIV_TEST                1048573 // at 1048573, fixed point numbers wrap around to zero
40 using namespace etl;
41
42 /* === C L A S S E S ======================================================= */
43
44 template <class value_type>
45 struct speed_test
46 {
47         double add_sub_test(void)
48         {
49                 value_type a=1;
50                 value_type b=2;
51                 value_type c=3;
52                 int i;
53                 etl::clock MyTimer;
54                 MyTimer.reset();
55                 for(i=0;i<ADD_SUB_TEST;i++)
56                 {
57                         a+=a; a-=b; a-=c; a+=a;
58                         a+=a; a-=b; a-=c; a+=a;
59                         a+=a; a-=b; a-=c; a+=a;
60                         a+=a; a-=b; a-=c; a+=a;
61                         a+=a; a-=b; a-=c; a+=a;
62                         a+=a; a-=b; a-=c; a+=a;
63                         a+=a; a-=b; a-=c; a+=a;
64                 }
65
66                 fprintf(stderr, "[%1d]...", int(int(a)/1e9)+5); // so the compiler doesn't optimize everything out
67                 return MyTimer();
68         }
69
70         double mul_test(void)
71         {
72                 value_type a,b,c,d;
73                 a=value_type(2.25);
74                 b=value_type(2);
75                 c=value_type(4.5);
76                 d=value_type(1);
77                 const value_type one_and_a_half(static_cast<value_type>(1.5));
78                 int i;
79                 etl::clock MyTimer;
80                 MyTimer.reset();
81                 for(i=1;i<MUL_TEST;i++)
82                 {
83                         d*=a;d*=b;d*=c;d*=3;d*=i; b*=c;b*=d;b*=d;b*=3; c*=d;c*=one_and_a_half;c*=a;c*=b;c*=3; a*=c;a*=b;a*=3;
84                         d*=a;d*=b;d*=c;d*=3;d*=i; b*=c;b*=d;b*=d;b*=3; c*=d;c*=one_and_a_half;c*=a;c*=b;c*=3; a*=c;a*=b;a*=3;
85                         d*=a;d*=b;d*=c;d*=3;d*=i; b*=c;b*=d;b*=d;b*=3; c*=d;c*=one_and_a_half;c*=a;c*=b;c*=3; a*=c;a*=b;a*=3;
86                         d*=a;d*=b;d*=c;d*=3;d*=i; b*=c;b*=d;b*=d;b*=3; c*=d;c*=one_and_a_half;c*=a;c*=b;c*=3; a*=c;a*=b;a*=3;
87                         d*=a;d*=b;d*=c;d*=3;d*=i; b*=c;b*=d;b*=d;b*=3; c*=d;c*=one_and_a_half;c*=a;c*=b;c*=3; a*=c;a*=b;a*=3;
88                         d*=a;d*=b;d*=c;d*=3;d*=i; b*=c;b*=d;b*=d;b*=3; c*=d;c*=one_and_a_half;c*=a;c*=b;c*=3; a*=c;a*=b;a*=3;
89                         d*=a;d*=b;d*=c;d*=3;d*=i; b*=c;b*=d;b*=d;b*=3; c*=d;c*=one_and_a_half;c*=a;c*=b;c*=3; a*=c;a*=b;a*=3;
90                 }
91
92                 fprintf(stderr, "[%1d]...", int(int(a)/1e9)+5); // so the compiler doesn't optimize everything out
93                 return MyTimer();
94         }
95
96         double div_test(void)
97         {
98                 value_type a(30);
99                 value_type b(40);
100                 value_type acc(0);
101                 int i, j;
102                 etl::clock MyTimer;
103                 MyTimer.reset();
104                 for(j=0;j<10;j++)
105                         for(i=1;i<DIV_TEST;i++)
106                         {
107                                 a=3+i; b=40+i; b/=a; a/=(i%20)+1; acc+= a;
108                                 a=3+i; b=40+i; b/=a; a/=(i%20)+1; acc+= a;
109                                 a=3+i; b=40+i; b/=a; a/=(i%20)+1; acc+= a;
110                                 a=3+i; b=40+i; b/=a; a/=(i%20)+1; acc+= a;
111                                 a=3+i; b=40+i; b/=a; a/=(i%20)+1; acc+= a;
112                                 a=3+i; b=40+i; b/=a; a/=(i%20)+1; acc+= a;
113                         }
114
115                 fprintf(stderr, "[%1d]...", int(int(acc)/1e9)+5); // so the compiler doesn't optimize everything out
116                 return MyTimer();
117         }
118 };
119
120 /* === P R O C E D U R E S ================================================= */
121
122 int basic_test(void)
123 {
124         int ret=0;
125
126         fixed a,b,c;
127         double d;
128
129         a=-1;
130         a=std::abs(a);
131         if(a!=fixed(1))
132         {
133                 fprintf(stderr,"fixed: abs() failure on line %d in "__FILE__".\n",__LINE__);
134                 ret++;
135         }
136
137         d=(double)(fixed(2.5)*fixed(3.0f)/7)-(2.5f*3.0f/7.0f);
138         fprintf(stderr,"fixed: 2.5 * 2 / 7 --- Difference: %f\n",d);
139         if(d<0.0)d=-d;
140         if( d>0.0005)
141         {
142                 fprintf(stderr,"fixed: Failed test on line %d in "__FILE__".\n",__LINE__);
143                 ret++;
144         }
145
146         a=1043;d=1043;
147         a/=27;d/=27;
148         a+=10.42;d+=10.42;
149         a/=6;d/=6;
150         a*=PI;d*=PI;
151         d-=(double)a;
152         fprintf(stderr,"fixed: ( 1043 / 27 + 10.42 ) / 6 * PI --- Difference: %f\n",d);
153         if(d<0.0)d=-d;
154 #ifdef ROUND_TO_NEAREST_INTEGER
155         if( d>0.0005)
156 #else
157         if( d>0.0025)
158 #endif
159         {
160                 fprintf(stderr,"fixed: Failed test on line %d in "__FILE__".\n",__LINE__);
161                 ret++;
162         }
163
164         return ret;
165 }
166
167 int char_test(void)
168 {
169         int ret=0;
170
171         fixed_base<unsigned char,8> fix;
172         double flt;
173
174         if(sizeof(fix)!=sizeof(unsigned char))
175         {
176                 ret++;
177                 fprintf(stderr,"fixed: Size of fixed_base<unsigned char,8> is wrong!\n");
178         }
179
180         flt=1.0;
181         fix=1.0;
182         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
183
184         flt*=0.7;
185         fix*=0.7;
186         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
187
188         flt*=0.7;
189         fix*=0.7;
190         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
191
192         flt*=0.7;
193         fix*=0.7;
194         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
195
196         flt*=0.7;
197         fix*=0.7;
198         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
199
200         flt*=0.7;
201         fix*=0.7;
202         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
203
204         //flt/=0.7;
205         //fix/=0.7;
206         //fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
207
208         flt+=0.3;
209         fix+=0.3;
210         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
211
212         flt*=2;
213         fix*=2;
214         fprintf(stderr,"fixed: value=%f, data=%d, shouldbe=%f, error=%f\n",(float)fix,fix.data(),flt,(float)fix-flt);
215
216
217         return ret;
218 }
219
220 /* === E N T R Y P O I N T ================================================= */
221
222 int main()
223 {
224         int error=0;
225
226         error+=basic_test();
227         error+=char_test();
228
229         speed_test<float> float_test;
230         speed_test<int> int_test;
231         speed_test<fixed> fixed_test;
232
233         {
234                 double flt,fix,inte;
235                 fprintf(stderr,"\nAddition/subtraction test...\n");
236
237                 fprintf(stderr,"  calculating float.....");
238                 flt=float_test.add_sub_test();
239                 fprintf(stderr,"   float time: %f sec\n",flt);
240
241                 fprintf(stderr,"  calculating fixed.....");
242                 fix=fixed_test.add_sub_test();
243                 fprintf(stderr,"   fixed time: %f sec\n",fix);
244
245                 fprintf(stderr,"  calculating integer...");
246                 inte=int_test.add_sub_test();
247                 fprintf(stderr," integer time: %f sec\n",inte);
248
249                 if(flt>fix)
250                         fprintf(stderr,"Fixed point wins by %f seconds! (%f%% faster)\n",flt-fix,flt/fix*100.0f-100.0f);
251                 else
252                         fprintf(stderr,"Floating point wins by %f seconds! (%f%% faster)\n",fix-flt,fix/flt*100.0f-100.0f);
253
254         }
255
256         {
257                 double flt,fix,inte;
258                 fprintf(stderr,"\nProduct test...\n");
259                 fprintf(stderr,"  calculating float.....");
260                 flt=float_test.mul_test();
261                 fprintf(stderr,"   float time: %f sec\n",flt);
262                 fprintf(stderr,"  calculating fixed.....");
263                 fix=fixed_test.mul_test();
264                 fprintf(stderr,"   fixed time: %f sec\n",fix);
265                 fprintf(stderr,"  calculating integer...");
266                 inte=int_test.mul_test();
267                 fprintf(stderr," integer time: %f sec\n",inte);
268                 if(flt>fix)
269                         fprintf(stderr,"Fixed point wins by %f seconds! (%f%% faster)\n",flt-fix,flt/fix*100.0f-100.0f);
270                 else
271                         fprintf(stderr,"Floating point wins by %f seconds! (%f%% faster)\n",fix-flt,fix/flt*100.0f-100.0f);
272         }
273
274         {
275                 double flt,fix,inte;
276                 fprintf(stderr,"\nDivision test...\n");
277                 fprintf(stderr,"  calculating float.....");
278                 flt=float_test.div_test();
279                 fprintf(stderr,"   float time: %f sec\n",flt);
280                 fprintf(stderr,"  calculating fixed.....");
281                 fix=fixed_test.div_test();
282                 fprintf(stderr,"   fixed time: %f sec\n",fix);
283                 fprintf(stderr,"  calculating integer...");
284                 inte=int_test.div_test();
285                 fprintf(stderr," integer time: %f sec\n",inte);
286                 if(flt>fix)
287                         fprintf(stderr,"Fixed point wins by %f seconds! (%f%% faster)\n",flt-fix,flt/fix*100.0f-100.0f);
288                 else
289                         fprintf(stderr,"Floating point wins by %f seconds! (%f%% faster)\n",fix-flt,fix/flt*100.0f-100.0f);
290                 fprintf(stderr,"\n");
291         }
292
293         return error;
294 }