P:/wx_LIB/Dcml/DecFloat.hpp

Aller à la documentation de ce fichier.
00001 /* Split into .h and a .cpp files later. RK
00002   http://www.rkaiser.de/rkaiser/DecFPClass/test_rk_cpp.html
00003   auteur de Decimal floating-point class
00004 Decimal floating-point class
00005 
00006 
00007 cela ma beaucoup aidé a comprendre les définitions de class avec opérateur,
00008 de plus je fais un mémoire  (document)  ce rapportant  sur  la  donnée  (field)
00009 a l'interieur  d'un programme
00010 les problèmes rencontrés, via disque / écran / liste / interne programme.
00011 comment véhiculer cette zone et comment accéder d'une manière simple.
00012 pour une validation d'acquis (diplôme)
00013 
00014 je vous remercie encore pour tout le travail que vous avez fais
00015 je mentionnerai sauf si vous n'êtes pas d'accord votre site et nom comme référence.
00016 translat....
00017 that my helped much has to include/understand the definitions of class with operator,
00018 moreover I make a report (document) this paying on the data (field) has the interior
00019 of a program the encountered problems, via disc/screen/list/intern programs how
00020 to convey this zone and how to reach in a simple way for a validation
00021 of asset (diploma) I still thank you for all the work which you have
00022 make I will mention except if you do not agree your site and name like reference.
00023 */
00024 
00025 //=============================================================================
00026 //=============================================================================
00027 //=============================================================================
00028 
00029 #ifndef __DecFloat_hpp__
00030 #define __DecFloat_hpp__
00031 
00032 #include <cstring>
00033 #include <stdlib.h>
00034 #include <iostream>
00035 #include <sstream>
00036  using namespace std;
00037 #define  DECNUMDIGITS 128            // work with up to 128 digits
00038 #define  DEC_English  56             // English wxLANGUAGE_ENGLISH wxwidgets "."
00039 #define  DEC_French   78             // French  wxLANGUAGE_FRENCH  wxwidgets ","
00040 int _EnFr_ = DEC_English;            // constant 0 = English  1 = French
00041 
00042 #include <Dcml/decNumber.c>
00043 #include <Dcml/decContext.c>
00044 
00045 
00046 class DecFloatContext // context wrapper class
00047 {
00048   decContext set;
00049  public:
00050 
00051   DecFloatContext(int kind=DEC_INIT_BASE)  // see decContext.c
00052   {
00053   decContextDefault(&set, kind);
00054   set.traps=0; // no traps, thank you
00055   set.digits=DECNUMDIGITS; // set precision
00056   }
00057 
00058   // set-functions with parameters and get-functions without ???
00059 
00060   void Precision(int digits) // set precision
00061   {
00062   set.digits=digits;
00063   }
00064 
00065   int Precision()            // get precision
00066   {
00067   return set.digits;
00068   }
00069 
00070   void setClamp(int x)
00071   {
00072   set.clamp=x;
00073   }
00074 
00075 #if DECSUBSET
00076   void setExtended(int e)
00077   {
00078   set.extended=e;
00079   }
00080 #endif
00081 
00082   void setRoundMode(rounding m)
00083   {
00084   set.round=m;         // set precision
00085   }
00086 
00087   void setMaxExponent(int e)
00088   {
00089   set.emax=e;
00090   }
00091 
00092   void setMinExponent(int e)
00093   {
00094   set.emin=e;
00095   }
00096 
00097   decContext* get()
00098   {
00099   return &set;
00100   }
00101 
00102   uint32_t status()
00103   {
00104   return set.status;
00105   }
00106 
00107   string StatusToString() // is the global function from below better???
00108   {
00109 const  char* s = decContextStatusToString(&set);
00110   return s;
00111   }
00112 
00113   bool Conversion_syntax_status()
00114   {
00115   return set.status&DEC_Conversion_syntax;
00116   }
00117   void Clear_Conversion_syntax_status()
00118   {
00119   set.status&=(~(set.status&DEC_Conversion_syntax));
00120   }
00121   void ClearStatus()
00122   {
00123   set.status=0; // to do: allow only to clear permitted flags, see p. 18
00124   }             //        get individual status flags
00125 };
00126 
00127 
00128 DecFloatContext Context(DEC_INIT_DECIMAL128);
00129 
00130 
00131 string DecContextStatusString()
00132 {
00133 int status=Context.status();
00134 string result;
00135 if (status&DEC_Conversion_syntax    ) result+=string(DEC_Condition_CS)+"; ";
00136 if (status&DEC_Division_by_zero     ) result+=string(DEC_Condition_DZ)+"; ";
00137 if (status&DEC_Division_impossible  ) result+=string(DEC_Condition_DI)+"; ";
00138 if (status&DEC_Division_undefined   ) result+=string(DEC_Condition_DU)+"; ";
00139 if (status&DEC_Inexact              ) result+=string(DEC_Condition_IE)+"; ";
00140 if (status&DEC_Insufficient_storage ) result+=string(DEC_Condition_IS)+"; ";
00141 if (status&DEC_Invalid_context      ) result+=string(DEC_Condition_IC)+"; ";
00142 if (status&DEC_Invalid_operation    ) result+=string(DEC_Condition_IO)+"; ";
00143 #if DECSUBSET
00144 if (status&DEC_Lost_digits          ) result+=string(DEC_Condition_LD)+"; ";
00145 #endif
00146 if (status&DEC_Overflow             ) result+=string(DEC_Condition_OV)+"; ";
00147 if (status&DEC_Clamped              ) result+=string(DEC_Condition_PA)+"; ";
00148 if (status&DEC_Rounded              ) result+=string(DEC_Condition_RO)+"; ";
00149 if (status&DEC_Subnormal            ) result+=string(DEC_Condition_SU)+"; ";
00150 if (status&DEC_Underflow            ) result+=string(DEC_Condition_UN)+"; ";
00151 //if (status&0                        ) result+=string(DEC_Condition_ZE)+";;
00152 return result;
00153 }
00154 
00155 //******* rtv_status   true = err      false = ok
00156 
00157 bool DecErrStatus()
00158 {
00159 int status=Context.status();
00160 bool err = false;
00161 if (status&DEC_Conversion_syntax    ) err = true;
00162 if (status&DEC_Division_by_zero     ) err = true;
00163 if (status&DEC_Division_impossible  ) err = true;
00164 if (status&DEC_Division_undefined   ) err = true;
00165 if (status&DEC_Inexact              ) err = true;
00166 if (status&DEC_Insufficient_storage ) err = true;
00167 if (status&DEC_Invalid_context      ) err = true;
00168 if (status&DEC_Invalid_operation    ) err = true;
00169 
00170 #if DECSUBSET
00171 if (status&DEC_Lost_digits          ) err = true;
00172 #endif
00173 if (status&DEC_Overflow             ) err = true;
00174 if (status&DEC_Clamped              ) err = true;
00175 if (status&DEC_Rounded              ) err = true;
00176 if (status&DEC_Subnormal            ) err = true;
00177 if (status&DEC_Underflow            ) err = true;
00178 //if (status&0                        ) result+=string(DEC_Condition_ZE)+";;
00179 return err;
00180 }
00181 //*** Jean-Pierre  Laroche *********************************************
00182 
00183 class DecFloat_ {     // decimal floating-point wrapper class
00184   decNumber d;
00185 
00186  public:
00187 
00188  // constructors and destructors
00189   DecFloat_()
00190 
00191   {
00192   decNumberZero(&d);
00193   }
00194 
00195   DecFloat_(const char* _X_)
00196   {
00197     string Str;
00198     Str.assign(_X_);
00199     int loc ;
00200     loc = Str.rfind( ".", Str.length());
00201          if(loc < 0) loc = Str.rfind( ",", Str.length());
00202      if(loc > 0) {
00203     if ( _EnFr_ == DEC_English ) Str.replace(loc, 1, ".");
00204     if ( _EnFr_ == DEC_French ) Str.replace(loc, 1, ",");
00205      }
00206   decNumberFromString(&d, (char*)Str.c_str(), Context.get()); // cast -- nicht gut ???
00207   }
00208 
00209   DecFloat_(const string& _X_)
00210   {
00211           int loc ;
00212    string Str = _X_;
00213     loc = Str.rfind( ".", Str.length());
00214          if(loc < 0) loc = Str.rfind( ",", Str.length());
00215      if(loc > 0) {
00216     if ( _EnFr_ == DEC_English ) Str.replace(loc, 1, ".");
00217     if ( _EnFr_ == DEC_French ) Str.replace(loc, 1, ",");
00218      }
00219 
00220   decNumberFromString(&d, (char*)Str.c_str(), Context.get()); // cast -- nicht gut ???
00221   }
00222 
00223   ~DecFloat_()   { }
00224 
00225  // assignments
00226   DecFloat_& operator=(const DecFloat_& _X_)
00227   { // is this necessary ???
00228   if (this!=&_X_)
00229     {
00230       DecFloat_ a=_X_; // nur notwendig, weil Parameter nicht const
00231       decNumberCopy(&d,&(a.d));
00232 
00233     }
00234   return *this;
00235   }
00236 // chg basique fonction original
00237   DecFloat_& operator=(int _X_)
00238   {
00239   char *ps = (char*) malloc(10);
00240   sprintf( ps, "%d", _X_);
00241 
00242   decNumberFromString(&d, ps, Context.get()); // cast -- nicht gut ???
00243 
00244   return *this;
00245   }
00246 
00247   DecFloat_& operator=(double _X_)
00248   {
00249   char *ps = (char*) malloc(30);
00250   sprintf( ps, "%f", _X_);
00251     string Str;
00252     Str.assign(ps);
00253     int loc ;
00254     loc = Str.rfind( ".", Str.length());
00255          if(loc < 0) loc = Str.rfind( ",", Str.length());
00256      if(loc > 0) {
00257     if ( _EnFr_ == DEC_English ) Str.replace(loc, 1, ".");
00258     if ( _EnFr_ == DEC_French ) Str.replace(loc, 1, ",");
00259      }
00260 
00261   decNumberFromString(&d, ps, Context.get()); // cast -- nicht gut ???
00262 
00263   return *this;
00264   }
00265   DecFloat_& operator=(const char* _X_)
00266   {
00267           string Str;
00268     Str.assign(_X_);
00269     int loc ;
00270     loc = Str.rfind( ".", Str.length());
00271          if(loc < 0) loc = Str.rfind( ",", Str.length());
00272      if(loc > 0) {
00273     if ( _EnFr_ == DEC_English ) Str.replace(loc, 1, ".");
00274     if ( _EnFr_ == DEC_French ) Str.replace(loc, 1, ",");
00275      }
00276 
00277   decNumberFromString(&d, (char*)Str.c_str(), Context.get()); // cast -- nicht gut ???
00278   return *this;
00279   }
00280   DecFloat_& operator=(const string _X_)
00281   {
00282           int loc ;
00283    string Str = _X_;
00284     loc = Str.rfind( ".", Str.length());
00285          if(loc < 0) loc = Str.rfind( ",", Str.length());
00286      if(loc > 0) {
00287     if ( _EnFr_ == DEC_English ) Str.replace(loc, 1, ".");
00288     if ( _EnFr_ == DEC_French ) Str.replace(loc, 1, ",");
00289      }
00290 
00291   decNumberFromString(&d, (char*)Str.c_str(), Context.get()); // cast -- nicht gut ???
00292   return *this;
00293   }
00294 //*********************************************************************
00295 //***************** BEGIN JPL *****************************************
00296 // JPL ------------- avec arrondi ----- // Tronc avec -1---------------
00297  char *  ToChar(int dec) const
00298   {
00299 
00300   char * value ;
00301   char chn[DECNUMDIGITS+14]; // conversion buffer
00302   decNumber p=d; // only necessary because of non const parameter
00303  /* rescale */
00304 
00305  if(dec >0) {
00306    DecFloat_  pp ;
00307 
00308    char * s ;
00309    s = (char*) malloc(dec+1);
00310    sprintf(s,"%d",(dec*-1));
00311   decNumberFromString(&pp.d,s , Context.get()); // cast
00312   decNumberRescale(&p, &d, &pp.d,Context.get());
00313  }
00314  if(dec ==0) {
00315    DecFloat_  pp ;
00316    char * s ;
00317    s = (char*) malloc(dec+1);
00318    sprintf(s,"%d",dec);
00319   decNumberFromString(&pp.d,s , Context.get()); // cast
00320 decNumberRescale(&p, &d, &pp.d,Context.get());
00321  }
00322  /* end rescale */
00323 
00324 decNumberToEngString(&p, chn);
00325 
00326    string x  =chn;
00327       int loc;
00328  loc = x.rfind( ".", strlen(chn) );
00329 
00330 
00331 value = (char*) malloc( strlen(chn) );
00332  if(dec >0 and loc > 0) {
00333     if ( _EnFr_ == DEC_English ) x.replace(loc, 1, ".");
00334     if ( _EnFr_ == DEC_French ) x.replace(loc, 1, ",");
00335  x.erase(loc+dec+1, x.length()-(loc+dec));
00336  sprintf(value,"%s",x.data());
00337  } else {
00338   if( loc > 0) {
00339     if ( _EnFr_ == DEC_English ) x.replace(loc, 1, ".");
00340     if ( _EnFr_ == DEC_French ) x.replace(loc, 1, ",");
00341   }
00342    if( dec == -1)   x.erase(loc+dec+1, x.length()-(loc+dec)); // Tronc avec -1
00343 
00344     strcpy(value, x.data());
00345  }
00346   return value;
00347   }
00348 
00349 
00350 // JPL ------------- idem string -------------------------------
00351    char *  ToChar() const
00352   {
00353   char * value ;
00354   string x ;
00355   x  = ToStr();
00356   value = (char*) malloc( x.length());
00357    sprintf(value,"%s",x.data());
00358     return value;
00359   }
00360 
00361 
00362 // JPL --------------------------------------------
00363   string ToStr() const
00364   {
00365   char str[DECNUMDIGITS+14]; // conversion buffer
00366   decNumber p=d; // only necessary because of non const parameter
00367   decNumberToEngString(&p, str);
00368   string value  =str;
00369   int loc;
00370   loc = value.rfind( ".", strlen(str) );
00371     if( loc > 0) {
00372     if ( _EnFr_ == DEC_English )  value.replace(loc, 1, ".");
00373     if ( _EnFr_ == DEC_French )  value.replace(loc, 1, ",");
00374   }
00375     return  value;
00376   }
00377 // JPL --------------------------------------------
00378   string ToStr(int dec) const
00379   {
00380     string  value  ;
00381      value.append(ToChar(dec));
00382  return value;
00383 
00384   }
00385 //********************** END JPL *******************************
00386 //**************************************************************
00387 
00388   DecFloat_& operator+=(const DecFloat_& a)
00389   {
00390 
00391   DecFloat_ x=a;
00392   decNumberAdd(&d, &d, &(x.d), Context.get());            // a=a+b
00393   return *this;
00394   }
00395 
00396   DecFloat_& operator-=(const DecFloat_& a)
00397   {
00398   DecFloat_ x=a;
00399   decNumberSubtract(&d, &d, &(x.d), Context.get());       // a=a-b
00400   return *this;
00401   }
00402 
00403   DecFloat_& operator*=(const DecFloat_& a)
00404   {
00405   DecFloat_ x=a;
00406   decNumberMultiply(&d, &d, &(x.d), Context.get());            // a=a+b
00407   return *this;
00408   }
00409 
00410   DecFloat_& operator/=(const DecFloat_& a)
00411   {
00412   DecFloat_ x=a;
00413   decNumberDivide(&d, &d, &(x.d), Context.get());            // a=a/b
00414   return *this;
00415   }
00416 
00417   DecFloat_& operator%=(const DecFloat_& a)
00418   {
00419   DecFloat_ x=a;
00420   decNumberRemainder(&d, &d, &(x.d), Context.get());            // a=a%b
00421   return *this;
00422   }
00423 
00424   DecFloat_& operator-()
00425   { //??? member function or global function or both
00426   decNumber x=d;
00427   decNumberMinus(&d, &x, Context.get());            // -a
00428   return *this;
00429   }
00430 
00431   DecFloat_& operator+()
00432   { //??? member function or global function or both
00433   decNumber x=d;
00434   decNumberPlus(&d, &x, Context.get());            // +a
00435   return *this;
00436   }
00437 
00438   void Normalize()
00439   { // ??? member function or global function or both
00440   decNumber x=d; // necessary ???
00441   decNumberNormalize(&d, &x, Context.get());
00442   }
00443 
00444   void Quantize(const DecFloat_& a)
00445   { // ??? member function or global function or both
00446   decNumber x=d;
00447   decNumber y=a.d;
00448   decNumberQuantize(&d, &x, &y,Context.get());
00449   }
00450 
00451   void Rescale( int a)
00452   {
00453   decNumber x=d;
00454   DecFloat_  y ;
00455   y = a;
00456   decNumberRescale(&d, &x, &y.d,Context.get());
00457   }
00458 
00459   bool SameQuantum(const DecFloat_& a)
00460   { // ??? member function or global function or both
00461   decNumber x=d;
00462   decNumber y=a.d, z;
00463   decNumberSameQuantum(&z, &x, &y);
00464   return !decNumberIsZero(&z);
00465   }
00466 
00467   DecFloat_ ToIntegralValue()
00468   { // ??? member function or global function or both
00469   decNumber x=d; // necessary ???
00470   decNumberToIntegralValue(&d, &x, Context.get());
00471   return *this;
00472   }
00473 
00474   void Trim()
00475   {
00476   decNumberTrim(&d);
00477   }
00478 
00479   friend bool operator==(const DecFloat_& q1, const DecFloat_& q2);
00480   friend bool operator< (const DecFloat_& q1, const DecFloat_& q2);
00481   friend istream& operator>>(istream& f, DecFloat_& b);
00482 // ??? besser als Elementfunktion, bzw. auf Basis einer EF
00483   friend DecFloat_ abs(const DecFloat_& a);
00484   friend DecFloat_ pow(const DecFloat_& x, const DecFloat_& y); // x^y
00485   friend DecFloat_ sqrt(const DecFloat_& x);
00486   friend DecFloat_ min(const DecFloat_& x, const DecFloat_& y);
00487   friend DecFloat_ max(const DecFloat_& x, const DecFloat_& y);
00488   friend DecFloat_ DivideInteger(const DecFloat_& x, const DecFloat_& y);
00489   friend DecFloat_ RemainderNear(const DecFloat_& x, const DecFloat_& y); // x^y
00490 
00491 };
00492 
00493 // ??? Diese Funktionen entweder als inline (dann sollten sie Einzeiler sein, was
00494 // konstante Referenzparameter vorausssetzt, oder in eine .h und eine .cpp Datei
00495 // aufteilen
00496 
00497 inline bool operator==(const DecFloat_& lhs, const DecFloat_& rhs)
00498 {
00499 decNumber d, a=lhs.d, b=rhs.d; // // nur notwendig, weil Parameter nicht const
00500 // Is decNumberCopy necessary here?
00501 decNumberCopy_(&a,&(lhs.d));
00502 decNumberCopy_(&b,&(rhs.d));
00503 // Must lhs and rhs have the same context???
00504 decNumberCompare(&d, &a, &b, Context.get());
00505 // returns 0, if a==b
00506 return decNumberIsZero(&d)==1; // returns 1 if d==0
00507 
00508 
00509 }
00510 
00511 inline bool operator<(const DecFloat_& lhs, const DecFloat_& rhs)
00512 {
00513 
00514 decNumber d, a=lhs.d, b=rhs.d; // // nur notwendig, weil Parameter nicht const
00515 // Is decNumberCopy necessary here?
00516 decNumberCopy_(&a,&(lhs.d));
00517 decNumberCopy_(&b,&(rhs.d));
00518 // decNumberCompare(&d, &a, &b, lhs.context.get());
00519 decNumberCompare(&d, &a, &b, Context.get());
00520 // returns 0, if a==b
00521 return (decNumberIsNegative(&d)==1) && (decNumberIsZero(&d)!=1); // returns 1 if d==0
00522 }
00523 
00524 // !=, <=, >, >= derived operators
00525 
00526 inline bool operator!=(const DecFloat_& x, const DecFloat_& y)
00527 {
00528 return !(x == y);
00529 }
00530 
00531 inline bool operator>(const DecFloat_& x, const DecFloat_& y)
00532 {
00533 return y < x;
00534 }
00535 
00536 inline bool operator<=(const DecFloat_& x, const DecFloat_& y)
00537 {
00538 return !(y < x);
00539 }
00540 
00541 inline bool operator>=(const DecFloat_& x, const DecFloat_& y)
00542 {
00543 return !(x < y);
00544 }
00545 
00546 
00547 
00548 inline DecFloat_ operator+(const DecFloat_& a,const DecFloat_& b)
00549 {
00550 DecFloat_ x=a;
00551 return x+=b;
00552 }
00553 
00554 inline DecFloat_ operator*(const DecFloat_& a,const DecFloat_& b)
00555 {
00556 DecFloat_ x=a;
00557 return x*=b;
00558 }
00559 
00560 inline DecFloat_ operator-(const DecFloat_& a,const DecFloat_& b)
00561 {
00562 DecFloat_ x=a;
00563 return x-=b;
00564 }
00565 
00566 inline DecFloat_ operator/(const DecFloat_& a,const DecFloat_& b)
00567 {
00568 DecFloat_ x=a;
00569 return x/=b;
00570 }
00571 
00572 inline DecFloat_ operator%(const DecFloat_& a,const DecFloat_& b)
00573 {
00574 DecFloat_ x=a;
00575 return x%=b;
00576 }
00577 
00578 inline DecFloat_ abs(const DecFloat_& a)
00579 {
00580 DecFloat_ result, x=a;
00581 decNumberAbs(&(result.d), &(x.d), Context.get());
00582 return result;
00583 }
00584 
00585 inline DecFloat_ pow(const DecFloat_& x, const DecFloat_& y) // x^y
00586 {
00587 DecFloat_ result, a=x, b=y;
00588 decNumberPower(&(result.d), &(a.d), &(b.d), Context.get());
00589 return result;
00590 }
00591 
00592 inline DecFloat_ DivideInteger(const DecFloat_& x, const DecFloat_& y) // x^y
00593 {
00594 DecFloat_ result, a=x, b=y;
00595 decNumberDivideInteger(&(result.d), &(a.d), &(b.d), Context.get());
00596 return result;
00597 }
00598 
00599 inline DecFloat_ RemainderNear(const DecFloat_& x, const DecFloat_& y) // x^y
00600 {
00601 DecFloat_ result, a=x, b=y;
00602 decNumberRemainderNear(&(result.d), &(a.d), &(b.d), Context.get());
00603 return result;
00604 }
00605 
00606 inline DecFloat_ min(const DecFloat_& x, const DecFloat_& y) // x^y
00607 {
00608 DecFloat_ result, a=x, b=y;
00609 decNumberMin(&(result.d), &(a.d), &(b.d), Context.get());
00610 return result;
00611 }
00612 
00613 inline DecFloat_ max(const DecFloat_& x, const DecFloat_& y) // x^y
00614 {
00615 DecFloat_ result, a=x, b=y;
00616 decNumberMax(&(result.d), &(a.d), &(b.d), Context.get());
00617 return result;
00618 }
00619 
00620 inline DecFloat_ sqrt(const DecFloat_& x)
00621 {
00622 DecFloat_ result, a=x;
00623 decNumberSquareRoot(&(result.d), &(a.d), Context.get());
00624 return result;
00625 }
00626 
00627 inline ostream& operator<<(ostream& f, const DecFloat_& b)
00628 {
00629 
00630 return f<<b.ToStr();
00631 }
00632 
00633 inline istream& operator>>(istream& f, DecFloat_& b)
00634 {
00635 string s;
00636 f>>s;
00637 char* ps=(char*)s.c_str(); // nur notwendig, weil Parameter nicht const
00638 decNumberFromString(&(b.d), ps, Context.get()); // cast -- nicht gut ???
00639 return f;
00640 }
00641 
00642   typedef DecFloat_ DCML;    // I would prefer this name -- Richard
00643 
00644 
00645 #endif

Généré le Mon Jul 20 18:22:14 2009 pour Decimal par  doxygen 1.5.1-p1