]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDtrapAlu.cxx
Revision of AliTRDmcmSim + coding rule violations
[u/mrichter/AliRoot.git] / TRD / AliTRDtrapAlu.cxx
CommitLineData
23200400 1/**************************************************************************\r
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *\r
3* *\r
4* Author: The ALICE Off-line Project. *\r
5* Contributors are mentioned in the code where appropriate. *\r
6* *\r
7* Permission to use, copy, modify and distribute this software and its *\r
8* documentation strictly for non-commercial purposes is hereby granted *\r
9* without fee, provided that the above copyright notice appears in all *\r
10* copies and that both the copyright notice and this permission notice *\r
11* appear in the supporting documentation. The authors make no claims *\r
12* about the suitability of this software for any purpose. It is *\r
13* provided "as is" without express or implied warranty. *\r
14**************************************************************************/\r
15\r
16/* $Id: AliTRDtrapAlu.cxx 25891 2008-05-19 14:58:18Z fca $ */\r
17\r
18///////////////////////////////////////////////////////////////////////////////\r
19// //\r
20// TRAP-ALU implementation //\r
21// //\r
22// Author: //\r
23// Clemens Haltebourg <halteb@physi.uni-heidelberg.de> //\r
24// //\r
25// Usage of the class: //\r
26// Declaration of class instances: AliTRDtrapAlu a,b,c; //\r
27// Initialization: a.Init(2,11); b.Init(4,4); c.Init(5,4);//\r
28// Assigning values: a.AssignDouble(5.7); b.AssignInt(3); //\r
29// (you can also do b.AssignDouble(3) with same effect); //\r
30// Calculation: c = a*b; //\r
31// Test if c has right value: c.WriteWord(); //\r
32// Don't declare pointers; operators not overridden for pointer types; //\r
33// You have to dereference yourself; //\r
34// Use operators +,-,*,/ only with instances of the class; don't do //\r
35// things like c=a*2 but rather b.AssignInt(2); c=a*b; //\r
36// //\r
37///////////////////////////////////////////////////////////////////////////////\r
38\r
1d93b218 39#include "AliTRDtrapAlu.h"\r
40\r
41ClassImp(AliTRDtrapAlu)\r
42\r
23200400 43//_____________________________________________________________________________ \r
1d93b218 44AliTRDtrapAlu::AliTRDtrapAlu():TObject()\r
45\r
46 ,fValue(0)\r
47 ,fPreCom(0)\r
48 ,fPostCom(0)\r
49 ,fuRestriction(0)\r
50 ,flRestriction(0)\r
51 ,fSigned(kFALSE)\r
52\r
53{\r
54 \r
23200400 55 // default constructor\r
56 \r
1d93b218 57}\r
58\r
23200400 59//_____________________________________________________________________________ \r
1d93b218 60AliTRDtrapAlu::~AliTRDtrapAlu(){\r
61 //destructor\r
62}\r
63\r
23200400 64//_____________________________________________________________________________ \r
1d93b218 65void AliTRDtrapAlu::Init(const Int_t& precom, const Int_t& postcom, const Int_t& lRestriction, const Int_t& uRestriction){\r
66 // initialization: characterizes the bit-word (nr of pre- and post-comma bits, boundaries)\r
67 fPostCom = postcom;\r
68 fPreCom = precom;\r
69 fValue = 0; //currently, re-initialization kills the value\r
70 fSigned = kFALSE;\r
71\r
72 if (fPreCom + fPostCom > 32 || fPreCom > 31) {fPreCom = 1; fPostCom = 0;return;} // prevent pre-comma part exceeding 31 spaces\r
73 if (fPreCom <= 0) {fPreCom = 1;}\r
74 if (fPostCom < 0) {fPostCom = 0;}\r
75 \r
76 Int_t lut = LUT(fPreCom + fPostCom)-1;\r
77 if (uRestriction <= -1 || uRestriction > lut) {fuRestriction = lut;}\r
78 else {fuRestriction = uRestriction;}\r
79 if (lRestriction <= -1 || lRestriction > fuRestriction) {flRestriction = -lut;}\r
80 else {flRestriction = lRestriction;}\r
81 // 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
82}\r
83\r
23200400 84//_____________________________________________________________________________ \r
1d93b218 85Double_t AliTRDtrapAlu::GetValueWhole() const { \r
86 // get the actual value (respecting pre- and post-comma parts) in integer-description\r
87 Double_t valPre = (Double_t)(fValue>>fPostCom);\r
88 Double_t valPost = 0.0;\r
89 for(Int_t i = 0; i<=fPostCom-1; i++){\r
90 Double_t num = (fValue>>i)&1;\r
91 Double_t denom = LUT(fPostCom-i);\r
92 valPost = valPost + num/denom;\r
93 }\r
94 Double_t val = valPre + valPost;\r
95 return val;\r
96 }\r
97\r
23200400 98//_____________________________________________________________________________ \r
1d93b218 99void AliTRDtrapAlu::WriteWord(){\r
100 // for debugging purposes\r
101 printf("bit-word: ");\r
102 if (fSigned == true) printf("-");\r
103 for(Int_t i = fPostCom + fPreCom - 1; i >= fPostCom; i--){ //read from behind in order to write the word from left to right\r
104 printf("%d",(fValue>>i) & 1);\r
105 }\r
106 printf(".");\r
107 for (Int_t j = fPostCom - 1; j >= 0; j--){\r
108 printf("%d",(fValue>>j) & 1);\r
109 }\r
110 printf("\n");\r
111 \r
112}\r
113\r
23200400 114//_____________________________________________________________________________ \r
1d93b218 115AliTRDtrapAlu& AliTRDtrapAlu::AssignInt(const Int_t& first){ \r
116 // assign an integer\r
117\r
118 // parameter "first" is an integer for the pre-comma part (not UInt in order to match the error case first<0)\r
119 fSigned = kFALSE;\r
120 Int_t exponent = fPreCom + fPostCom;\r
121\r
122 \r
123 if (first<0) {\r
124 fValue = 0; //setting fValue to 0; first should not be negative\r
125 fValue = fValue & 0;\r
126 return *this;\r
127 }\r
128\r
129 if (CheckUSize(first<<fPostCom) == kFALSE){\r
130 \r
131 //setting fValue to maximum; first was to big\r
132 fValue = fuRestriction;\r
4f57cad7 133 fValue = fValue & (LUT(exponent)-1);\r
1d93b218 134 return *this;\r
135 }\r
136\r
137 if (CheckLSize(first<<fPostCom) == kFALSE){\r
138 \r
139 //setting fValue to minimum; first was to small\r
140 fValue = flRestriction;\r
4f57cad7 141 fValue = fValue & (LUT(exponent)-1);\r
1d93b218 142 return *this;\r
143 }\r
144\r
145 \r
146 fValue = first;\r
147 fValue = fValue<<fPostCom; \r
4f57cad7 148 fValue = fValue & (LUT(exponent)-1);\r
1d93b218 149 \r
150 return *this;\r
151 \r
152}\r
153\r
23200400 154//_____________________________________________________________________________ \r
1d93b218 155AliTRDtrapAlu& AliTRDtrapAlu::AssignDouble(const Double_t& first){\r
156 // assign a double\r
157 \r
158 fSigned = kFALSE;\r
159 Int_t exponent = fPreCom + fPostCom;\r
160 Int_t firstPre = 0; //integer part of first\r
161 Int_t firstPost = 0; //comma part of first (cut off with enough accuracy\r
162 Int_t c = 0;\r
163 Double_t firstPreFloat = 0;\r
164 \r
165 \r
166 Int_t power1 = LUT(exponent);\r
167 \r
168 firstPre = (Int_t)first;\r
169 firstPreFloat = firstPre;\r
170 \r
171 if(firstPre < 0){\r
172 fValue = 0;\r
173 fValue = fValue & 0;\r
174 return *this;\r
175 }\r
176 \r
177 if(CheckUSize((Int_t)(first*LUT(fPostCom))) == kFALSE){\r
178 \r
179 //fValue = MakePower(2,fPreCom) - 1;\r
180 fValue = fuRestriction;\r
181 fValue = fValue & (power1 - 1);\r
182 return *this;\r
183 }\r
184 \r
185 if(CheckLSize((Int_t)(first*LUT(fPostCom))) == kFALSE){\r
186 \r
187 //fValue = MakePower(2,fPreCom) - 1;\r
188 fValue = flRestriction;\r
189 fValue = fValue & (power1 - 1);\r
190 return *this;\r
191 }\r
192 \r
193\r
194 fValue = firstPre;\r
195 \r
196 //get post comma part with adequate accuracy\r
197 firstPost = (Int_t)((first - firstPreFloat)*LUT(fPostCom));\r
198 for(Int_t i = 1; i <= fPostCom; i++) {\r
199 c = (firstPost>>(fPostCom - i)) & 1;\r
200 fValue = fValue<<1;\r
201 fValue = fValue | c;\r
202 }\r
203\r
204 fValue = fValue & (power1 - 1);\r
205 return *this;\r
206}\r
207\r
23200400 208//_____________________________________________________________________________ \r
1d93b218 209AliTRDtrapAlu& AliTRDtrapAlu::operator=(const AliTRDtrapAlu& binary){\r
210 // assign an object of type AliTRDtrapAlu\r
211\r
212 Int_t c = 0;\r
213 //Int_t exponent = fPreCom + fPostCom;\r
214 \r
215 \r
216 Int_t power1 = LUT(fPreCom + fPostCom);\r
217\r
218 fValue = binary.GetValue(); // in case this==&binary : binary's values are overwritten\r
219 Int_t diffPost = binary.GetPost()-fPostCom;\r
220 Int_t check = 0;\r
221 if(diffPost<0) check = fValue<<(-diffPost);\r
222 else check = fValue>>(diffPost);\r
223 if (CheckUSize(check)==kFALSE){ //checking size of pre-comma part\r
224 \r
225 //setting fValue to maximum\r
226 \r
227 \r
228 fValue = fuRestriction; // fuRestriction >= 0 \r
229 fValue = fValue & (power1 - 1);\r
230 fSigned = kFALSE;\r
231 return *this;\r
232 }\r
233\r
234 Int_t val = (binary.GetSign()==kFALSE) ? check : -check; \r
235 if (CheckLSize(val)==kFALSE){ //checking size of pre-comma part\r
236 \r
237 //setting fValue to minimum\r
238 \r
239 \r
240 if (flRestriction < 0) {\r
241 fValue = -flRestriction;\r
242 fSigned = kTRUE;\r
243 }\r
244 else {\r
245 fValue = flRestriction;\r
246 fSigned = kFALSE;\r
247 }\r
248 fValue = fValue & (power1 - 1);\r
249 return *this;\r
250 }\r
251 \r
252 if (this == & binary) return *this;\r
253 \r
254 fSigned = kFALSE;\r
255 Int_t iValue = fValue;\r
256 fValue = fValue>>(binary.GetPost()); //only keep the valid pre-comma bits\r
257 \r
258 //append existing post-comma bits to fValue; cut off or add 0 if post-comma numbers don`t match\r
259 for(Int_t i = 1; i <= fPostCom; i++){\r
260 if(i <= (binary.GetPost())){\r
261 c = ((iValue)>>(binary.GetPost()-i)) & 1;\r
262 }\r
263 else{\r
264 c = 0;\r
265 }\r
266 fValue = fValue<<1;\r
267 fValue = fValue | c;\r
268 }\r
269 \r
270 fValue = fValue & (power1 - 1);\r
271 fSigned = binary.GetSign();\r
272 return *this;\r
273}\r
274\r
23200400 275//_____________________________________________________________________________ \r
276AliTRDtrapAlu AliTRDtrapAlu::operator+(const AliTRDtrapAlu& binary){ \r
1d93b218 277 // + operator\r
278\r
279 //no const parameter because referenced object will be changed\r
280 \r
23200400 281 AliTRDtrapAlu alu;\r
1d93b218 282 \r
283 Int_t binPre = binary.GetPre();\r
284 Int_t binPost = binary.GetPost();\r
285 Int_t binVal = binary.GetValue();\r
286 \r
287 Int_t min = Min(binPost,fPostCom);\r
288 Int_t max = Max(binPre,fPreCom);\r
289 \r
290 Int_t shift = binPost - min;\r
291 Int_t add1 = (binVal)>>(shift); //for addition: cut off at minimum accuracy\r
292 shift = fPostCom - min;\r
293 Int_t add2 = fValue>>(shift);\r
294 if(binary.GetSign() == kTRUE) add1 = -add1;\r
295 if(fSigned == kTRUE) add2 = -add2;\r
296 Int_t add = add1 + add2;\r
297 \r
23200400 298 /*\r
1d93b218 299 //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
300 Mem().Init(max + 1,min); //buffer: enough space for pre-comma,post-comma according to accuracy\r
301 Mem().AssignFormatted(Max(add,-add));\r
302 Mem().SetSign(add);\r
303 \r
304\r
305 //Mem().FastInit(max+1,min,add);\r
23200400 306 return Mem();*/\r
307 \r
308 alu.Init(max + 1,min); //buffer: enough space for pre-comma,post-comma according to accuracy\r
309 alu.AssignFormatted(Max(add,-add));\r
310 alu.SetSign(add);\r
311 \r
312 return alu;\r
1d93b218 313\r
23200400 314}\r
1d93b218 315\r
23200400 316//_____________________________________________________________________________ \r
317AliTRDtrapAlu AliTRDtrapAlu::operator-(const AliTRDtrapAlu& binary){\r
1d93b218 318 // - operator \r
319\r
23200400 320 AliTRDtrapAlu alu;\r
321\r
1d93b218 322 Int_t binPre = binary.GetPre();\r
323 Int_t binPost = binary.GetPost();\r
324 Int_t binVal = binary.GetValue();\r
325\r
326\r
327 Int_t min = Min(binPost,fPostCom);\r
328 Int_t max = Max(binPre,fPreCom);\r
329\r
330 Int_t shift = binPost - min;\r
331 Int_t sub1 = (binVal)>>(shift); //for addition: cut off at minimum accuracy\r
332 shift = fPostCom - min;\r
333 Int_t sub2 = fValue>>(shift);\r
334 if(binary.GetSign() == kTRUE) sub1 = -sub1;\r
335 if(fSigned == kTRUE) sub2 = -sub2;\r
336 Int_t sub = sub2 - sub1; // order of subtraction is important\r
337 \r
23200400 338/*\r
1d93b218 339 Mem().Init(max + 1,min); //buffer: enough space for pre-comma, post-comma according to accuracy\r
340 Mem().AssignFormatted(Max(sub,-sub)); \r
341 Mem().SetSign(sub);\r
342 //Mem().FastInit(max+1,min,sub);\r
23200400 343 return Mem();*/\r
344 \r
345 alu.Init(max + 1,min);\r
346 alu.AssignFormatted(Max(sub,-sub)); \r
347 alu.SetSign(sub);\r
348\r
349 return alu;\r
1d93b218 350\r
23200400 351} \r
1d93b218 352\r
23200400 353//_____________________________________________________________________________ \r
354AliTRDtrapAlu AliTRDtrapAlu::operator*(const AliTRDtrapAlu& binary){\r
1d93b218 355 // * operator\r
356 \r
23200400 357 AliTRDtrapAlu alu;\r
1d93b218 358\r
359 Int_t binPre = binary.GetPre();\r
360 Int_t binPost = binary.GetPost();\r
361\r
362\r
363 Int_t min = Min(binPost,fPostCom);\r
364 Int_t max = Max(binPre,fPreCom);\r
365\r
366 \r
367 Int_t mult1 = binary.GetValue();\r
368 Int_t mult2 = fValue;\r
369 Int_t shift = (Int_t)(fPostCom + binPost - min);\r
370 Double_t fmult1 = (Double_t)mult1;\r
371 Double_t fmult2 = (Double_t)mult2;\r
372 (fmult1 > fmult2) ? fmult1 = fmult1/LUT(shift) : fmult2 = fmult2/LUT(shift);\r
373 \r
374 \r
375 if (binary.GetSign() == kTRUE) fmult1 = -fmult1;\r
376 if (fSigned == kTRUE) fmult2 = -fmult2;\r
377 Double_t fmult = fmult1*fmult2;\r
378 Int_t mult = (Int_t)fmult;\r
379 Int_t sign = 1;\r
380 if(mult<0) sign = -1;\r
381 mult = Max(mult,-mult);\r
382 //Int_t shift = fPostCom + binPost - min;\r
383 //mult = mult>>(shift);\r
23200400 384\r
385/*\r
1d93b218 386 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
387 // 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
388\r
389 Mem().AssignFormatted(mult);\r
390 Mem().SetSign(sign);\r
391 //mult = sign*mult;\r
392 //Mem().FastInit(2*max+1,min,mult);\r
23200400 393 return Mem();*/\r
1d93b218 394 \r
23200400 395 alu.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
396// 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
1d93b218 397\r
23200400 398 alu.AssignFormatted(mult);\r
399 alu.SetSign(sign);\r
400 \r
401 return alu;\r
402}\r
403 \r
404//_____________________________________________________________________________ \r
405AliTRDtrapAlu AliTRDtrapAlu::operator/(const AliTRDtrapAlu& binary){\r
1d93b218 406 // / operator\r
407 \r
23200400 408 AliTRDtrapAlu alu;\r
1d93b218 409\r
410 Int_t binPre = binary.GetPre();\r
411 Int_t binPost = binary.GetPost();\r
412 Int_t min = Min(binPost,fPostCom);\r
413 Int_t max = Max(binPre,fPreCom);\r
414 \r
415 Int_t div1 = binary.GetValue(); //value in integer format\r
416 Int_t div2 = fValue;\r
417 \r
418 // this approach does not always work because it can exceed the range of integers\r
419 //Int_t numerator = div2 * LUT(min);\r
420 Int_t numerator = div2;\r
421 if (fSigned == kTRUE) numerator = numerator*(-1);\r
422 Int_t denominator = div1;\r
423 if (binary.GetSign() == kTRUE) denominator = denominator*(-1);\r
424 Double_t fdiv = 0.0;\r
425 Double_t fLUT = 0.0;\r
426 Int_t div = 0;\r
427 \r
428\r
429 if (div1 == 0){\r
23200400 430 /*Mem().Init(max + 1,min);\r
1d93b218 431 Mem().AssignFormatted(LUT(max+min+1)-1); // division by 0: set to max value\r
432 //Mem().FastInit(max+1,min,div1);\r
23200400 433 return Mem();*/\r
434 alu.Init(max + 1,min);\r
435 alu.AssignFormatted(LUT(max+min+1)-1); // division by 0: set to max value\r
436 return alu;\r
1d93b218 437 }\r
438 \r
439 fdiv = (Double_t)numerator/denominator;\r
440 \r
441 Int_t shift = fPostCom - binPost;\r
442 \r
443 if(shift>0){\r
444 //denominator = denominator * LUT(shift);\r
445 fLUT = (Double_t)LUT(min)/LUT(shift);\r
446 }\r
447 else {\r
448 if(shift<0) {\r
449 shift = -shift;\r
450 //numerator = numerator * LUT(shift);\r
451 fLUT = (Double_t)LUT(min)*LUT(shift);\r
452 }\r
453 else {\r
454 fLUT = (Double_t)LUT(min);\r
455 }\r
456 }\r
457\r
458 fdiv = fdiv*fLUT;\r
459 div = (Int_t)fdiv;\r
460 \r
461 Int_t sign = (div>=0) ? 1 : -1;\r
462 div = Max(div,-div);\r
463 \r
464 // chose min as past-comma part because from a division of integers you can't get only an integer\r
23200400 465 \r
466 /*Mem().Init(max + 1,min); // max+1+min must <= 32!!\r
1d93b218 467 Mem().SetSign(sign);\r
468 Mem().AssignFormatted(div);\r
469 \r
23200400 470 return Mem();*/\r
1d93b218 471\r
23200400 472 alu.Init(max + 1,min); // max+1+min must <= 32!!\r
473 alu.SetSign(sign);\r
474 alu.AssignFormatted(div);\r
475 \r
476 return alu;\r
1d93b218 477\r
23200400 478 \r
479}\r
1d93b218 480\r
23200400 481//_____________________________________________________________________________ \r
1d93b218 482Int_t AliTRDtrapAlu::MakePower(const Int_t& base,const Int_t& exponent)const{\r
483// calculate "base" to the power of "exponent"\r
484 Int_t result = 1;\r
485 \r
486 for(Int_t i = 1; i <= exponent; i++){\r
487 result = result * base;\r
488 }\r
489 return result;\r
490}\r
491\r
23200400 492//_____________________________________________________________________________ \r
1d93b218 493Int_t AliTRDtrapAlu::LUT(const Int_t& index){ \r
494 // simple look-up table for base=2\r
495 \r
23200400 496 AliTRDtrapAlu alu;\r
497\r
1d93b218 498 static Bool_t fLUT = kFALSE;\r
499 static Int_t gLUT[30];\r
500 if (fLUT == kFALSE) {\r
501 gLUT[0] = 1;\r
502 for(Int_t i = 1; i<30; i++) {\r
503 gLUT[i] = gLUT[i-1] * 2;\r
504 }\r
505 fLUT = kTRUE;\r
506 } \r
507 if (index >=0 && index < 30){\r
508 return gLUT[index];\r
509 }\r
510 else {\r
511 \r
23200400 512 //return Mem().MakePower(2,index);\r
513 return alu.MakePower(2,index);\r
1d93b218 514 }\r
515}\r