]>
Commit | Line | Data |
---|---|---|
1d93b218 | 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 |