]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDtrapAlu.cxx
Shadowing of variabled corrected.
[u/mrichter/AliRoot.git] / TRD / AliTRDtrapAlu.cxx
1 #include "AliTRDtrapAlu.h"\r
2 \r
3 ClassImp(AliTRDtrapAlu)\r
4 \r
5 //usage of the class: \r
6 //declaration of class instances:   AliTRDtrapAlu a,b,c;\r
7 //initialization:                  a.Init(2,11); b.Init(4,4); c.Init(5,4);\r
8 //assigning values:                a.AssignDouble(5.7); b.AssignInt(3);(you can also do b.AssignDouble(3) with same effect);\r
9 //calculation:                     c = a*b;  \r
10 //test if c has right value:       c.WriteWord();\r
11 //don't declare pointers; operators not overridden for pointer types; you have to dereference yourself;\r
12 //use operators +,-,*,/ only with instances of the class; don't do things like c=a*2 but rather b.AssignInt(2); c=a*b;\r
13 \r
14 \r
15 \r
16   \r
17 AliTRDtrapAlu::AliTRDtrapAlu():TObject()\r
18 \r
19   ,fValue(0)\r
20   ,fPreCom(0)\r
21   ,fPostCom(0)\r
22   ,fuRestriction(0)\r
23   ,flRestriction(0)\r
24   ,fSigned(kFALSE)\r
25 \r
26 {\r
27   \r
28  // default constructor\r
29  \r
30  \r
31 }\r
32 \r
33 \r
34 AliTRDtrapAlu::~AliTRDtrapAlu(){\r
35   //destructor\r
36 }\r
37 \r
38 \r
39 \r
40 void AliTRDtrapAlu::Init(const Int_t& precom, const Int_t& postcom, const Int_t& lRestriction, const Int_t& uRestriction){\r
41    // initialization: characterizes the bit-word (nr of pre- and post-comma bits, boundaries)\r
42    fPostCom = postcom;\r
43    fPreCom  = precom;\r
44    fValue   = 0;       //currently, re-initialization kills the value\r
45    fSigned  = kFALSE;\r
46 \r
47    if (fPreCom + fPostCom > 32 || fPreCom > 31) {fPreCom = 1; fPostCom = 0;return;} // prevent pre-comma part exceeding 31 spaces\r
48    if (fPreCom  <= 0) {fPreCom  = 1;}\r
49    if (fPostCom <  0) {fPostCom = 0;}\r
50    \r
51    Int_t lut = LUT(fPreCom + fPostCom)-1;\r
52    if (uRestriction <= -1 || uRestriction > lut) {fuRestriction = lut;}\r
53    else {fuRestriction = uRestriction;}\r
54    if (lRestriction <= -1 || lRestriction > fuRestriction) {flRestriction = -lut;}\r
55    else {flRestriction = lRestriction;}\r
56    // up to now you can only choose a non-negative lower restriction (e.g. if you want your values to be >=0) ; can't deal with asymmetric borders; have to be implemented if needed\r
57 }\r
58 \r
59 \r
60 Double_t AliTRDtrapAlu::GetValueWhole() const { \r
61    // get the actual value (respecting pre- and post-comma parts) in integer-description\r
62    Double_t valPre = (Double_t)(fValue>>fPostCom);\r
63    Double_t valPost = 0.0;\r
64    for(Int_t i = 0; i<=fPostCom-1; i++){\r
65      Double_t num = (fValue>>i)&1;\r
66      Double_t denom = LUT(fPostCom-i);\r
67      valPost = valPost + num/denom;\r
68    }\r
69    Double_t val = valPre + valPost;\r
70    return val;\r
71  }\r
72 \r
73 \r
74 void AliTRDtrapAlu::WriteWord(){\r
75   // for debugging purposes\r
76   printf("bit-word: ");\r
77   if (fSigned == true) printf("-");\r
78   for(Int_t i = fPostCom + fPreCom - 1; i >= fPostCom; i--){  //read from behind in order to write the word from left to right\r
79     printf("%d",(fValue>>i) & 1);\r
80   }\r
81   printf(".");\r
82   for (Int_t j = fPostCom - 1; j >= 0; j--){\r
83     printf("%d",(fValue>>j) & 1);\r
84   }\r
85   printf("\n");\r
86          \r
87 }\r
88 \r
89 \r
90 \r
91 \r
92 \r
93 AliTRDtrapAlu& AliTRDtrapAlu::AssignInt(const Int_t& first){  \r
94   // assign an integer\r
95 \r
96   // parameter "first" is an integer for the pre-comma part (not UInt in order to match the error case first<0)\r
97   fSigned = kFALSE;\r
98   Int_t exponent = fPreCom + fPostCom;\r
99 \r
100     \r
101   if (first<0) {\r
102     fValue  = 0;                      //setting fValue to 0; first should not be negative\r
103     fValue  = fValue & 0;\r
104     return *this;\r
105   }\r
106 \r
107   if (CheckUSize(first<<fPostCom) == kFALSE){\r
108     \r
109     //setting fValue to maximum; first was to big\r
110     fValue  = fuRestriction;\r
111     fValue  = fValue & LUT(exponent)-1;\r
112     return *this;\r
113   }\r
114 \r
115   if (CheckLSize(first<<fPostCom) == kFALSE){\r
116     \r
117     //setting fValue to minimum; first was to small\r
118     fValue  = flRestriction;\r
119     fValue  = fValue & LUT(exponent)-1;\r
120     return *this;\r
121   }\r
122 \r
123   \r
124   fValue  = first;\r
125   fValue  = fValue<<fPostCom; \r
126   fValue  = fValue & LUT(exponent)-1;\r
127  \r
128   return *this;\r
129     \r
130 }\r
131 \r
132 AliTRDtrapAlu& AliTRDtrapAlu::AssignDouble(const  Double_t& first){\r
133   // assign a double\r
134  \r
135   fSigned = kFALSE;\r
136   Int_t exponent           = fPreCom + fPostCom;\r
137   Int_t firstPre          = 0;  //integer part of first\r
138   Int_t firstPost         = 0;  //comma part of first (cut off with enough accuracy\r
139   Int_t c                  = 0;\r
140   Double_t firstPreFloat = 0;\r
141   \r
142   \r
143   Int_t power1 = LUT(exponent);\r
144   \r
145   firstPre       = (Int_t)first;\r
146   firstPreFloat = firstPre;\r
147   \r
148   if(firstPre < 0){\r
149     fValue  = 0;\r
150     fValue = fValue & 0;\r
151     return *this;\r
152   }\r
153   \r
154   if(CheckUSize((Int_t)(first*LUT(fPostCom))) == kFALSE){\r
155     \r
156     //fValue  = MakePower(2,fPreCom) - 1;\r
157     fValue  = fuRestriction;\r
158     fValue  = fValue & (power1 - 1);\r
159     return *this;\r
160   }\r
161   \r
162   if(CheckLSize((Int_t)(first*LUT(fPostCom))) == kFALSE){\r
163     \r
164     //fValue  = MakePower(2,fPreCom) - 1;\r
165     fValue  = flRestriction;\r
166     fValue  = fValue & (power1 - 1);\r
167     return *this;\r
168   }\r
169   \r
170 \r
171   fValue = firstPre;\r
172   \r
173   //get post comma part with adequate accuracy\r
174   firstPost = (Int_t)((first - firstPreFloat)*LUT(fPostCom));\r
175   for(Int_t i = 1; i <= fPostCom; i++) {\r
176     c = (firstPost>>(fPostCom - i)) & 1;\r
177     fValue  = fValue<<1;\r
178     fValue  = fValue | c;\r
179   }\r
180 \r
181   fValue = fValue & (power1 - 1);\r
182   return *this;\r
183 }\r
184 \r
185 \r
186 AliTRDtrapAlu& AliTRDtrapAlu::operator=(const AliTRDtrapAlu& binary){\r
187   // assign an object of type AliTRDtrapAlu\r
188 \r
189   Int_t c    = 0;\r
190   //Int_t exponent = fPreCom + fPostCom;\r
191   \r
192   \r
193   Int_t power1 = LUT(fPreCom + fPostCom);\r
194 \r
195   fValue          = binary.GetValue();         // in case this==&binary : binary's values are overwritten\r
196   Int_t diffPost = binary.GetPost()-fPostCom;\r
197   Int_t check     = 0;\r
198   if(diffPost<0) check = fValue<<(-diffPost);\r
199   else check = fValue>>(diffPost);\r
200   if (CheckUSize(check)==kFALSE){    //checking size of pre-comma part\r
201     \r
202     //setting fValue to maximum\r
203       \r
204            \r
205     fValue  = fuRestriction;         // fuRestriction >= 0 \r
206     fValue  = fValue & (power1 - 1);\r
207     fSigned = kFALSE;\r
208     return *this;\r
209   }\r
210 \r
211   Int_t val = (binary.GetSign()==kFALSE) ? check : -check; \r
212   if (CheckLSize(val)==kFALSE){    //checking size of pre-comma part\r
213     \r
214     //setting fValue to minimum\r
215       \r
216            \r
217     if (flRestriction < 0) {\r
218       fValue  = -flRestriction;\r
219       fSigned = kTRUE;\r
220     }\r
221     else {\r
222       fValue  = flRestriction;\r
223       fSigned = kFALSE;\r
224     }\r
225     fValue  = fValue & (power1 - 1);\r
226     return *this;\r
227   }\r
228   \r
229   if (this == & binary) return *this;\r
230   \r
231   fSigned = kFALSE;\r
232   Int_t iValue = fValue;\r
233   fValue = fValue>>(binary.GetPost());           //only keep the valid pre-comma bits\r
234   \r
235   //append existing post-comma bits to fValue; cut off or add 0 if post-comma numbers don`t match\r
236   for(Int_t i = 1; i <= fPostCom; i++){\r
237     if(i <= (binary.GetPost())){\r
238       c = ((iValue)>>(binary.GetPost()-i)) & 1;\r
239     }\r
240     else{\r
241       c = 0;\r
242     }\r
243     fValue  = fValue<<1;\r
244     fValue  = fValue | c;\r
245   }\r
246   \r
247   fValue = fValue & (power1 - 1);\r
248   fSigned = binary.GetSign();\r
249   return *this;\r
250 }\r
251 \r
252 \r
253 \r
254 AliTRDtrapAlu& AliTRDtrapAlu::operator+(AliTRDtrapAlu& binary){ \r
255   // + operator\r
256 \r
257   //no const parameter because referenced object will be changed\r
258      \r
259   \r
260   Int_t binPre     = binary.GetPre();\r
261   Int_t binPost    = binary.GetPost();\r
262   Int_t binVal     = binary.GetValue();\r
263   \r
264   Int_t min         = Min(binPost,fPostCom);\r
265   Int_t max         = Max(binPre,fPreCom);\r
266   \r
267   Int_t shift       = binPost - min;\r
268   Int_t add1        = (binVal)>>(shift);    //for addition: cut off at minimum accuracy\r
269   shift             = fPostCom - min;\r
270   Int_t add2        = fValue>>(shift);\r
271   if(binary.GetSign() == kTRUE) add1 = -add1;\r
272   if(fSigned == kTRUE) add2 = -add2;\r
273   Int_t add = add1 + add2;\r
274   \r
275   \r
276   //because the parameter "binary" could be a reference to the object to which Mem() is a reference, do not change Mem() until you have extracted all information from "binary"; otherwise you change the information you would like to read\r
277   Mem().Init(max + 1,min);      //buffer: enough space for pre-comma,post-comma according to accuracy\r
278   Mem().AssignFormatted(Max(add,-add));\r
279   Mem().SetSign(add);\r
280   \r
281 \r
282   //Mem().FastInit(max+1,min,add);\r
283   return Mem();\r
284 }\r
285 \r
286 \r
287 AliTRDtrapAlu& AliTRDtrapAlu::operator-(AliTRDtrapAlu& binary){\r
288   // - operator    \r
289 \r
290   Int_t binPre    = binary.GetPre();\r
291   Int_t binPost   = binary.GetPost();\r
292   Int_t binVal    = binary.GetValue();\r
293 \r
294 \r
295   Int_t min      = Min(binPost,fPostCom);\r
296   Int_t max      = Max(binPre,fPreCom);\r
297 \r
298   Int_t shift    = binPost - min;\r
299   Int_t sub1 = (binVal)>>(shift); //for addition: cut off at minimum accuracy\r
300   shift = fPostCom - min;\r
301   Int_t sub2 = fValue>>(shift);\r
302   if(binary.GetSign() == kTRUE) sub1 = -sub1;\r
303   if(fSigned  == kTRUE) sub2 = -sub2;\r
304   Int_t sub = sub2 - sub1;     // order of subtraction is important\r
305  \r
306 \r
307   Mem().Init(max + 1,min);      //buffer: enough space for pre-comma, post-comma according to accuracy\r
308   Mem().AssignFormatted(Max(sub,-sub)); \r
309   Mem().SetSign(sub);\r
310   //Mem().FastInit(max+1,min,sub);\r
311   return Mem();\r
312\r
313 \r
314 \r
315 AliTRDtrapAlu& AliTRDtrapAlu::operator*(AliTRDtrapAlu& binary){\r
316   // * operator\r
317   \r
318 \r
319   Int_t binPre   = binary.GetPre();\r
320   Int_t binPost  = binary.GetPost();\r
321 \r
322 \r
323   Int_t min      = Min(binPost,fPostCom);\r
324   Int_t max      = Max(binPre,fPreCom);\r
325 \r
326   \r
327   Int_t mult1 = binary.GetValue();\r
328   Int_t mult2 = fValue;\r
329   Int_t shift  = (Int_t)(fPostCom + binPost - min);\r
330   Double_t fmult1 = (Double_t)mult1;\r
331   Double_t fmult2 = (Double_t)mult2;\r
332   (fmult1 > fmult2) ? fmult1 = fmult1/LUT(shift) : fmult2 = fmult2/LUT(shift);\r
333   \r
334     \r
335   if (binary.GetSign() == kTRUE) fmult1 = -fmult1;\r
336   if (fSigned  == kTRUE) fmult2 = -fmult2;\r
337   Double_t fmult  = fmult1*fmult2;\r
338   Int_t mult = (Int_t)fmult;\r
339   Int_t sign = 1;\r
340   if(mult<0) sign = -1;\r
341   mult = Max(mult,-mult);\r
342   //Int_t shift = fPostCom + binPost - min;\r
343   //mult = mult>>(shift);\r
344   Mem().Init(2 * max + 1, min); // +1 to consider the borrow from the past-comma part; accuracy of past-comma part is determined by the minimum; therefore, for the result not more accuracy is guaranteed\r
345   // be aware that this only works if 2*max+1+min <= 32!! adjusting the pre-comma place to the value would consume too much time\r
346 \r
347   Mem().AssignFormatted(mult);\r
348   Mem().SetSign(sign);\r
349   //mult = sign*mult;\r
350   //Mem().FastInit(2*max+1,min,mult);\r
351   return Mem();\r
352 }\r
353   \r
354 \r
355 \r
356 AliTRDtrapAlu& AliTRDtrapAlu::operator/(AliTRDtrapAlu& binary){\r
357   // / operator\r
358  \r
359 \r
360   Int_t binPre  = binary.GetPre();\r
361   Int_t binPost = binary.GetPost();\r
362   Int_t min              = Min(binPost,fPostCom);\r
363   Int_t max              = Max(binPre,fPreCom);\r
364   \r
365   Int_t div1             = binary.GetValue(); //value in integer format\r
366   Int_t div2             = fValue;\r
367   \r
368   // this approach does not always work because it can exceed the range of integers\r
369   //Int_t numerator     = div2 * LUT(min);\r
370   Int_t numerator     = div2;\r
371   if (fSigned == kTRUE) numerator = numerator*(-1);\r
372   Int_t denominator   = div1;\r
373   if (binary.GetSign() == kTRUE) denominator = denominator*(-1);\r
374   Double_t fdiv       = 0.0;\r
375   Double_t fLUT       = 0.0;\r
376   Int_t div           = 0;\r
377   \r
378 \r
379   if (div1 == 0){\r
380     Mem().Init(max + 1,min);\r
381     Mem().AssignFormatted(LUT(max+min+1)-1); // division by 0: set to max value\r
382     //Mem().FastInit(max+1,min,div1);\r
383     return Mem();\r
384   }\r
385       \r
386   fdiv = (Double_t)numerator/denominator;\r
387   \r
388   Int_t shift = fPostCom - binPost;\r
389   \r
390   if(shift>0){\r
391       //denominator = denominator * LUT(shift);\r
392       fLUT = (Double_t)LUT(min)/LUT(shift);\r
393   }\r
394   else {\r
395       if(shift<0) {\r
396           shift = -shift;\r
397           //numerator =  numerator * LUT(shift);\r
398           fLUT = (Double_t)LUT(min)*LUT(shift);\r
399       }\r
400       else {\r
401           fLUT = (Double_t)LUT(min);\r
402       }\r
403   }\r
404 \r
405   fdiv = fdiv*fLUT;\r
406   div = (Int_t)fdiv;\r
407   \r
408   Int_t sign = (div>=0) ? 1 : -1;\r
409   div = Max(div,-div);\r
410   \r
411   // chose min as past-comma part because from a division of integers you can't get only an integer\r
412   Mem().Init(max + 1,min); // max+1+min must <= 32!!\r
413   Mem().SetSign(sign);\r
414   Mem().AssignFormatted(div);\r
415   \r
416   return Mem();\r
417   \r
418 }\r
419 \r
420 \r
421 \r
422 Int_t AliTRDtrapAlu::MakePower(const Int_t& base,const  Int_t& exponent)const{\r
423 // calculate "base" to the power of "exponent"\r
424   Int_t result = 1;\r
425   \r
426     for(Int_t i = 1; i <= exponent; i++){\r
427     result = result * base;\r
428   }\r
429   return result;\r
430 }\r
431 \r
432 \r
433 \r
434 \r
435 Int_t AliTRDtrapAlu::LUT(const Int_t& index){   \r
436   // simple look-up table for base=2\r
437   \r
438   static Bool_t fLUT = kFALSE;\r
439   static Int_t gLUT[30];\r
440   if (fLUT == kFALSE) {\r
441     gLUT[0] = 1;\r
442     for(Int_t i = 1; i<30; i++) {\r
443       gLUT[i] = gLUT[i-1] * 2;\r
444     }\r
445   fLUT = kTRUE;\r
446   } \r
447   if (index >=0 && index < 30){\r
448     return gLUT[index];\r
449   }\r
450   else {\r
451     \r
452     return Mem().MakePower(2,index);\r
453   }\r
454 }\r