]>
Commit | Line | Data |
---|---|---|
3e87ef69 | 1 | // @(#) $Id$ |
62e60107 | 2 | |
3 | // Author: Constantin Loizides <mailto:loizides@fi.uib.no> | |
3e87ef69 | 4 | //*-- Copyright & copy ALICE HLT Group |
62e60107 | 5 | |
24dbb695 | 6 | #ifdef USEFFLOAT |
7 | ||
8 | #include "AliL3StandardIncludes.h" | |
62e60107 | 9 | |
10 | #include "AliL3Logging.h" | |
11 | #include "AliL3Logger.h" | |
24dbb695 | 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 | ||
62e60107 | 20 | #include "AliL3FFloat.h" |
21 | ||
22 | /** \class AliL3FFloat | |
3e87ef69 | 23 | <pre> |
62e60107 | 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. | |
3e87ef69 | 35 | </pre> |
24dbb695 | 36 | */ |
62e60107 | 37 | |
62e60107 | 38 | ClassImp(AliL3FFloat) |
39 | ||
27835353 | 40 | Int_t AliL3FFloat::fDigits = DEFDIG; |
41 | Int_t AliL3FFloat::fMax = DEFMAX; | |
42 | Int_t AliL3FFloat::fMin = DEFMIN; | |
27835353 | 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; | |
62e60107 | 52 | Int_t AliL3FFloat::fNUnderFlow = 0; |
27835353 | 53 | Double_t AliL3FFloat::fNDiff = 0; |
54 | #endif | |
55 | ||
24dbb695 | 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 | } | |
27835353 | 71 | |
72 | AliL3FFloat::~AliL3FFloat() | |
73 | { | |
74 | #ifdef CALCSTATS | |
24dbb695 | 75 | Double_t diff=fabs(fVal-fExactVal); |
76 | // if(diff>10./fDigits) cout << diff << " Diff " << *this << endl; | |
77 | fNDiff+=diff; | |
27835353 | 78 | #endif |
79 | } | |
62e60107 | 80 | |
81 | ostream& operator<<(ostream &os, const AliL3FFloat &f) | |
82 | { | |
27835353 | 83 | os << (Double_t)f << "(" << f.fExactVal << ")"; |
62e60107 | 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 | ||
62e60107 | 114 | AliL3FFloat operator - (const AliL3FFloat &f1,const AliL3FFloat &f2) |
115 | { | |
116 | AliL3FFloat r(f1); | |
27835353 | 117 | r-=f2; |
62e60107 | 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 | ||
27835353 | 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 | ||
62e60107 | 162 | AliL3FFloat operator / (const AliL3FFloat &f1,const AliL3FFloat &f2) |
163 | { | |
164 | AliL3FFloat r(f1); | |
165 | r/=f2; | |
166 | return r; | |
167 | } | |
168 | ||
27835353 | 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 | ||
24dbb695 | 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 | ||
62e60107 | 369 | AliL3FFloat& AliL3FFloat::operator += (const AliL3FFloat &f) |
370 | { | |
371 | Double_t ev=fExactVal+f.GetExactVal(); | |
372 | Set(fVal+(Double_t)f); | |
373 | fExactVal=ev; | |
27835353 | 374 | #ifdef CALCSTATS |
62e60107 | 375 | fNOpAdds++; |
27835353 | 376 | #endif |
62e60107 | 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; | |
27835353 | 385 | #ifdef CALCSTATS |
62e60107 | 386 | fNOpAdds++; |
27835353 | 387 | #endif |
62e60107 | 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; | |
27835353 | 396 | #ifdef CALCSTATS |
62e60107 | 397 | fNOpSubs++; |
27835353 | 398 | #endif |
62e60107 | 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; | |
27835353 | 407 | #ifdef CALCSTATS |
62e60107 | 408 | fNOpSubs++; |
27835353 | 409 | #endif |
62e60107 | 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; | |
27835353 | 418 | #ifdef CALCSTATS |
62e60107 | 419 | fNOpMults++; |
27835353 | 420 | #endif |
62e60107 | 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; | |
27835353 | 429 | #ifdef CALCSTATS |
62e60107 | 430 | fNOpMults++; |
27835353 | 431 | #endif |
62e60107 | 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; | |
27835353 | 440 | #ifdef CALCSTATS |
62e60107 | 441 | fNOpDivs++; |
27835353 | 442 | #endif |
62e60107 | 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; | |
27835353 | 451 | #ifdef CALCSTATS |
62e60107 | 452 | fNOpDivs++; |
27835353 | 453 | #endif |
62e60107 | 454 | return *this; |
455 | } | |
456 | ||
24dbb695 | 457 | inline Bool_t AliL3FFloat::CheckUpperBound() |
62e60107 | 458 | { |
24dbb695 | 459 | if(fVal>fMax){ |
460 | fVal=fMax; | |
27835353 | 461 | #ifdef CALCSTATS |
24dbb695 | 462 | fNOverFlow++; |
27835353 | 463 | #endif |
24dbb695 | 464 | return kFALSE; |
465 | } | |
466 | return kTRUE; | |
62e60107 | 467 | } |
468 | ||
24dbb695 | 469 | inline Bool_t AliL3FFloat::CheckLowerBound() |
62e60107 | 470 | { |
24dbb695 | 471 | if(fVal<fMin){ |
472 | fVal=fMin; | |
27835353 | 473 | #ifdef CALCSTATS |
24dbb695 | 474 | fNUnderFlow++; |
27835353 | 475 | #endif |
24dbb695 | 476 | return kFALSE; |
477 | } | |
478 | return kTRUE; | |
62e60107 | 479 | } |
480 | ||
24dbb695 | 481 | #ifdef FASTWITHROUNDINGERROS |
27835353 | 482 | inline Double_t AliL3FFloat::Round(Double_t val) |
62e60107 | 483 | { |
484 | Int_t dummy=Int_t(fDigits*val); | |
485 | Double_t ret=(Double_t)(dummy)/fDigits; | |
27835353 | 486 | #ifdef CALCSTATS |
62e60107 | 487 | if(ret!=val) fNRounded++; |
27835353 | 488 | #endif |
62e60107 | 489 | return ret; |
490 | } | |
27835353 | 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 | |
62e60107 | 503 | |
62e60107 | 504 | void AliL3FFloat::SetParams(Int_t dig,Int_t min,Int_t max) |
505 | { | |
506 | fDigits=dig; | |
27835353 | 507 | Int_t prec=0; |
508 | if(fDigits>0) prec=(Int_t)log10(fDigits); | |
509 | sprintf(fQuery,"%%.%df",prec); | |
62e60107 | 510 | fMin=min; |
511 | fMax=max; | |
512 | } | |
513 | ||
27835353 | 514 | #endif |
24dbb695 | 515 | #endif |