1 #include "AliTRDtrapAlu.h"
\r
3 ClassImp(AliTRDtrapAlu)
\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
17 AliTRDtrapAlu::AliTRDtrapAlu():TObject()
\r
28 // default constructor
\r
34 AliTRDtrapAlu::~AliTRDtrapAlu(){
\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
44 fValue = 0; //currently, re-initialization kills the value
\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
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
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
69 Double_t val = valPre + valPost;
\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
82 for (Int_t j = fPostCom - 1; j >= 0; j--){
\r
83 printf("%d",(fValue>>j) & 1);
\r
93 AliTRDtrapAlu& AliTRDtrapAlu::AssignInt(const Int_t& first){
\r
94 // assign an integer
\r
96 // parameter "first" is an integer for the pre-comma part (not UInt in order to match the error case first<0)
\r
98 Int_t exponent = fPreCom + fPostCom;
\r
102 fValue = 0; //setting fValue to 0; first should not be negative
\r
103 fValue = fValue & 0;
\r
107 if (CheckUSize(first<<fPostCom) == kFALSE){
\r
109 //setting fValue to maximum; first was to big
\r
110 fValue = fuRestriction;
\r
111 fValue = fValue & LUT(exponent)-1;
\r
115 if (CheckLSize(first<<fPostCom) == kFALSE){
\r
117 //setting fValue to minimum; first was to small
\r
118 fValue = flRestriction;
\r
119 fValue = fValue & LUT(exponent)-1;
\r
125 fValue = fValue<<fPostCom;
\r
126 fValue = fValue & LUT(exponent)-1;
\r
132 AliTRDtrapAlu& AliTRDtrapAlu::AssignDouble(const Double_t& first){
\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
140 Double_t firstPreFloat = 0;
\r
143 Int_t power1 = LUT(exponent);
\r
145 firstPre = (Int_t)first;
\r
146 firstPreFloat = firstPre;
\r
150 fValue = fValue & 0;
\r
154 if(CheckUSize((Int_t)(first*LUT(fPostCom))) == kFALSE){
\r
156 //fValue = MakePower(2,fPreCom) - 1;
\r
157 fValue = fuRestriction;
\r
158 fValue = fValue & (power1 - 1);
\r
162 if(CheckLSize((Int_t)(first*LUT(fPostCom))) == kFALSE){
\r
164 //fValue = MakePower(2,fPreCom) - 1;
\r
165 fValue = flRestriction;
\r
166 fValue = fValue & (power1 - 1);
\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
181 fValue = fValue & (power1 - 1);
\r
186 AliTRDtrapAlu& AliTRDtrapAlu::operator=(const AliTRDtrapAlu& binary){
\r
187 // assign an object of type AliTRDtrapAlu
\r
190 //Int_t exponent = fPreCom + fPostCom;
\r
193 Int_t power1 = LUT(fPreCom + fPostCom);
\r
195 fValue = binary.GetValue(); // in case this==&binary : binary's values are overwritten
\r
196 Int_t diffPost = binary.GetPost()-fPostCom;
\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
202 //setting fValue to maximum
\r
205 fValue = fuRestriction; // fuRestriction >= 0
\r
206 fValue = fValue & (power1 - 1);
\r
211 Int_t val = (binary.GetSign()==kFALSE) ? check : -check;
\r
212 if (CheckLSize(val)==kFALSE){ //checking size of pre-comma part
\r
214 //setting fValue to minimum
\r
217 if (flRestriction < 0) {
\r
218 fValue = -flRestriction;
\r
222 fValue = flRestriction;
\r
225 fValue = fValue & (power1 - 1);
\r
229 if (this == & binary) return *this;
\r
232 Int_t iValue = fValue;
\r
233 fValue = fValue>>(binary.GetPost()); //only keep the valid pre-comma bits
\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
243 fValue = fValue<<1;
\r
244 fValue = fValue | c;
\r
247 fValue = fValue & (power1 - 1);
\r
248 fSigned = binary.GetSign();
\r
254 AliTRDtrapAlu& AliTRDtrapAlu::operator+(AliTRDtrapAlu& binary){
\r
257 //no const parameter because referenced object will be changed
\r
260 Int_t binPre = binary.GetPre();
\r
261 Int_t binPost = binary.GetPost();
\r
262 Int_t binVal = binary.GetValue();
\r
264 Int_t min = Min(binPost,fPostCom);
\r
265 Int_t max = Max(binPre,fPreCom);
\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
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
282 //Mem().FastInit(max+1,min,add);
\r
287 AliTRDtrapAlu& AliTRDtrapAlu::operator-(AliTRDtrapAlu& binary){
\r
290 Int_t binPre = binary.GetPre();
\r
291 Int_t binPost = binary.GetPost();
\r
292 Int_t binVal = binary.GetValue();
\r
295 Int_t min = Min(binPost,fPostCom);
\r
296 Int_t max = Max(binPre,fPreCom);
\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
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
315 AliTRDtrapAlu& AliTRDtrapAlu::operator*(AliTRDtrapAlu& binary){
\r
319 Int_t binPre = binary.GetPre();
\r
320 Int_t binPost = binary.GetPost();
\r
323 Int_t min = Min(binPost,fPostCom);
\r
324 Int_t max = Max(binPre,fPreCom);
\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
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
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
347 Mem().AssignFormatted(mult);
\r
348 Mem().SetSign(sign);
\r
349 //mult = sign*mult;
\r
350 //Mem().FastInit(2*max+1,min,mult);
\r
356 AliTRDtrapAlu& AliTRDtrapAlu::operator/(AliTRDtrapAlu& binary){
\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
365 Int_t div1 = binary.GetValue(); //value in integer format
\r
366 Int_t div2 = fValue;
\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
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
386 fdiv = (Double_t)numerator/denominator;
\r
388 Int_t shift = fPostCom - binPost;
\r
391 //denominator = denominator * LUT(shift);
\r
392 fLUT = (Double_t)LUT(min)/LUT(shift);
\r
397 //numerator = numerator * LUT(shift);
\r
398 fLUT = (Double_t)LUT(min)*LUT(shift);
\r
401 fLUT = (Double_t)LUT(min);
\r
408 Int_t sign = (div>=0) ? 1 : -1;
\r
409 div = Max(div,-div);
\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
422 Int_t AliTRDtrapAlu::MakePower(const Int_t& base,const Int_t& exponent)const{
\r
423 // calculate "base" to the power of "exponent"
\r
426 for(Int_t i = 1; i <= exponent; i++){
\r
427 result = result * base;
\r
435 Int_t AliTRDtrapAlu::LUT(const Int_t& index){
\r
436 // simple look-up table for base=2
\r
438 static Bool_t fLUT = kFALSE;
\r
439 static Int_t gLUT[30];
\r
440 if (fLUT == kFALSE) {
\r
442 for(Int_t i = 1; i<30; i++) {
\r
443 gLUT[i] = gLUT[i-1] * 2;
\r
447 if (index >=0 && index < 30){
\r
448 return gLUT[index];
\r
452 return Mem().MakePower(2,index);
\r