00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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;
00041
00042 #include <Dcml/decNumber.c>
00043 #include <Dcml/decContext.c>
00044
00045
00046 class DecFloatContext
00047 {
00048 decContext set;
00049 public:
00050
00051 DecFloatContext(int kind=DEC_INIT_BASE)
00052 {
00053 decContextDefault(&set, kind);
00054 set.traps=0;
00055 set.digits=DECNUMDIGITS;
00056 }
00057
00058
00059
00060 void Precision(int digits)
00061 {
00062 set.digits=digits;
00063 }
00064
00065 int 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;
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()
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;
00124 }
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
00152 return result;
00153 }
00154
00155
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
00179 return err;
00180 }
00181
00182
00183 class DecFloat_ {
00184 decNumber d;
00185
00186 public:
00187
00188
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());
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());
00221 }
00222
00223 ~DecFloat_() { }
00224
00225
00226 DecFloat_& operator=(const DecFloat_& _X_)
00227 {
00228 if (this!=&_X_)
00229 {
00230 DecFloat_ a=_X_;
00231 decNumberCopy(&d,&(a.d));
00232
00233 }
00234 return *this;
00235 }
00236
00237 DecFloat_& operator=(int _X_)
00238 {
00239 char *ps = (char*) malloc(10);
00240 sprintf( ps, "%d", _X_);
00241
00242 decNumberFromString(&d, ps, Context.get());
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());
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());
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());
00292 return *this;
00293 }
00294
00295
00296
00297 char * ToChar(int dec) const
00298 {
00299
00300 char * value ;
00301 char chn[DECNUMDIGITS+14];
00302 decNumber p=d;
00303
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());
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());
00320 decNumberRescale(&p, &d, &pp.d,Context.get());
00321 }
00322
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));
00343
00344 strcpy(value, x.data());
00345 }
00346 return value;
00347 }
00348
00349
00350
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
00363 string ToStr() const
00364 {
00365 char str[DECNUMDIGITS+14];
00366 decNumber p=d;
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
00378 string ToStr(int dec) const
00379 {
00380 string value ;
00381 value.append(ToChar(dec));
00382 return value;
00383
00384 }
00385
00386
00387
00388 DecFloat_& operator+=(const DecFloat_& a)
00389 {
00390
00391 DecFloat_ x=a;
00392 decNumberAdd(&d, &d, &(x.d), Context.get());
00393 return *this;
00394 }
00395
00396 DecFloat_& operator-=(const DecFloat_& a)
00397 {
00398 DecFloat_ x=a;
00399 decNumberSubtract(&d, &d, &(x.d), Context.get());
00400 return *this;
00401 }
00402
00403 DecFloat_& operator*=(const DecFloat_& a)
00404 {
00405 DecFloat_ x=a;
00406 decNumberMultiply(&d, &d, &(x.d), Context.get());
00407 return *this;
00408 }
00409
00410 DecFloat_& operator/=(const DecFloat_& a)
00411 {
00412 DecFloat_ x=a;
00413 decNumberDivide(&d, &d, &(x.d), Context.get());
00414 return *this;
00415 }
00416
00417 DecFloat_& operator%=(const DecFloat_& a)
00418 {
00419 DecFloat_ x=a;
00420 decNumberRemainder(&d, &d, &(x.d), Context.get());
00421 return *this;
00422 }
00423
00424 DecFloat_& operator-()
00425 {
00426 decNumber x=d;
00427 decNumberMinus(&d, &x, Context.get());
00428 return *this;
00429 }
00430
00431 DecFloat_& operator+()
00432 {
00433 decNumber x=d;
00434 decNumberPlus(&d, &x, Context.get());
00435 return *this;
00436 }
00437
00438 void Normalize()
00439 {
00440 decNumber x=d;
00441 decNumberNormalize(&d, &x, Context.get());
00442 }
00443
00444 void Quantize(const DecFloat_& a)
00445 {
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 {
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 {
00469 decNumber x=d;
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
00483 friend DecFloat_ abs(const DecFloat_& a);
00484 friend DecFloat_ pow(const DecFloat_& x, const DecFloat_& 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);
00490
00491 };
00492
00493
00494
00495
00496
00497 inline bool operator==(const DecFloat_& lhs, const DecFloat_& rhs)
00498 {
00499 decNumber d, a=lhs.d, b=rhs.d;
00500
00501 decNumberCopy_(&a,&(lhs.d));
00502 decNumberCopy_(&b,&(rhs.d));
00503
00504 decNumberCompare(&d, &a, &b, Context.get());
00505
00506 return decNumberIsZero(&d)==1;
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;
00515
00516 decNumberCopy_(&a,&(lhs.d));
00517 decNumberCopy_(&b,&(rhs.d));
00518
00519 decNumberCompare(&d, &a, &b, Context.get());
00520
00521 return (decNumberIsNegative(&d)==1) && (decNumberIsZero(&d)!=1);
00522 }
00523
00524
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)
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)
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)
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)
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)
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();
00638 decNumberFromString(&(b.d), ps, Context.get());
00639 return f;
00640 }
00641
00642 typedef DecFloat_ DCML;
00643
00644
00645 #endif