Class for fixed point operations.
[u/mrichter/AliRoot.git] / HLT / misc / AliL3FFloat.cxx
1 //$Id$
2
3 // Author: Constantin Loizides <mailto:loizides@fi.uib.no>
4 //*-- Copyright & copy CL
5
6 #include <stream.h>
7 #include <math.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 #include "AliL3Logging.h"
12 #include "AliL3Logger.h"
13 #include "AliL3FFloat.h"
14
15 /** \class AliL3FFloat
16 //<pre>
17 //----------------------------------------------------
18 // AliL3FFloat
19 //
20 // Fixed Floating Point class for debugging purposes.
21 //
22 // The class behaves like a normal Double_t class but
23 // calculates everything in respect to fDigits (eg. 
24 // fDigits=100 -> 2 digits behind the comma). Further-
25 // more it keeps the exact value in floating precision
26 // and gathers some statistical information about 
27 // its usage.
28 //</pre>
29  */
30
31
32 ClassImp(AliL3FFloat)
33
34 Int_t AliL3FFloat::fDigits =  DEFDIG;
35 Int_t AliL3FFloat::fMax = DEFMAX;
36 Int_t AliL3FFloat::fMin = DEFMIN;
37
38 Int_t AliL3FFloat::fN = 0;
39 Int_t AliL3FFloat::fNRounded = 0;
40 Int_t AliL3FFloat::fNOpAdds = 0;
41 Int_t AliL3FFloat::fNOpMults = 0;
42 Int_t AliL3FFloat::fNOpDivs = 0;
43 Int_t AliL3FFloat::fNOpSubs = 0;
44 Int_t AliL3FFloat::fNOverFlow = 0;
45 Int_t AliL3FFloat::fNUnderFlow = 0;
46
47 ostream& operator<<(ostream &os, const AliL3FFloat &f) 
48 {
49   //  os << (Double_t)f << endl; 
50   os << (Double_t)f << "(" << f.fExactVal << ")" << endl; 
51   return os;
52 }
53
54 AliL3FFloat operator + (const AliL3FFloat &f1,const AliL3FFloat &f2)
55 {
56   AliL3FFloat r(f1); 
57   r+=f2; 
58   return r;
59 }
60
61 AliL3FFloat operator + (const AliL3FFloat &f1,const Double_t f2)
62 {
63   AliL3FFloat r(f1); 
64   r+=f2; 
65   return r;
66 }
67
68 AliL3FFloat operator + (const Double_t f1,const AliL3FFloat &f2)
69 {
70   AliL3FFloat r(f1); 
71   r+=f2; 
72   return r;
73 }
74
75 AliL3FFloat operator + (const AliL3FFloat &f)
76 {
77   AliL3FFloat r(f); 
78   return r;
79 }
80
81
82 AliL3FFloat operator - (const AliL3FFloat &f1,const AliL3FFloat &f2)
83 {
84   AliL3FFloat r(f1); 
85   r+=f2; 
86   return r;
87 }
88
89 AliL3FFloat operator - (const AliL3FFloat &f1,const Double_t f2)
90 {
91   AliL3FFloat r(f1); 
92   r-=f2; 
93   return r;
94 }
95
96 AliL3FFloat operator - (const Double_t f1,const AliL3FFloat &f2)
97 {
98   AliL3FFloat r(f1); 
99   r-=f2; 
100   return r;
101 }
102
103 AliL3FFloat operator - (const AliL3FFloat &f)
104 {
105   AliL3FFloat r((-(Double_t)f)); 
106   return r;
107 }
108
109 AliL3FFloat operator * (const AliL3FFloat &f1,const AliL3FFloat &f2)
110 {
111   AliL3FFloat r(f1); 
112   r*=f2; 
113   return r;
114 }
115
116 AliL3FFloat operator / (const AliL3FFloat &f1,const AliL3FFloat &f2)
117 {
118   AliL3FFloat r(f1); 
119   r/=f2; 
120   return r;
121 }
122
123 AliL3FFloat& AliL3FFloat::operator += (const AliL3FFloat &f)
124 {
125   Double_t ev=fExactVal+f.GetExactVal();
126   Set(fVal+(Double_t)f); 
127   fExactVal=ev;
128   fNOpAdds++; 
129   return *this;
130 }
131
132 AliL3FFloat& AliL3FFloat::operator += (const Double_t f)     
133 {
134   Double_t ev=fExactVal+f;
135   Set(fVal+Round(f));   
136   fExactVal=ev;
137   fNOpAdds++; 
138   return *this;
139 }
140
141 AliL3FFloat& AliL3FFloat::operator -= (const AliL3FFloat &f) 
142 {
143   Double_t ev=fExactVal-f.GetExactVal();
144   Set(fVal-(Double_t)f);
145   fExactVal=ev;
146   fNOpSubs++; 
147   return *this;
148 }
149
150 AliL3FFloat& AliL3FFloat::operator -= (const Double_t f)
151 {
152   Double_t ev=fExactVal-f;
153   Set(fVal-Round(f)); 
154   fExactVal=ev;
155   fNOpSubs++; 
156   return *this;
157 }
158
159 AliL3FFloat& AliL3FFloat::operator *= (const AliL3FFloat &f) 
160 {
161   Double_t ev=fExactVal*f.GetExactVal();
162   Set(fVal*(Double_t)f);
163   fExactVal=ev;
164   fNOpMults++;
165   return *this;
166 }
167
168 AliL3FFloat& AliL3FFloat::operator *= (const Double_t f)     
169 {
170   Double_t ev=fExactVal*f;
171   Set(fVal*Round(f));   
172   fExactVal=ev;
173   fNOpMults++;
174   return *this;
175 }
176
177 AliL3FFloat& AliL3FFloat::operator /= (const AliL3FFloat &f) 
178 {
179   Double_t ev=fExactVal/f.GetExactVal();
180   Set(fVal/(Double_t)f);
181   fExactVal=ev;
182   fNOpDivs++; 
183   return *this;
184 }
185
186 AliL3FFloat& AliL3FFloat::operator /= (const Double_t f)     
187 {
188   Double_t ev=fExactVal/f;
189   Set(fVal/Round(f));   
190   fExactVal=ev;
191   fNOpDivs++; 
192   return *this;
193 }
194
195 void AliL3FFloat::Set(Double_t val)
196 {
197   fVal=Round(val);
198   fExactVal=val;
199   CheckBounds();
200   fN++;
201 }
202
203 void AliL3FFloat::Set(AliL3FFloat &f)
204 {
205   fVal=(Double_t)f;
206   fExactVal=f.GetExactVal();
207   CheckBounds();
208   fN++;
209 }
210
211 Double_t AliL3FFloat::Round(Double_t val)
212 {
213   Int_t dummy=Int_t(fDigits*val);
214   Double_t ret=(Double_t)(dummy)/fDigits;
215   if(ret!=val) fNRounded++;
216   return ret;
217 }
218
219 Bool_t AliL3FFloat::CheckUpperBound()
220 {
221   if(fVal>fMax){
222     fVal=fMax;
223     fNOverFlow++;
224     return kFALSE;
225   }
226
227   return kTRUE;
228 }
229
230 Bool_t AliL3FFloat::CheckLowerBound()
231 {
232   if(fVal<fMin){
233     fVal=fMin;
234     fNUnderFlow++;
235     return kFALSE;
236   }
237
238   return kTRUE;
239 }
240
241 void AliL3FFloat::SetParams(Int_t dig,Int_t min,Int_t max)
242 {
243   fDigits=dig;
244   fMin=min;
245   fMax=max;
246 }
247
248 void AliL3FFloat::PrintStat(){
249   cout << "fN:            " << fN << endl;
250   cout << "fNRounded:     " << fNRounded << endl;
251   cout << "fNOpAdds:      " << fNOpAdds << endl;
252   cout << "fNOpSubs:      " << fNOpSubs << endl;
253   cout << "fNOpMults:     " << fNOpMults << endl;
254   cout << "fNOpDivs:      " << fNOpDivs << endl;
255   cout << "fNOpOverFlow:  " << fNOverFlow << endl;
256   cout << "fNOpUnderFlow: " << fNUnderFlow << endl;
257 }