]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/misc/AliL3FFloat.cxx
New version of SPD raw-data reconstruction. The format now correponds to the actual...
[u/mrichter/AliRoot.git] / HLT / misc / AliL3FFloat.cxx
1 // @(#) $Id$
2
3 // Author: Constantin Loizides <mailto:loizides@fi.uib.no>
4 //*-- Copyright & copy ALICE HLT Group
5
6 #ifdef USEFFLOAT
7
8 #include "AliL3StandardIncludes.h"
9
10 #include "AliL3Logging.h"
11 #include "AliL3Logger.h"
12
13 //calculate statistics according to usage and
14 //difference to floating point results
15 #define CALCSTATS
16
17 //use cast to int instead of sprintf and atoi
18 //#define FASTWITHROUNDINGERROS
19
20 #include "AliL3FFloat.h"
21
22 /** \class AliL3FFloat
23 <pre>
24 //----------------------------------------------------
25 // AliL3FFloat
26 //
27 // Fixed Floating Point class for debugging purposes.
28 //
29 // The class behaves like a normal Double_t class but
30 // calculates everything in respect to fDigits (eg. 
31 // fDigits=100 -> 2 digits behind the comma). Further-
32 // more it keeps the exact value in floating precision
33 // and gathers some statistical information about 
34 // its usage.
35 </pre>
36 */
37
38 ClassImp(AliL3FFloat)
39
40 Int_t AliL3FFloat::fDigits = DEFDIG;
41 Int_t AliL3FFloat::fMax    = DEFMAX;
42 Int_t AliL3FFloat::fMin    = DEFMIN;
43
44 #ifdef CALCSTATS
45 Int_t AliL3FFloat::fN          = 0;
46 Int_t AliL3FFloat::fNRounded   = 0;
47 Int_t AliL3FFloat::fNOpAdds    = 0;
48 Int_t AliL3FFloat::fNOpMults   = 0;
49 Int_t AliL3FFloat::fNOpDivs    = 0;
50 Int_t AliL3FFloat::fNOpSubs    = 0;
51 Int_t AliL3FFloat::fNOverFlow  = 0;
52 Int_t AliL3FFloat::fNUnderFlow = 0;
53 Double_t AliL3FFloat::fNDiff   = 0;
54 #endif
55
56 void AliL3FFloat::PrintStat(){
57 #ifdef CALCSTATS
58   cout << "fN:            " << fN << endl;
59   cout << "fNRounded:     " << fNRounded << endl;
60   cout << "fNOpAdds:      " << fNOpAdds << endl;
61   cout << "fNOpSubs:      " << fNOpSubs << endl;
62   cout << "fNOpMults:     " << fNOpMults << endl;
63   cout << "fNOpDivs:      " << fNOpDivs << endl;
64   cout << "fNOpOverFlow:  " << fNOverFlow << endl;
65   cout << "fNOpUnderFlow: " << fNUnderFlow << endl;
66   if(fN) cout << "fNDiff:        " << fNDiff/fN << endl;
67 #else
68   cerr << "Not compiled with #define CALCSTATS!" << endl;
69 #endif
70 }
71
72 AliL3FFloat::~AliL3FFloat()
73 {
74 #ifdef CALCSTATS
75   Double_t diff=fabs(fVal-fExactVal);
76   //  if(diff>10./fDigits) cout << diff << " Diff " << *this << endl;
77   fNDiff+=diff;
78 #endif
79 }
80
81 ostream& operator<<(ostream &os, const AliL3FFloat &f) 
82 {
83   os << (Double_t)f << "(" << f.fExactVal << ")"; 
84   return os;
85 }
86
87 AliL3FFloat operator + (const AliL3FFloat &f1,const AliL3FFloat &f2)
88 {
89   AliL3FFloat r(f1); 
90   r+=f2; 
91   return r;
92 }
93
94 AliL3FFloat operator + (const AliL3FFloat &f1,const Double_t f2)
95 {
96   AliL3FFloat r(f1); 
97   r+=f2; 
98   return r;
99 }
100
101 AliL3FFloat operator + (const Double_t f1,const AliL3FFloat &f2)
102 {
103   AliL3FFloat r(f1); 
104   r+=f2; 
105   return r;
106 }
107
108 AliL3FFloat operator + (const AliL3FFloat &f)
109 {
110   AliL3FFloat r(f); 
111   return r;
112 }
113
114 AliL3FFloat operator - (const AliL3FFloat &f1,const AliL3FFloat &f2)
115 {
116   AliL3FFloat r(f1); 
117   r-=f2; 
118   return r;
119 }
120
121 AliL3FFloat operator - (const AliL3FFloat &f1,const Double_t f2)
122 {
123   AliL3FFloat r(f1); 
124   r-=f2; 
125   return r;
126 }
127
128 AliL3FFloat operator - (const Double_t f1,const AliL3FFloat &f2)
129 {
130   AliL3FFloat r(f1); 
131   r-=f2; 
132   return r;
133 }
134
135 AliL3FFloat operator - (const AliL3FFloat &f)
136 {
137   AliL3FFloat r((-(Double_t)f)); 
138   return r;
139 }
140
141 AliL3FFloat operator * (const AliL3FFloat &f1,const AliL3FFloat &f2)
142 {
143   AliL3FFloat r(f1); 
144   r*=f2; 
145   return r;
146 }
147
148 AliL3FFloat operator * (const AliL3FFloat &f1,const Double_t f2)
149 {
150   AliL3FFloat r(f1); 
151   r*=f2; 
152   return r;
153 }
154
155 AliL3FFloat operator * (const Double_t f1,const AliL3FFloat &f2)
156 {
157   AliL3FFloat r(f1); 
158   r*=f2; 
159   return r;
160 }
161
162 AliL3FFloat operator / (const AliL3FFloat &f1,const AliL3FFloat &f2)
163 {
164   AliL3FFloat r(f1); 
165   r/=f2; 
166   return r;
167 }
168
169 AliL3FFloat operator / (const AliL3FFloat &f1,const Double_t f2)
170 {
171   AliL3FFloat r(f1); 
172   r/=f2; 
173   return r;
174 }
175
176 AliL3FFloat operator / (const Double_t f1,const AliL3FFloat &f2)
177 {
178   AliL3FFloat r(f1); 
179   r/=f2; 
180   return r;
181 }
182
183 #ifdef USEINTS
184 void AliL3FFloat::SetParams(Int_t dig,Int_t min,Int_t max)
185 {
186   fDigits=dig;
187   fMin=min;
188   fMax=max;
189 }
190
191 inline void AliL3FFloat::Set(Double_t val)
192 {
193   Round(val);
194   CheckBounds();
195 #ifdef CALCSTATS
196   fN++;
197 #endif
198 }
199
200 inline void AliL3FFloat::Set(const AliL3FFloat &f)
201 {
202   fVali=f.GetValInt();
203   fVal=f.GetVal();
204   fExactVal=f.GetExactVal();
205   CheckBounds();
206 #ifdef CALCSTATS
207   fN++;
208 #endif
209 }
210
211 inline void AliL3FFloat::Round(Double_t val)
212 {
213   fExactVal=val;
214   fVali=Fnt_t(val*fDigits);
215   fVal=Double_t(fVali)/fDigits;
216 #ifdef CALCSTATS
217   if(fVal!=fExactVal) fNRounded++;
218 #endif
219 }
220
221 inline Bool_t AliL3FFloat::CheckUpperBound()
222 {
223   if(fVal>fMax){
224     fVal=fMax;
225     fVali=Fnt_t(fMax*fDigits);
226 #ifdef CALCSTATS
227     fNOverFlow++;
228 #endif
229     return kFALSE;
230   }
231   return kTRUE;
232 }
233
234 inline Bool_t AliL3FFloat::CheckLowerBound()
235 {
236   if(fVal<fMin){
237     fVal=fMin;
238     fVali=Fnt_t(fMin*fDigits);
239 #ifdef CALCSTATS
240     fNUnderFlow++;
241 #endif
242     return kFALSE;
243   }
244   return kTRUE;
245 }
246
247 AliL3FFloat& AliL3FFloat::operator += (const AliL3FFloat &f)
248 {
249   fExactVal+=f.GetExactVal();
250   fVali+=f.GetValInt(); 
251   fVal=Double_t(fVali)/fDigits;  
252   CheckBounds();
253 #ifdef CALCSTATS
254   fNOpAdds++; 
255 #endif
256   return *this;
257 }
258
259 AliL3FFloat& AliL3FFloat::operator += (const Double_t f)     
260 {
261   fExactVal+=f;
262   fVali+=Fnt_t(f*fDigits);
263   fVal=Double_t(fVali)/fDigits;  
264   CheckBounds();
265 #ifdef CALCSTATS
266   fNOpAdds++; 
267 #endif
268   return *this;
269 }
270
271 AliL3FFloat& AliL3FFloat::operator -= (const AliL3FFloat &f) 
272 {
273   fExactVal-=f.GetExactVal();
274   fVali-=f.GetValInt(); 
275   fVal=Double_t(fVali)/fDigits;  
276   CheckBounds();
277 #ifdef CALCSTATS
278   fNOpSubs++; 
279 #endif
280   return *this;
281 }
282
283 AliL3FFloat& AliL3FFloat::operator -= (const Double_t f)
284 {
285   fExactVal-=f;
286   fVali-=Fnt_t(f*fDigits);
287   fVal=Double_t(fVali)/fDigits;  
288   CheckBounds();
289 #ifdef CALCSTATS
290   fNOpSubs++; 
291 #endif
292   return *this;
293 }
294
295 AliL3FFloat& AliL3FFloat::operator *= (const AliL3FFloat &f) 
296 {
297   fExactVal*=f.GetExactVal();
298   fVali=Fnt_t((fVali*f.GetValInt())/fDigits);
299   fVal=Double_t(fVali)/fDigits;  
300   CheckBounds();
301 #ifdef CALCSTATS
302   fNOpMults++;
303 #endif
304   return *this;
305 }
306
307 AliL3FFloat& AliL3FFloat::operator *= (const Double_t f)     
308 {
309   fExactVal*=f;
310   fVali=Fnt_t(fVali*Fnt_t(f));
311   fVal=Double_t(fVali)/fDigits;  
312   CheckBounds();
313 #ifdef CALCSTATS
314   fNOpMults++;
315 #endif
316   return *this;
317 }
318
319 AliL3FFloat& AliL3FFloat::operator /= (const AliL3FFloat &f) 
320 {
321   fExactVal/=f.GetExactVal();
322   fVali=Fnt_t(fVali*fDigits/f.GetValInt());
323   fVal=Double_t(fVali)/fDigits;  
324   CheckBounds();
325 #ifdef CALCSTATS
326   fNOpDivs++; 
327 #endif
328   return *this;
329 }
330
331 AliL3FFloat& AliL3FFloat::operator /= (const Double_t f)     
332 {
333   fExactVal/=f;
334   fVali=Fnt_t((fVali*fDigits)/(Int_t(f*fDigits)));
335   fVal=Double_t(fVali)/fDigits;  
336   CheckBounds();
337 #ifdef CALCSTATS
338   fNOpDivs++; 
339 #endif
340   return *this;
341 }
342
343 //--------------------------------------------------------
344 #else
345 //--------------------------------------------------------
346
347 Char_t AliL3FFloat::fQuery[10] = "%.2f";
348
349 inline void AliL3FFloat::Set(const Double_t val)
350 {
351   fVal=Round(val);
352   fExactVal=val;
353   CheckBounds();
354 #ifdef CALCSTATS
355   fN++;
356 #endif
357 }
358
359 inline void AliL3FFloat::Set(const AliL3FFloat &f)
360 {
361   fVal=(Double_t)f;
362   fExactVal=f.GetExactVal();
363   CheckBounds();
364 #ifdef CALCSTATS
365   fN++;
366 #endif
367 }
368
369 AliL3FFloat& AliL3FFloat::operator += (const AliL3FFloat &f)
370 {
371   Double_t ev=fExactVal+f.GetExactVal();
372   Set(fVal+(Double_t)f); 
373   fExactVal=ev;
374 #ifdef CALCSTATS
375   fNOpAdds++; 
376 #endif
377   return *this;
378 }
379
380 AliL3FFloat& AliL3FFloat::operator += (const Double_t f)     
381 {
382   Double_t ev=fExactVal+f;
383   Set(fVal+Round(f));   
384   fExactVal=ev;
385 #ifdef CALCSTATS
386   fNOpAdds++; 
387 #endif
388   return *this;
389 }
390
391 AliL3FFloat& AliL3FFloat::operator -= (const AliL3FFloat &f) 
392 {
393   Double_t ev=fExactVal-f.GetExactVal();
394   Set(fVal-(Double_t)f);
395   fExactVal=ev;
396 #ifdef CALCSTATS
397   fNOpSubs++; 
398 #endif
399   return *this;
400 }
401
402 AliL3FFloat& AliL3FFloat::operator -= (const Double_t f)
403 {
404   Double_t ev=fExactVal-f;
405   Set(fVal-Round(f)); 
406   fExactVal=ev;
407 #ifdef CALCSTATS
408   fNOpSubs++; 
409 #endif
410   return *this;
411 }
412
413 AliL3FFloat& AliL3FFloat::operator *= (const AliL3FFloat &f) 
414 {
415   Double_t ev=fExactVal*f.GetExactVal();
416   Set(fVal*(Double_t)f);
417   fExactVal=ev;
418 #ifdef CALCSTATS
419   fNOpMults++;
420 #endif
421   return *this;
422 }
423
424 AliL3FFloat& AliL3FFloat::operator *= (const Double_t f)     
425 {
426   Double_t ev=fExactVal*f;
427   Set(fVal*Round(f));   
428   fExactVal=ev;
429 #ifdef CALCSTATS
430   fNOpMults++;
431 #endif
432   return *this;
433 }
434
435 AliL3FFloat& AliL3FFloat::operator /= (const AliL3FFloat &f) 
436 {
437   Double_t ev=fExactVal/f.GetExactVal();
438   Set(fVal/(Double_t)f);
439   fExactVal=ev;
440 #ifdef CALCSTATS
441   fNOpDivs++; 
442 #endif
443   return *this;
444 }
445
446 AliL3FFloat& AliL3FFloat::operator /= (const Double_t f)     
447 {
448   Double_t ev=fExactVal/f;
449   Set(fVal/Round(f));   
450   fExactVal=ev;
451 #ifdef CALCSTATS
452   fNOpDivs++; 
453 #endif
454   return *this;
455 }
456
457 inline Bool_t AliL3FFloat::CheckUpperBound()
458 {
459   if(fVal>fMax){
460     fVal=fMax;
461 #ifdef CALCSTATS
462     fNOverFlow++;
463 #endif
464     return kFALSE;
465   }
466   return kTRUE;
467 }
468
469 inline Bool_t AliL3FFloat::CheckLowerBound()
470 {
471   if(fVal<fMin){
472     fVal=fMin;
473 #ifdef CALCSTATS
474     fNUnderFlow++;
475 #endif
476     return kFALSE;
477   }
478   return kTRUE;
479 }
480
481 #ifdef FASTWITHROUNDINGERROS
482 inline Double_t AliL3FFloat::Round(Double_t val)
483 {
484   Int_t dummy=Int_t(fDigits*val);
485   Double_t ret=(Double_t)(dummy)/fDigits;
486 #ifdef CALCSTATS
487   if(ret!=val) fNRounded++;
488 #endif
489   return ret;
490 }
491 #else
492 inline Double_t AliL3FFloat::Round(Double_t val)
493 {
494   static Char_t strnum[100];
495   sprintf(strnum,fQuery,val);
496   Double_t ret=atof(strnum);
497 #ifdef CALCSTATS
498   if(ret!=val) fNRounded++;
499 #endif
500   return ret;
501 }
502 #endif
503
504 void AliL3FFloat::SetParams(Int_t dig,Int_t min,Int_t max)
505 {
506   fDigits=dig;
507   Int_t prec=0;
508   if(fDigits>0) prec=(Int_t)log10(fDigits);
509   sprintf(fQuery,"%%.%df",prec);
510   fMin=min;
511   fMax=max;
512 }
513
514 #endif
515 #endif