ROOTPWA
TFracNum.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <string>
3 #include <stdio.h>
4 #include <string.h>
5 #include "TFracNum.h"
6 using namespace std;
7 
9 char factorial[] = {'f','a','c','t','o','r','i','a','l'};
10 
11 const char* SQUAREROOT_CHAR="#";
12 
14  if (debugFracNum) {
15  cout<< "N:";for (Int_t i=0; i<mN; i++) cout<<N[i]<<","; cout<<endl;
16  cout<< "D:";for (Int_t i=0; i<mD; i++) cout<<D[i]<<","; cout<<endl;
17  }
18  maxPrimNom=mN;
19  maxPrimDen=mD;
20  NOM = N;
21  DEN = D;
22  sign_prefac=s;
23  if (debugFracNum) {
24  cout << "NOM pointer: " << NOM;
25  cout<< "| ";for (Int_t i=0; i<mN; i++) cout<<NOM[i]<<","; cout<<endl;
26  cout << "DEN pointer: " << DEN;
27  cout<< "| ";for (Int_t i=0; i<mD; i++) cout<<DEN[i]<<","; cout<<endl;
28  }
29  this->SetINTs();
30 }
31 
32 TFracNum::TFracNum(Int_t N, Int_t D, const char* s) {
33  maxPrimNom=0;
34  maxPrimDen=0;
35  NOM=0;
36  DEN=0;
37  sign_prefac=1;
38  if (strcmp(s,"factorial")==0) {
39  if (debugFracNum) cout << s << endl;
40  if (N==D) return;
41  Int_t Low=N;
42  Int_t High=D;
43  if (N>D){Low=D; High=N;}
44  Int_t prim_vec[NPRIMFIELD];
45  for (Int_t i=0; i<NPRIMFIELD; i++) prim_vec[i]=0;
46  Int_t maxPrim=0;
47  for (Int_t fac=Low+1; fac<=High; fac++) {
48  Int_t rest=fac;
49  Int_t fmax=0;
50  while (rest!=1 && fmax<NPRIMFIELD){
51  while (rest % PRIMES[fmax] == 0) {
52  prim_vec[fmax]++;
53  rest /= PRIMES[fmax];
54  }
55  fmax++;
56  }
57  if (fmax>maxPrim) maxPrim=fmax;
58  }
59  if (N<D) {
60  maxPrimDen=maxPrim;
61  DEN=new Int_t[maxPrimDen];
62  for (Int_t jp=0; jp<maxPrimDen; jp++) DEN[jp]=prim_vec[jp];
63  }
64  else {
65  maxPrimNom=maxPrim;
66  NOM=new Int_t[maxPrimNom];
67  for (Int_t jp=0; jp<maxPrimNom; jp++) NOM[jp]=prim_vec[jp];
68  }
69  }
70  this->SetINTs();
71 }
72 
74 
75  if (debugFracNum) {
76  cout << "Initializing with " << inom<<","<< iden << endl;
77  }
78  NOM_INT = inom; if (inom<0) NOM_INT=-inom;
79  DEN_INT = iden; if (iden<0) DEN_INT=-iden;
80 
81  if (inom==0) {
82  if (iden==0){
83  maxPrimNom=0;
84  maxPrimDen=0;
85  NOM=0;
86  DEN=0;
87  sign_prefac=-6666;
88  return;
89  }
90  maxPrimNom=0;
91  maxPrimDen=0;
92  NOM=0;
93  DEN=0;
94  sign_prefac=0;
95  NOM_INT=0;
96  DEN_INT=1;
97  dvalue=0;
98  return;
99  }
100 
101  if (iden==0) {
102  sign_prefac=-7777;
103  return;
104  }
105 
106  sign_prefac=1;
107  if (inom<0) {sign_prefac *= -1; inom*=-1;}
108  if (iden<0) {sign_prefac *= -1; iden*=-1;}
109 
110  if ( (inom>1000 || iden>1000) && // catch the const initialisations
111  (inom > MAXPRIMSQUARED || // in the header file
112  iden > MAXPRIMSQUARED) ) {
113 
114  if (inom > MAXPRIMSQUARED || iden > MAXPRIMSQUARED) {
115  cerr << "MAXPRIMSQUARED reached!!! NOM=" << inom << ", DEN="
116  << iden<<endl;
117  }
118  maxPrimNom=-inom;
119  maxPrimDen=-iden;
120  NOM=0;
121  DEN=0;
122  NOM_INT=inom;
123  DEN_INT=iden;
124  dvalue=sign_prefac*Double_t(inom)/Double_t(iden);
125  }
126  else {
127  maxPrimNom=0;
128  Int_t rest_nom=inom;
129  Int_t prim_vec_nom[NPRIMFIELD];
130  for (Int_t i=0; i<NPRIMFIELD; i++) prim_vec_nom[i]=0;
131  while (rest_nom!=1 && maxPrimNom<NPRIMFIELD){
132  while (rest_nom % PRIMES[maxPrimNom] == 0) {
133  prim_vec_nom[maxPrimNom]++;
134  rest_nom /= PRIMES[maxPrimNom];
135  }
136  maxPrimNom++;
137  }
138  if (rest_nom!=1){
139  maxPrimNom=-inom;
140  maxPrimDen=-iden;
141  NOM=0;
142  DEN=0;
143  }
144  else {
145  maxPrimDen=0;
146  Int_t rest_den=iden;
147  Int_t prim_vec_den[NPRIMFIELD];
148  for (Int_t i=0; i<NPRIMFIELD; i++) prim_vec_den[i]=0;
149  while (rest_den!=1 && maxPrimDen<NPRIMFIELD){
150  while (rest_den % PRIMES[maxPrimDen] == 0) {
151  prim_vec_den[maxPrimDen]++;
152  rest_den /= PRIMES[maxPrimDen];
153  }
154  maxPrimDen++;
155  }
156  if (rest_den!=1){
157  maxPrimNom=-inom;
158  maxPrimDen=-iden;
159  NOM=0;
160  DEN=0;
161  }
162  else {
163  Int_t maxPrim=maxPrimNom;
164  if (maxPrimDen>maxPrim) maxPrim=maxPrimDen;
165 
166  for (Int_t ip=0; ip<maxPrim; ip++) {
167  if (prim_vec_nom[ip]!=0 && prim_vec_den[ip]!=0) {
168  if (prim_vec_den[ip] > prim_vec_nom[ip]) {
169  prim_vec_den[ip] -= prim_vec_nom[ip];
170  prim_vec_nom[ip] = 0;
171  }
172  else {
173  prim_vec_nom[ip] -= prim_vec_den[ip];
174  prim_vec_den[ip] = 0;
175  }
176  }
177  }
178 
179  maxPrimNom=0;
180  maxPrimDen=0;
181  for (Int_t ip=0; ip<NPRIMFIELD; ip++) {
182  if (prim_vec_nom[ip]!=0) maxPrimNom=ip+1;
183  if (prim_vec_den[ip]!=0) maxPrimDen=ip+1;
184  }
185 
186  if (maxPrimNom) {
187  NOM=new Int_t[maxPrimNom];
188  for (Int_t jp=0; jp<maxPrimNom; jp++) NOM[jp]=prim_vec_nom[jp];
189  }
190  else {
191  NOM=0;
192  }
193  if (maxPrimDen) {
194  DEN=new Int_t[maxPrimDen];
195  for (Int_t jp=0; jp<maxPrimDen; jp++) DEN[jp]=prim_vec_den[jp];
196  }
197  else {
198  DEN=0;
199  }
200  }
201  }
202  this->SetINTs();
203  }
204 }
205 
206 Bool_t
208  if (sign_prefac==0) {
209  NOM_INT=0;
210  DEN_INT=1;
211  dvalue=0;
212  }
213  else {
214  NOM_INT=1;
215  DEN_INT=1;
216  if (maxPrimNom<0 && maxPrimDen<0){
217  NOM_INT=-maxPrimNom;
218  DEN_INT=-maxPrimDen;
219  }
220  else {
221 
222  Int_t ip=maxPrimNom-1;
223  while (ip>=0 && NOM[ip]==0) { maxPrimNom=ip; ip--;}
224  //if (maxPrimNom==0) NOM=0;
225 
226  ip=maxPrimDen-1;
227  while (ip>=0 && DEN[ip]==0) { maxPrimDen=ip; ip--;}
228 
229  Int_t ipn=0;
230  while (ipn<maxPrimNom) {
231  for (Int_t jj=0; jj<NOM[ipn]; jj++) NOM_INT *= PRIMES[ipn];
232  ipn++;
233  }
234  Int_t ipd=0;
235  while (ipd<maxPrimDen) {
236  for (Int_t jj=0; jj<DEN[ipd]; jj++) DEN_INT *= PRIMES[ipd];
237  ipd++;
238  }
239  }
240  dvalue=Double_t(sign_prefac)*Double_t(NOM_INT)/Double_t(DEN_INT);
241  }
242  return true;
243 }
244 
245 Int_t
247  Int_t maxPD=maxPrimDen;
248  if ( maxPD > b.maxPrimDen ) maxPD=b.maxPrimDen;
249  Int_t comdiv=1;
250  for (Int_t i=0; i<maxPD; i++) {
251  Int_t ppot=DEN[i];
252  if (b.DEN[i]<ppot) ppot=b.DEN[i];
253  while (ppot-- > 0) comdiv*=PRIMES[i];
254  }
255  return comdiv;
256 }
257 
258 TFracNum*
260  TFracNum mixed = (*this) * (*b);
261  TFracNum aa=*this;
262  TFracNum bb=*b;
263  TFracNum *res = new TFracNum();
264  if (mixed.Sqrt()) {
265  Bool_t flipsign=(aa.Dval()+bb.Dval()<0);
266  aa.Abs();
267  bb.Abs();
268  *res = aa + bb + TFracNum_Two*mixed;
269  if (flipsign) res->FlipSign();
270  return res;
271  }
272  cerr << "Error in TFracNum::SumSignedRoots()" << endl
273  << "this:" << this->Dval() << endl;
274  this->PrintToErr();
275  cerr << "b:" << b->Dval() << endl;
276  b->PrintToErr();
277  return 0;
278 }
279 
280 Bool_t
282  if (sign_prefac==0||NOM_INT==0) return true;
283  if (debugFracNum) {
284  Int_t sqrt_ok=1;
285  for (Int_t i=0; i<maxPrimNom; i++)
286  if (NOM[i]%2) { sqrt_ok=0; break; }
287  if (sqrt_ok==1)
288  for (Int_t i=0; i<maxPrimDen; i++)
289  if (DEN[i]%2) { sqrt_ok=0; break; }
290  if (sqrt_ok==0) {
291  cout << "square root not possible for this fracnum :(" <<endl;
292  this->Print();
293  }
294  }
295  for (Int_t i=0; i<maxPrimNom; i++) if (NOM[i]%2) return false;
296  for (Int_t i=0; i<maxPrimDen; i++) if (DEN[i]%2) return false;
297  for (Int_t i=0; i<maxPrimNom; i++) NOM[i]/=2;
298  for (Int_t i=0; i<maxPrimDen; i++) DEN[i]/=2;
299  this->SetINTs();
300  return true;
301 };
302 
303 Bool_t
305  sign_prefac*=-1;
306  dvalue*=-1.0;
307  return true;
308 }
309 
310 Bool_t
312  if (sign_prefac==0) return true;
313  sign_prefac=1;
314  if (NOM_INT<0) NOM_INT*=-1;
315  if (dvalue<0) dvalue*=-1.0;
316  return true;
317 }
318 
319 Bool_t
321  if (sign_prefac==-7777) {
322  maxPrimNom=0;
323  maxPrimDen=0;
324  NOM=0;
325  DEN=0;
326  sign_prefac=-6666;
327  this->SetINTs();
328  return false;
329  }
330  if (NOM_INT==0) {
331  maxPrimNom=0;
332  maxPrimDen=0;
333  NOM=0;
334  DEN=0;
335  sign_prefac=-7777;
336  this->SetINTs();
337  return false;
338  }
339  Int_t MPN=maxPrimNom;
340  maxPrimNom=maxPrimDen;
341  maxPrimDen=MPN;
342  Int_t* NOMPTR=NOM;
343  NOM=DEN;
344  DEN=NOMPTR;
345  this->SetINTs();
346  return true;
347 }
348 
349 Int_t
351  if (dvalue<0) return -1;
352  else return 1;
353 }
354 
355 Bool_t
357  if (sign_prefac==0 && b.sign_prefac==0) return true;
358  if (sign_prefac != b.sign_prefac) return false;
359  if (maxPrimNom!=b.maxPrimNom) return false;
360  if (maxPrimDen!=b.maxPrimDen) return false;
361  for (Int_t i=0; i<maxPrimNom; i++)
362  if (NOM[i]!=b.NOM[i]) return false;
363  for (Int_t i=0; i<maxPrimDen; i++)
364  if (DEN[i]!=b.DEN[i]) return false;
365  return true;
366 };
367 
368 Bool_t
370  if (sign_prefac==0 && b.sign_prefac==0) {
371  cout << "Both zero, they are equal."<<endl; return true;
372  }
373  if (sign_prefac != b.sign_prefac) {
374  cout << "Different sign: "
375  <<sign_prefac<<"!="<<b.sign_prefac<<endl;
376  return false;
377  }
378  if (maxPrimNom!=b.maxPrimNom) {
379  cout << "Different maxPrimNom: "
380  <<maxPrimNom<<"!="<<b.maxPrimNom<<endl;
381  return false;
382  }
383  if (maxPrimDen!=b.maxPrimDen) {
384  cout << "Different maxPrimDen: "
385  <<maxPrimDen<<"!="<<b.maxPrimDen<<endl;
386  return false;
387  }
388  for (Int_t i=0; i<maxPrimNom; i++)
389  if (NOM[i]!=b.NOM[i]){
390  cout << "Different numerator contribution at prime "<<i<<": "
391  <<NOM[i]<<"!="<<b.NOM[i]<<endl;
392  return false;
393  }
394  for (Int_t i=0; i<maxPrimDen; i++)
395  if (DEN[i]!=b.DEN[i]) {
396  cout << "Different denominator contribution at prime "<<i<<": "
397  <<DEN[i]<<"!="<<b.DEN[i]<<endl;
398  return false;
399  }
400  cout << "Well, they're simply equal!" << endl;
401  return true;
402 };
403 
404 char*
406  char* hstr = new char[30];
407  if (sign_prefac==0) {sprintf(hstr, "{0,1}"); return hstr;}
408  if (sign_prefac==-7777) {sprintf(hstr, "{1,0}"); return hstr;}
409  if (sign_prefac==-6666) {sprintf(hstr, "{0,0}"); return hstr;}
410  if (sign_prefac==1) sprintf(hstr, "{%lld,%lld}", NOM_INT, DEN_INT);
411  else sprintf(hstr, "{%lld,%lld}", -NOM_INT, DEN_INT);
412  return hstr;
413 };
414 
415 Bool_t
417  if (dvalue>b.dvalue) return true;
418  return false;
419 };
420 
421 
422 TFracNum
424 {
425  Int_t den_cdiv=DenomCommonDivisor(b);
426  Int_t bdc=b.DEN_INT/den_cdiv;
427  Int_t adc= DEN_INT/den_cdiv;
428  return TFracNum(sign_prefac * NOM_INT*bdc+
429  b.sign_prefac*b.NOM_INT*adc, DEN_INT*bdc);
430 }
431 
432 
433 TFracNum
435 {
436  // if one of the two numbers is undetermined,
437  // the product is also undetermined
438  if (sign_prefac==-6666 || b.sign_prefac == -6666)
439  return TFracNum(0,0,0,0,-6666);
440 
441  // if one of the two numbers contains division by zero,
442  // and the other nominator is zero, the product is undetermined
443  if ( (sign_prefac==-7777 && b.sign_prefac == 0 ) ||
444  (sign_prefac==0 && b.sign_prefac == -7777) )
445  return TFracNum(0,0,0,0,-6666);
446 
447  // other cases with division by zero; product is also infinity
448  if ( (sign_prefac==-7777 || b.sign_prefac == -7777) )
449  return TFracNum(0,0,0,0,-7777);
450 
451  if (sign_prefac*b.sign_prefac == 0)
452  return TFracNum(0,0,0,0,0);
453 
454  Int_t maxPrimNom_ = maxPrimNom;
455  if (b.maxPrimNom > maxPrimNom_) maxPrimNom_ = b.maxPrimNom;
456  Int_t maxPrimDen_ = maxPrimDen;
457  if (b.maxPrimDen > maxPrimDen_) maxPrimDen_ = b.maxPrimDen;
458  Int_t maxPrim=maxPrimNom_;
459  if (maxPrimDen_>maxPrim) maxPrim=maxPrimDen_;
460 
461  Int_t prim_vec_nom[maxPrim];
462  Int_t prim_vec_den[maxPrim];
463 
464  for (Int_t ip=0; ip<maxPrim; ip++) {
465  prim_vec_nom[ip]=0;
466  prim_vec_den[ip]=0;
467  if ( maxPrimNom>ip) prim_vec_nom[ip]+= NOM[ip];
468  if (b.maxPrimNom>ip) prim_vec_nom[ip]+=b.NOM[ip];
469  if ( maxPrimDen>ip) prim_vec_den[ip]+= DEN[ip];
470  if (b.maxPrimDen>ip) prim_vec_den[ip]+=b.DEN[ip];
471  }
472 
473  for (Int_t ip=0; ip<maxPrim; ip++) {
474  if (prim_vec_nom[ip]!=0 && prim_vec_den[ip]!=0) {
475  if (prim_vec_den[ip] > prim_vec_nom[ip]) {
476  prim_vec_den[ip] -= prim_vec_nom[ip];
477  prim_vec_nom[ip] = 0;
478  }
479  else {
480  prim_vec_nom[ip] -= prim_vec_den[ip];
481  prim_vec_den[ip] = 0;
482  }
483  }
484  }
485 
486  for (Int_t ip=0; ip<maxPrim; ip++) {
487  if (prim_vec_nom[ip]!=0) maxPrimNom_=ip+1;
488  if (prim_vec_den[ip]!=0) maxPrimDen_=ip+1;
489  }
490 
491  Int_t* NOM_=new Int_t[maxPrimNom_];
492  for (Int_t jp=0; jp<maxPrimNom_; jp++) NOM_[jp]=prim_vec_nom[jp];
493 
494  Int_t* DEN_=new Int_t[maxPrimDen_];
495  for (Int_t jp=0; jp<maxPrimDen_; jp++) DEN_[jp]=prim_vec_den[jp];
496 
497  if(debugFracNum) {
498  cout << " Initial with maxN=" << maxPrimNom_<<", maxD="
499  << maxPrimDen_<<", "<< NOM_<<", "<< DEN_<<", "<<
500  sign_prefac*b.sign_prefac<<endl;
501  cout<< "NOM:";
502  for (Int_t i=0; i<maxPrimNom_; i++) cout<<NOM_[i]<<","; cout<<endl;
503  cout<< "DEN:";
504  for (Int_t i=0; i<maxPrimDen_; i++) cout<<DEN_[i]<<","; cout<<endl;
505  }
506  return TFracNum(maxPrimNom_, maxPrimDen_, NOM_, DEN_,
507  sign_prefac*b.sign_prefac);
508 }
509 
510 Double_t
512  if (debugFracNum) {
513  cout << "nom prime list: " << maxPrimNom << ",pointer "<< NOM << endl;
514  cout << "den prime list: " << maxPrimDen << ",pointer "<< DEN << endl;
515  cout<< "NOM:";
516  for (Int_t i=0; i<maxPrimNom; i++) cout<<NOM[i]<<","; cout<<endl;
517  cout<< "DEN:";
518  for (Int_t i=0; i<maxPrimDen; i++) cout<<DEN[i]<<","; cout<<endl;
519  }
520  cout<<"sign_prefac="<<sign_prefac<<endl;
521  if (maxPrimNom<0) {
522  if (sign_prefac<0) cout << "-";
523  cout << -maxPrimNom << "/" << -maxPrimDen << endl;
524  return Double_t(sign_prefac)*Double_t(-maxPrimNom)/Double_t(-maxPrimDen);
525  }
526  Int_t integrity=1;
527  for (Int_t i=0; i<maxPrimNom; i++) if (NOM[i]<0 || NOM[i]>1000) integrity=0;
528  for (Int_t i=0; i<maxPrimDen; i++) if (DEN[i]<0 || DEN[i]>1000) integrity=0;
529  if (integrity==0) return -1;
530 
531  Int_t nom=1;
532  Int_t ipn=0;
533  if (sign_prefac<0) cout << "-NOM = ";
534  else cout << " NOM = ";
535  Int_t FirstTerm=1;
536  while (ipn<maxPrimNom) {
537  if (NOM[ipn]!=0) {
538  cout << PRIMES[ipn] << "^" << NOM[ipn];
539  FirstTerm=0;
540  }
541  for (Int_t jj=0; jj<NOM[ipn]; jj++) nom *= PRIMES[ipn];
542  ipn++;
543  if (!FirstTerm && ipn<maxPrimNom && NOM[ipn]!=0) cout << " * ";
544  }
545  cout << " = " << nom << endl;
546 
547  Int_t den=1;
548  Int_t ipd=0;
549  cout << " DEN = ";
550  FirstTerm=1;
551  while (ipd<maxPrimDen) {
552  if (DEN[ipd]!=0) {
553  cout << PRIMES[ipd] << "^" << DEN[ipd];
554  FirstTerm=0;
555  }
556  for (Int_t jj=0; jj<DEN[ipd]; jj++) den *= PRIMES[ipd];
557  ipd++;
558  if (!FirstTerm && ipd<maxPrimDen && DEN[ipd]!=0) cout << " * ";
559  }
560  cout << " = " << den << endl;
561  cout << "NOM_INT="<<NOM_INT<<endl;
562  cout << "DEN_INT="<<DEN_INT<<endl;
563  cout << "dvalue="<<dvalue<<endl;
564  return Double_t(sign_prefac)*Double_t(nom)/Double_t(den);
565 }
566 
567 Double_t
569  cerr << "nom prime list: " << maxPrimNom << ",pointer "<< NOM << endl;
570  cerr << "den prime list: " << maxPrimDen << ",pointer "<< DEN << endl;
571  cerr<< "NOM:";
572  for (Int_t i=0; i<maxPrimNom; i++) cerr<<NOM[i]<<","; cerr<<endl;
573  cerr<< "DEN:";
574  for (Int_t i=0; i<maxPrimDen; i++) cerr<<DEN[i]<<","; cerr<<endl;
575  cerr<<"sign_prefac="<<sign_prefac<<endl;
576  if (maxPrimNom<0) {
577  if (sign_prefac<0) cerr << "-";
578  cerr << -maxPrimNom << "/" << -maxPrimDen << endl;
579  return Double_t(sign_prefac)*Double_t(-maxPrimNom)/Double_t(-maxPrimDen);
580  }
581  Int_t integrity=1;
582  for (Int_t i=0; i<maxPrimNom; i++) if (NOM[i]<0 || NOM[i]>1000) integrity=0;
583  for (Int_t i=0; i<maxPrimDen; i++) if (DEN[i]<0 || DEN[i]>1000) integrity=0;
584  if (integrity==0) return -1;
585 
586  Int_t nom=1;
587  Int_t ipn=0;
588  if (sign_prefac<0) cerr << "-NOM = ";
589  else cerr << " NOM = ";
590  Int_t FirstTerm=1;
591  while (ipn<maxPrimNom) {
592  if (NOM[ipn]!=0) {
593  cerr << PRIMES[ipn] << "^" << NOM[ipn];
594  FirstTerm=0;
595  }
596  for (Int_t jj=0; jj<NOM[ipn]; jj++) nom *= PRIMES[ipn];
597  ipn++;
598  if (!FirstTerm && ipn<maxPrimNom && NOM[ipn]!=0) cerr << " * ";
599  }
600  cerr << " = " << nom << endl;
601 
602  Int_t den=1;
603  Int_t ipd=0;
604  cerr << " DEN = ";
605  FirstTerm=1;
606  while (ipd<maxPrimDen) {
607  if (DEN[ipd]!=0) {
608  cerr << PRIMES[ipd] << "^" << DEN[ipd];
609  FirstTerm=0;
610  }
611  for (Int_t jj=0; jj<DEN[ipd]; jj++) den *= PRIMES[ipd];
612  ipd++;
613  if (!FirstTerm && ipd<maxPrimDen && DEN[ipd]!=0) cerr << " * ";
614  }
615  cerr << " = " << den << endl;
616  cerr << "NOM_INT="<<NOM_INT<<endl;
617  cerr << "DEN_INT="<<DEN_INT<<endl;
618  cerr << "dvalue="<<dvalue<<endl;
619  return Double_t(sign_prefac)*Double_t(nom)/Double_t(den);
620 }
621 
622 const char*
624  char *formstr=new char[50];
625  char *fstr=new char[100];
626  if (NOM_INT==0) {
627  sprintf(fstr,"0");
628  }
629  else if (DEN_INT==1) {
630  sprintf(formstr, "%%c%s", IOUTSTRING);
631  sprintf(fstr, formstr, sign_prefac<0 ? '-':'+', NOM_INT);
632  }
633  else {
634  sprintf(formstr, "%%c%s/%s", IOUTSTRING, IOUTSTRING);
635  sprintf(fstr, formstr, sign_prefac<0 ? '-':'+', NOM_INT, DEN_INT);
636  }
637  return fstr;
638 };
639 
640 const char NULLSTRING[1]=""; // workaround CINT warning when sprintf(s,"");
641 
642 const char*
644  char *formstr=new char[50];
645  char *fstr=new char[200];
646  if (NOM_INT==0) {
647  sprintf(fstr, "0");
648  return fstr;
649  }
650  Int_t ipn=0;
651  Int_t SQRT_NOM_INT=1;
652  Int_t NOM_INT_REST=1;
653  while (ipn<maxPrimNom) {
654  for (Int_t jj=0; jj<NOM[ipn]/2; jj++) SQRT_NOM_INT *= PRIMES[ipn];
655  if (NOM[ipn]%2) NOM_INT_REST *= PRIMES[ipn];
656  ipn++;
657  }
658  Int_t ipd=0;
659  Int_t SQRT_DEN_INT=1;
660  Int_t DEN_INT_REST=1;
661  while (ipd<maxPrimDen) {
662  for (Int_t jj=0; jj<DEN[ipd]/2; jj++) SQRT_DEN_INT *= PRIMES[ipd];
663  if (DEN[ipd]%2) DEN_INT_REST *= PRIMES[ipd];
664  ipd++;
665  }
666 
667  char *sqrtstr=new char[100];
668  Bool_t one1=false;
669  Bool_t one2=false;
670  if (SQRT_DEN_INT==1) {
671  if (SQRT_NOM_INT==1) {
672  sprintf(sqrtstr, "%s", NULLSTRING);
673  one1=true;
674  }
675  else {
676  sprintf(formstr, "%s", IOUTSTRING);
677  sprintf(sqrtstr, formstr, SQRT_NOM_INT);
678  }
679  }
680  else {
681  sprintf(formstr, "%s/%s", IOUTSTRING, IOUTSTRING);
682  sprintf(sqrtstr,formstr, SQRT_NOM_INT, SQRT_DEN_INT);
683  }
684 
685  char *reststr=new char[100];
686  if (DEN_INT_REST==1) {
687  if (NOM_INT_REST==1) {
688  sprintf(reststr, "%s", NULLSTRING);
689  one2=true;
690  }
691  else {
692  sprintf(formstr, "%s%s", SQUAREROOT_CHAR, IOUTSTRING);
693  sprintf(reststr, formstr, NOM_INT_REST);
694  }
695  }
696  else {
697  sprintf(formstr, "%s%s/%s", SQUAREROOT_CHAR, IOUTSTRING, IOUTSTRING);
698  sprintf(reststr, formstr, NOM_INT_REST, DEN_INT_REST);
699  }
700 
701  if (one1&&one2) sprintf(sqrtstr,"1");
702  sprintf(fstr,"%c%s%s", sign_prefac<0 ? '-':'+', sqrtstr, reststr);
703  return fstr;
704 };
705 
707  Int_t kappa = (J-m) % 2;
708  cout << "kappa=" << kappa << endl;
709  Int_t nom_ptr[1]={1};
710  TFracNum twofac(kappa, 0, nom_ptr, 0, 1);
711  TFracNum fac1(J+m, 2*J, "factorial");
712  TFracNum fac2(J-m, 1, "factorial");
713  return twofac*fac1*fac2;
714 }
715 
717  Int_t nom_ptr[1]={m0};
718  TFracNum twofac(1, 0, nom_ptr, 0, 1);
719  TFracNum fac1(J+m, 2*J, "factorial");
720  TFracNum fac2(J-m, 1, "factorial");
721  return twofac*fac1*fac2;
722 }
723 
725  if (ell==0) return TFracNum(0,0,0,0,1);
726  Int_t nom_ptr[1]={ell};
727  TFracNum two_to_ell(1, 0, nom_ptr, 0, 1);
728  TFracNum fac1(ell, 1, "factorial");
729  TFracNum fac2(ell, 2*ell, "factorial");
730  return two_to_ell*fac1*fac2;
731 }
732 
734  if (ell==0) return TFracNum(0,0,0,0,1);
735  Int_t nom_ptr[1]={(ell+m0)/2};
736  TFracNum two_to_ell(1, 0, nom_ptr, 0, 1);
737  TFracNum fac1(ell, 1, "factorial");
738  TFracNum fac2(ell, 2*ell, "factorial");
739  return two_to_ell*fac1*fac2;
740 }
741 
743  //return am0_to_J(ell, 0, m0);
744  if (ell==0) return TFracNum(0,0,0,0,1);
745  Int_t nom_ptr[1]={(ell+m0)};
746  TFracNum two_to_ell(1, 0, nom_ptr, 0, 1);
747  TFracNum fac1a(ell, 1, "factorial");
748  TFracNum fac1b(ell, 1, "factorial");
749  TFracNum fac2a(ell, 2*ell, "factorial");
750  TFracNum fac2b(ell, 2*ell, "factorial");
751  return two_to_ell*fac1a*fac1b*fac2a*fac2b;
752 }
753