Decimal: Main Page

  • Main Page
  • Namespaces
  • Classes
  • Files

Decimal Documentation

version mise a jour le 20 juillet 2009
les source de GCC sont actuel et validé derniere modif..
j'ai repris le wrapper
je remerci particulierement IBM pour avoir fourni les sources
http://www.alphaworks.ibm.com/tech/decnumber

j'ai inclus
la prise en charge des lanugue English / French point / virgule
 char *  ToChar(int dec)  0= tronc -1 tronc avec arrondi   n = x digits apres "," et arrondi
 char *  ToChar() reel

  string ToStr()  reel
  string ToStr(int dec)   0= tronc -1 tronc avec arrondi   n = x digits apres "," et arrondi

j'ai restructuré les   sources pour y inclure pour plus de cohérence
decNumber.h  ( decNumber  * decNumberCopy_(decNumber* dst, const decNumber* src);)
decNumber.c

DecFloat

pour facilité le jonction avec sqilite3 et db2 wxsqlite3->(excelent) .
cela permet de travailler en compta ect... avec des zones pouvant travailler 128 digits ouffff .....

les Sources d'origine (decimal....) de GCC vient du site open source

le wrapper de Mr kaiser

Puis j'ai réadapté pour plus de simplicité lors de mise à jour du contexte fondamental mathématique

cela ma beaucoup aidé a comprendre les définitions de class avec opérateur,
de plus je fais un mémoire (document) ce rapportant sur la donnée (field) à l'interieur d'un programme
les problèmes rencontrés, via disque / écran / liste / interne programme.
comment véhiculer cette zone et comment accéder d'une manière simple. pour une validation d'acquis (diplôme)

je vous remercie encore pour tout le travail que vous avez fait je mentionnerai sauf si vous n'êtes pas d'accord votre site et nom comme référence.
translat....

The Sources of origin (decimal.....) of GCC comes from the site open source

Mr's kaiser --> wrapper

Then readjusted for more simplicity during update of the fundamental context mathematical

that my helped much has to include/understand the definitions of class with operator, moreover I make a report (document) this paying on the data (field) has the interior of a program the encountered problems, via disc/screen/list/intern programs how to convey this zone and how to reach in a simple way for a validation of asset (diploma) I still thank you for all the work which you have make I will mention except if you do not agree your site and name like reference.

http://www.rkaiser.de/

source http://www.ombrebleu.com/wxsrc/src/ftp/

Dear Jean.Pierre Laroche,

I am not sure whether I fully understood your mail. But if your question is whether I agree to mention my site and name, the answer is yes.

If you speak German, you can mail me in German.

Kind regards
Richard Kaiser


Decimal: Index des espaces de nommage

  • Page principale
  • Espaces de nommage
  • Classes
  • Fichiers

Decimal Liste des espaces de nommage

Liste de tous les espaces de nommage avec une brève description:
std
Généré le Mon Jul 20 18:22:18 2009 pour Decimal par doxygen 1.5.1-p1


Decimal: Liste des classes

  • Fichiers
  • Liste des classes
  • Membres de classe

Decimal Liste des classes

Liste des classes, structures, unions et interfaces avec une brève description :
bcdnum
decContext
DecFloat_
DecFloatContext
decNumber


Decimal: Index des fichiers

  • Liste des fichiers
  • Membres de fichier

Decimal Liste des fichiers

Liste de tous les fichiers avec une brève description :
P:/wx_LIB/Dcml/decContext.c [code]
P:/wx_LIB/Dcml/decContext.h [code]
P:/wx_LIB/Dcml/decDPD.h [code]
P:/wx_LIB/Dcml/DecFloat.hpp [code]
P:/wx_LIB/Dcml/decNumber.c [code]
P:/wx_LIB/Dcml/decNumber.h [code]
P:/wx_LIB/Dcml/decNumberLocal.h [code]


Decimal: Référence de l'espace de nommage std

Référence de l'espace de nommage std

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


Decimal: Référence de la structure bcdnum

  • Liste des classes
  • Membres de classe

Référence de la structure bcdnum

#include <decNumberLocal.h>

Liste de tous les membres

Attributs publics

uByte * | msd
uByte * | lsd
uInt | sign
Int | exponent

Description détaillée

Définition à la ligne 293 du fichier decNumberLocal.h.

Documentation des données membres

uByte* bcdnum::msd

Définition à la ligne 294 du fichier decNumberLocal.h.

uByte* bcdnum::lsd

Définition à la ligne 295 du fichier decNumberLocal.h.

uInt bcdnum::sign

Définition à la ligne 296 du fichier decNumberLocal.h.

Int bcdnum::exponent

Définition à la ligne 297 du fichier decNumberLocal.h.

La documentation de cette structure a été générée à partir du fichier suivant :
  • P:/wx_LIB/Dcml/decNumberLocal.h


Decimal: Référence de la structure decContext

  • Liste des classes
  • Membres de classe

Référence de la structure decContext

#include <decContext.h>

Liste de tous les membres

Attributs publics

int32_t | digits
int32_t | emax
int32_t | emin
enum rounding | round
uint32_t | traps
uint32_t | status
uint8_t | clamp

Description détaillée

Définition à la ligne 76 du fichier decContext.h.

Documentation des données membres

int32_t decContext::digits

Définition à la ligne 77 du fichier decContext.h.

Référencé par decAddOp(), decCheckMath(), decCompareOp(), decContextDefault(), decDivideOp(), decExpOp(), decFinalize(), DecFloatContext::DecFloatContext(), decLnOp(), decMultiplyOp(), decNaNs(), decNumberAnd(), decNumberExp(), decNumberFMA(), decNumberFromString(), decNumberInvert(), decNumberLn(), decNumberLog10(), decNumberOr(), decNumberPower(), decNumberReduce(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToIntegralExact(), decNumberXor(), decQuantizeOp(), decSetCoeff(), decSetMaxValue(), decSetOverflow(), decSetSubnormal(), decTrim(), et DecFloatContext::Precision().

int32_t decContext::emax

Définition à la ligne 78 du fichier decContext.h.

Référencé par decAddOp(), decApplyRound(), decCheckMath(), decContextDefault(), decExpOp(), decFinalize(), decLnOp(), decNumberFMA(), decNumberLog10(), decNumberPower(), decNumberScaleB(), decNumberSquareRoot(), decQuantizeOp(), decSetMaxValue(), decSetOverflow(), decTrim(), et DecFloatContext::setMaxExponent().

int32_t decContext::emin

Définition à la ligne 79 du fichier decContext.h.

Référencé par decAddOp(), decCheckMath(), decContextDefault(), decDivideOp(), decExpOp(), decFinalize(), decLnOp(), decNumberFMA(), decNumberLog10(), decNumberPower(), decNumberSquareRoot(), decQuantizeOp(), decSetSubnormal(), et DecFloatContext::setMinExponent().

enum rounding decContext::round

Définition à la ligne 80 du fichier decContext.h.

Référencé par decAddOp(), decApplyRound(), decContextDefault(), decContextGetRounding(), decContextSetRounding(), decLnOp(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPower(), decNumberSquareRoot(), decSetOverflow(), et DecFloatContext::setRoundMode().

uint32_t decContext::traps

Définition à la ligne 81 du fichier decContext.h.

Référencé par decContextDefault(), decContextSetStatus(), DecFloatContext::DecFloatContext(), decNumberToIntegralExact(), et decNumberToIntegralValue().

uint32_t decContext::status

Définition à la ligne 82 du fichier decContext.h.

Référencé par DecFloatContext::Clear_Conversion_syntax_status(), DecFloatContext::ClearStatus(), DecFloatContext::Conversion_syntax_status(), decContextClearStatus(), decContextDefault(), decContextGetStatus(), decContextRestoreStatus(), decContextSaveStatus(), decContextSetStatus(), decContextSetStatusQuiet(), decContextStatusToString(), decContextTestStatus(), decContextZeroStatus(), decNumberToIntegralExact(), decNumberToIntegralValue(), et DecFloatContext::status().

uint8_t decContext::clamp

Définition à la ligne 83 du fichier decContext.h.

Référencé par decContextDefault(), decExpOp(), decFinalize(), decLnOp(), decNumberFromString(), decNumberLog10(), decNumberPower(), decNumberSquareRoot(), decSetOverflow(), decTrim(), et DecFloatContext::setClamp().

La documentation de cette structure a été générée à partir du fichier suivant :
  • P:/wx_LIB/Dcml/decContext.h


Decimal: Référence de la classe DecFloat_

  • Liste des classes
  • Membres de classe

Référence de la classe DecFloat_

#include <DecFloat.hpp>

Liste de tous les membres

Fonctions membres publiques

DecFloat_ ()
DecFloat_ (const char *_X_)
DecFloat_ (const string &_X_)
~DecFloat_ ()
DecFloat_ & | operator= (const DecFloat_ &_X_)
DecFloat_ & | operator= (int _X_)
DecFloat_ & | operator= (double _X_)
DecFloat_ & | operator= (const char *_X_)
DecFloat_ & | operator= (const string _X_)
char * | ToChar (int dec) const
char * | ToChar () const
string | ToStr () const
string | ToStr (int dec) const
DecFloat_ & | operator+= (const DecFloat_ &a)
DecFloat_ & | operator-= (const DecFloat_ &a)
DecFloat_ & | operator *= (const DecFloat_ &a)
DecFloat_ & | operator/= (const DecFloat_ &a)
DecFloat_ & | operator%= (const DecFloat_ &a)
DecFloat_ & operator- ()
DecFloat_ & operator+ ()
void | Normalize ()
void | Quantize (const DecFloat_ &a)
void | Rescale (int a)
bool | SameQuantum (const DecFloat_ &a)
DecFloat_ ToIntegralValue ()
void | Trim ()

Attributs privés

decNumber d

Amis

bool | operator== (const DecFloat_ &q1, const DecFloat_ &q2)
bool | operator< (const DecFloat_ &q1, const DecFloat_ &q2)
istream & | operator>> (istream &f, DecFloat_ &b)
DecFloat_ | abs (const DecFloat_ &a)
DecFloat_ | pow (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | sqrt (const DecFloat_ &x)
DecFloat_ | min (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | max (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | DivideInteger (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | RemainderNear (const DecFloat_ &x, const DecFloat_ &y)

Description détaillée

Définition à la ligne 183 du fichier DecFloat.hpp.

Documentation des contructeurs et destructeur

DecFloat_::DecFloat_ ( ) [inline]

Définition à la ligne 189 du fichier DecFloat.hpp.

Références d, et decNumberZero().

00191   {
00192   decNumberZero(&d);
00193   }

DecFloat_::DecFloat_ ( const char * _X_ ) [inline]

Définition à la ligne 195 du fichier DecFloat.hpp.

Références _EnFr_, Context, d, DEC_English, DEC_French, decNumberFromString(), et DecFloatContext::get().

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   }

DecFloat_::DecFloat_ ( const string & _X_ ) [inline]

Définition à la ligne 209 du fichier DecFloat.hpp.

Références _EnFr_, Context, d, DEC_English, DEC_French, decNumberFromString(), et DecFloatContext::get().

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   }

DecFloat_::~DecFloat_ ( ) [inline]

Définition à la ligne 223 du fichier DecFloat.hpp.

00223 { }

Documentation des fonctions membres

DecFloat_& DecFloat_::operator= ( const DecFloat_ & _X_ ) [inline]

Définition à la ligne 226 du fichier DecFloat.hpp.

Références d, et decNumberCopy().

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   }

DecFloat_& DecFloat_::operator= ( int _X_ ) [inline]

Définition à la ligne 237 du fichier DecFloat.hpp.

Références Context, d, decNumberFromString(), et DecFloatContext::get().

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   }

DecFloat_& DecFloat_::operator= ( double _X_ ) [inline]

Définition à la ligne 247 du fichier DecFloat.hpp.

Références _EnFr_, Context, d, DEC_English, DEC_French, decNumberFromString(), et DecFloatContext::get().

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   }

DecFloat_& DecFloat_::operator= ( const char * _X_ ) [inline]

Définition à la ligne 265 du fichier DecFloat.hpp.

Références _EnFr_, Context, d, DEC_English, DEC_French, decNumberFromString(), et DecFloatContext::get().

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   }

DecFloat_& DecFloat_::operator= ( const string _X_ ) [inline]

Définition à la ligne 280 du fichier DecFloat.hpp.

Références _EnFr_, Context, d, DEC_English, DEC_French, decNumberFromString(), et DecFloatContext::get().

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   }

char* DecFloat_::ToChar ( int dec ) const [inline]

Définition à la ligne 297 du fichier DecFloat.hpp.

Références _EnFr_, Context, d, DEC_English, DEC_French, decNumberFromString(), decNumberRescale(), decNumberToEngString(), DECNUMDIGITS, et DecFloatContext::get().

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   }

char* DecFloat_::ToChar ( ) const [inline]

Définition à la ligne 351 du fichier DecFloat.hpp.

Références ToStr().

Référencé par ToStr().

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   }

string DecFloat_::ToStr ( ) const [inline]

Définition à la ligne 363 du fichier DecFloat.hpp.

Références _EnFr_, d, DEC_English, DEC_French, decNumberToEngString(), et DECNUMDIGITS.

Référencé par operator<<(), et ToChar().

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   }

string DecFloat_::ToStr ( int dec ) const [inline]

Définition à la ligne 378 du fichier DecFloat.hpp.

Références ToChar().

00379   {
00380     string  value  ;
00381      value.append(ToChar(dec));
00382  return value;
00383
00384   }

DecFloat_& DecFloat_::operator+= ( const DecFloat_ & a ) [inline]

Définition à la ligne 388 du fichier DecFloat.hpp.

Références Context, d, decNumberAdd(), et DecFloatContext::get().

00389   {
00390
00391   DecFloat_ x=a;
00392   decNumberAdd(&d, &d, &(x.d), Context.get());            // a=a+b
00393   return *this;
00394   }

DecFloat_& DecFloat_::operator-= ( const DecFloat_ & a ) [inline]

Définition à la ligne 396 du fichier DecFloat.hpp.

Références Context, d, decNumberSubtract(), et DecFloatContext::get().

00397   {
00398   DecFloat_ x=a;
00399   decNumberSubtract(&d, &d, &(x.d), Context.get());       // a=a-b
00400   return *this;
00401   }

DecFloat_& DecFloat_::operator *= ( const DecFloat_ & a ) [inline]

Définition à la ligne 403 du fichier DecFloat.hpp.

Références Context, d, decNumberMultiply(), et DecFloatContext::get().

00404   {
00405   DecFloat_ x=a;
00406   decNumberMultiply(&d, &d, &(x.d), Context.get());            // a=a+b
00407   return *this;
00408   }

DecFloat_& DecFloat_::operator/= ( const DecFloat_ & a ) [inline]

Définition à la ligne 410 du fichier DecFloat.hpp.

Références Context, d, decNumberDivide(), et DecFloatContext::get().

00411   {
00412   DecFloat_ x=a;
00413   decNumberDivide(&d, &d, &(x.d), Context.get());            // a=a/b
00414   return *this;
00415   }

DecFloat_& DecFloat_::operator%= ( const DecFloat_ & a ) [inline]

Définition à la ligne 417 du fichier DecFloat.hpp.

Références Context, d, decNumberRemainder(), et DecFloatContext::get().

00418   {
00419   DecFloat_ x=a;
00420   decNumberRemainder(&d, &d, &(x.d), Context.get());            // a=a%b
00421   return *this;
00422   }

DecFloat_& DecFloat_::operator- ( ) [inline]

Définition à la ligne 424 du fichier DecFloat.hpp.

Références Context, d, decNumberMinus(), et DecFloatContext::get().

00425   { //??? member function or global function or both
00426   decNumber x=d;
00427   decNumberMinus(&d, &x, Context.get());            // -a
00428   return *this;
00429   }

DecFloat_& DecFloat_::operator+ ( ) [inline]

Définition à la ligne 431 du fichier DecFloat.hpp.

Références Context, d, decNumberPlus(), et DecFloatContext::get().

00432   { //??? member function or global function or both
00433   decNumber x=d;
00434   decNumberPlus(&d, &x, Context.get());            // +a
00435   return *this;
00436   }

void DecFloat_::Normalize ( ) [inline]

Définition à la ligne 438 du fichier DecFloat.hpp.

Références Context, d, decNumberNormalize(), et DecFloatContext::get().

00439   { // ??? member function or global function or both
00440   decNumber x=d; // necessary ???
00441   decNumberNormalize(&d, &x, Context.get());
00442   }

void DecFloat_::Quantize ( const DecFloat_ & a ) [inline]

Définition à la ligne 444 du fichier DecFloat.hpp.

Références Context, d, decNumberQuantize(), et DecFloatContext::get().

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   }

void DecFloat_::Rescale ( int a ) [inline]

Définition à la ligne 451 du fichier DecFloat.hpp.

Références Context, d, decNumberRescale(), et DecFloatContext::get().

00452   {
00453   decNumber x=d;
00454   DecFloat_  y ;
00455   y = a;
00456   decNumberRescale(&d, &x, &y.d,Context.get());
00457   }

bool DecFloat_::SameQuantum ( const DecFloat_ & a ) [inline]

Définition à la ligne 459 du fichier DecFloat.hpp.

Références d, decNumberIsZero, et decNumberSameQuantum().

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   }

DecFloat_ DecFloat_::ToIntegralValue ( ) [inline]

Définition à la ligne 467 du fichier DecFloat.hpp.

Références Context, d, decNumberToIntegralValue(), et DecFloatContext::get().

00468   { // ??? member function or global function or both
00469   decNumber x=d; // necessary ???
00470   decNumberToIntegralValue(&d, &x, Context.get());
00471   return *this;
00472   }

void DecFloat_::Trim ( ) [inline]

Définition à la ligne 474 du fichier DecFloat.hpp.

Références d, et decNumberTrim().

00475   {
00476   decNumberTrim(&d);
00477   }

Documentation des fonctions amies et associées

bool operator== | ( | const DecFloat_ & | q1,
 |  | const DecFloat_ & | q2 |
 | ) |  |  | [friend]

Définition à la ligne 497 du fichier DecFloat.hpp.

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 }

bool operator< | ( | const DecFloat_ & | q1,
 |  | const DecFloat_ & | q2 |
 | ) |  |  | [friend]

Définition à la ligne 511 du fichier DecFloat.hpp.

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 }

istream& operator>> | ( | istream & | f,
 |  | DecFloat_ & | b |
 | ) |  |  | [friend]

Définition à la ligne 633 du fichier DecFloat.hpp.

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 }

DecFloat_ abs ( const DecFloat_ & a ) [friend]

Définition à la ligne 578 du fichier DecFloat.hpp.

00579 {
00580 DecFloat_ result, x=a;
00581 decNumberAbs(&(result.d), &(x.d), Context.get());
00582 return result;
00583 }

DecFloat_ pow | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [friend]

Définition à la ligne 585 du fichier DecFloat.hpp.

00586 {
00587 DecFloat_ result, a=x, b=y;
00588 decNumberPower(&(result.d), &(a.d), &(b.d), Context.get());
00589 return result;
00590 }

DecFloat_ sqrt ( const DecFloat_ & x ) [friend]

Définition à la ligne 620 du fichier DecFloat.hpp.

00621 {
00622 DecFloat_ result, a=x;
00623 decNumberSquareRoot(&(result.d), &(a.d), Context.get());
00624 return result;
00625 }

DecFloat_ min | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [friend]

Définition à la ligne 606 du fichier DecFloat.hpp.

00607 {
00608 DecFloat_ result, a=x, b=y;
00609 decNumberMin(&(result.d), &(a.d), &(b.d), Context.get());
00610 return result;
00611 }

DecFloat_ max | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [friend]

Définition à la ligne 613 du fichier DecFloat.hpp.

00614 {
00615 DecFloat_ result, a=x, b=y;
00616 decNumberMax(&(result.d), &(a.d), &(b.d), Context.get());
00617 return result;
00618 }

DecFloat_ DivideInteger | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [friend]

Définition à la ligne 592 du fichier DecFloat.hpp.

00593 {
00594 DecFloat_ result, a=x, b=y;
00595 decNumberDivideInteger(&(result.d), &(a.d), &(b.d), Context.get());
00596 return result;
00597 }

DecFloat_ RemainderNear | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [friend]

Définition à la ligne 599 du fichier DecFloat.hpp.

00600 {
00601 DecFloat_ result, a=x, b=y;
00602 decNumberRemainderNear(&(result.d), &(a.d), &(b.d), Context.get());
00603 return result;
00604 }

Documentation des données membres

decNumber DecFloat_::d [private]

Définition à la ligne 184 du fichier DecFloat.hpp.

Référencé par abs(), DecFloat_(), DivideInteger(), max(), min(), Normalize(), operator *=(), operator%=(), operator+(), operator+=(), operator-(), operator-=(), operator/=(), operator<(), operator=(), operator==(), operator>>(), pow(), Quantize(), RemainderNear(), Rescale(), SameQuantum(), sqrt(), ToChar(), ToIntegralValue(), ToStr(), et Trim().

La documentation de cette classe a été générée à partir du fichier suivant :
  • P:/wx_LIB/Dcml/DecFloat.hpp


Decimal: Référence de la classe DecFloatContext

  • Liste des classes
  • Membres de classe

Référence de la classe DecFloatContext

#include <DecFloat.hpp>

Liste de tous les membres

Fonctions membres publiques

DecFloatContext (int kind=DEC_INIT_BASE)
void | Precision (int digits)
int | Precision ()
void | setClamp (int x)
void | setRoundMode (rounding m)
void | setMaxExponent (int e)
void | setMinExponent (int e)
decContext * get ()
uint32_t | status ()
string | StatusToString ()
bool | Conversion_syntax_status ()
void | Clear_Conversion_syntax_status ()
void | ClearStatus ()

Attributs privés

decContext set

Description détaillée

Définition à la ligne 46 du fichier DecFloat.hpp.

Documentation des contructeurs et destructeur

DecFloatContext::DecFloatContext ( int kind = DEC_INIT_BASE ) [inline]

Définition à la ligne 51 du fichier DecFloat.hpp.

Références decContextDefault(), DECNUMDIGITS, decContext::digits, set, et decContext::traps.

00052   {
00053   decContextDefault(&set, kind);
00054   set.traps=0; // no traps, thank you
00055   set.digits=DECNUMDIGITS; // set precision
00056   }

Documentation des fonctions membres

void DecFloatContext::Precision ( int digits ) [inline]

Définition à la ligne 60 du fichier DecFloat.hpp.

Références decContext::digits, et set.

00061   {
00062   set.digits=digits;
00063   }

int DecFloatContext::Precision ( ) [inline]

Définition à la ligne 65 du fichier DecFloat.hpp.

Références decContext::digits, et set.

00066   {
00067   return set.digits;
00068   }

void DecFloatContext::setClamp ( int x ) [inline]

Définition à la ligne 70 du fichier DecFloat.hpp.

Références decContext::clamp, et set.

00071   {
00072   set.clamp=x;
00073   }

void DecFloatContext::setRoundMode ( rounding m ) [inline]

Définition à la ligne 82 du fichier DecFloat.hpp.

Références decContext::round, et set.

00083   {
00084   set.round=m;         // set precision
00085   }

void DecFloatContext::setMaxExponent ( int e ) [inline]

Définition à la ligne 87 du fichier DecFloat.hpp.

Références decContext::emax, et set.

00088   {
00089   set.emax=e;
00090   }

void DecFloatContext::setMinExponent ( int e ) [inline]

Définition à la ligne 92 du fichier DecFloat.hpp.

Références decContext::emin, et set.

00093   {
00094   set.emin=e;
00095   }

decContext* DecFloatContext::get ( ) [inline]

Définition à la ligne 97 du fichier DecFloat.hpp.

Références set.

Référencé par abs(), DecFloat_::DecFloat_(), DivideInteger(), max(), min(), DecFloat_::Normalize(), DecFloat_::operator *=(), DecFloat_::operator%=(), DecFloat_::operator+(), DecFloat_::operator+=(), DecFloat_::operator-(), DecFloat_::operator-=(), DecFloat_::operator/=(), operator<(), DecFloat_::operator=(), operator==(), operator>>(), pow(), DecFloat_::Quantize(), RemainderNear(), DecFloat_::Rescale(), sqrt(), DecFloat_::ToChar(), et DecFloat_::ToIntegralValue().

00098   {
00099   return &set;
00100   }

uint32_t DecFloatContext::status ( ) [inline]

Définition à la ligne 102 du fichier DecFloat.hpp.

Références set, et decContext::status.

Référencé par DecContextStatusString(), et DecErrStatus().

00103   {
00104   return set.status;
00105   }

string DecFloatContext::StatusToString ( ) [inline]

Définition à la ligne 107 du fichier DecFloat.hpp.

Références decContextStatusToString(), et set.

00108   {
00109 const  char* s = decContextStatusToString(&set);
00110   return s;
00111   }

bool DecFloatContext::Conversion_syntax_status ( ) [inline]

Définition à la ligne 113 du fichier DecFloat.hpp.

Références DEC_Conversion_syntax, set, et decContext::status.

00114   {
00115   return set.status&DEC_Conversion_syntax;
00116   }

void DecFloatContext::Clear_Conversion_syntax_status ( ) [inline]

Définition à la ligne 117 du fichier DecFloat.hpp.

Références DEC_Conversion_syntax, set, et decContext::status.

00118   {
00119   set.status&=(~(set.status&DEC_Conversion_syntax));
00120   }

void DecFloatContext::ClearStatus ( ) [inline]

Définition à la ligne 121 du fichier DecFloat.hpp.

Références set, et decContext::status.

00122   {
00123   set.status=0; // to do: allow only to clear permitted flags, see p. 18
00124   }             //        get individual status flags

Documentation des données membres

decContext DecFloatContext::set [private]

Définition à la ligne 48 du fichier DecFloat.hpp.

Référencé par Clear_Conversion_syntax_status(), ClearStatus(), Conversion_syntax_status(), DecFloatContext(), get(), Precision(), setClamp(), setMaxExponent(), setMinExponent(), setRoundMode(), status(), et StatusToString().

La documentation de cette classe a été générée à partir du fichier suivant :
  • P:/wx_LIB/Dcml/DecFloat.hpp


Decimal: Référence de la structure decNumber

  • Liste des classes
  • Membres de classe

Référence de la structure decNumber

#include <decNumber.h>

Liste de tous les membres

Attributs publics

int32_t | digits
int32_t | exponent
uint8_t | bits
decNumberUnit | lsu [DECNUMUNITS]

Description détaillée

Définition à la ligne 69 du fichier decNumber.h.

Documentation des données membres

int32_t decNumber::digits

Définition à la ligne 70 du fichier decNumber.h.

Référencé par decAddOp(), decApplyRound(), decCheckMath(), decCompare(), decCompareOp(), decCopyFit(), decDecap(), decDivideOp(), decExpOp(), decFinalize(), decGetInt(), decLnOp(), decMultiplyOp(), decNaNs(), decNumberAnd(), decNumberCompareTotalMag(), decNumberCopy(), decNumberExp(), decNumberFMA(), decNumberFromUInt32(), decNumberGetBCD(), decNumberInvert(), decNumberIsNormal(), decNumberIsSubnormal(), decNumberLn(), decNumberLog10(), decNumberLogB(), decNumberOr(), decNumberPower(), decNumberReduce(), decNumberSetBCD(), decNumberSquareRoot(), decNumberToInt32(), decNumberToIntegralExact(), decNumberToUInt32(), decNumberXor(), decNumberZero(), decQuantizeOp(), decSetCoeff(), decSetMaxValue(), decSetSubnormal(), decToString(), et decTrim().

int32_t decNumber::exponent

Définition à la ligne 71 du fichier decNumber.h.

Référencé par decAddOp(), decApplyRound(), decCheckMath(), decCompare(), decCompareOp(), decCopyFit(), decDivideOp(), decExpOp(), decFinalize(), decGetInt(), decLnOp(), decMultiplyOp(), decNaNs(), decNumberAbs(), decNumberAnd(), decNumberCopy(), decNumberInvert(), decNumberIsNormal(), decNumberIsSubnormal(), decNumberLog10(), decNumberLogB(), decNumberMinus(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberOr(), decNumberPlus(), decNumberPower(), decNumberRotate(), decNumberSameQuantum(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToInt32(), decNumberToIntegralExact(), decNumberToUInt32(), decNumberXor(), decNumberZero(), decQuantizeOp(), decSetCoeff(), decSetMaxValue(), decSetOverflow(), decSetSubnormal(), decToString(), et decTrim().

uint8_t decNumber::bits

Définition à la ligne 73 du fichier decNumber.h.

Référencé par decAddOp(), decCompare(), decCompareOp(), decCopyFit(), decDivideOp(), decLnOp(), decMultiplyOp(), decNaNs(), decNumberAbs(), decNumberAnd(), decNumberCompareTotalMag(), decNumberCopy(), decNumberCopyAbs(), decNumberCopyNegate(), decNumberCopySign(), decNumberFromInt32(), decNumberInvert(), decNumberLog10(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberOr(), decNumberPower(), decNumberSquareRoot(), decNumberToInt32(), decNumberToUInt32(), decNumberXor(), decNumberZero(), decQuantizeOp(), decSetMaxValue(), decSetOverflow(), decStatus(), decToString(), et decTrim().

decNumberUnit decNumber::lsu[DECNUMUNITS]

Définition à la ligne 75 du fichier decNumber.h.

Référencé par decAddOp(), decApplyRound(), decCompare(), decCompareOp(), decCopyFit(), decDecap(), decDivideOp(), decExpOp(), decFinalize(), decGetInt(), decLnOp(), decMultiplyOp(), decNaNs(), decNumberAnd(), decNumberCopy(), decNumberFromUInt32(), decNumberGetBCD(), decNumberInvert(), decNumberLog10(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberOr(), decNumberPower(), decNumberSameQuantum(), decNumberSetBCD(), decNumberSquareRoot(), decNumberToInt32(), decNumberToUInt32(), decNumberXor(), decNumberZero(), decQuantizeOp(), decSetCoeff(), decSetMaxValue(), decSetSubnormal(), decToString(), et decTrim().

La documentation de cette structure a été générée à partir du fichier suivant :
  • P:/wx_LIB/Dcml/decNumber.h


Decimal: Référence du fichier P:/wx_LIB/Dcml/decContext.c

Référence du fichier P:/wx_LIB/Dcml/decContext.c

#include <string.h>
#include <stdio.h>
#include "decContext.h"
#include "decNumberLocal.h"

Aller au code source de ce fichier.

Macros

#define | LITEND *mfctop

Fonctions

decContext * | decContextClearStatus (decContext *context, uInt mask)
decContext * | decContextDefault (decContext *context, Int kind)
enum rounding | decContextGetRounding (decContext *context)
uInt | decContextGetStatus (decContext *context)
decContext * | decContextRestoreStatus (decContext *context, uInt newstatus, uInt mask)
uInt | decContextSaveStatus (decContext *context, uInt mask)
decContext * | decContextSetRounding (decContext *context, enum rounding newround)
decContext * | decContextSetStatus (decContext *context, uInt status)
decContext * | decContextSetStatusFromString (decContext *context, const char *string)
decContext * | decContextSetStatusFromStringQuiet (decContext *context, const char *string)
decContext * | decContextSetStatusQuiet (decContext *context, uInt status)
const char * | decContextStatusToString (const decContext *context)
Int | decContextTestEndian (Flag quiet)
uInt | decContextTestSavedStatus (uInt oldstatus, uInt mask)
uInt | decContextTestStatus (decContext *context, uInt mask)
decContext * | decContextZeroStatus (decContext *context)

Variables

static const Int | mfcone = 1
static const Flag * | mfctop = (Flag *)&mfcone
const uByte | DECSTICKYTAB [10] = {1,1,2,3,4,6,6,7,8,9}
const uInt | DECPOWERS [10]

Documentation des macros

#define LITEND *mfctop

Définition à la ligne 36 du fichier decContext.c.

Référencé par decContextTestEndian().

Documentation des fonctions

decContext* decContextClearStatus | ( | decContext * | context,
 |  | uInt | mask
 | ) |  |

Définition à la ligne 59 du fichier decContext.c.

Références decContext::status.

00059                                                                   {
00060   context->status&=~mask;
00061   return context;
00062   } // decContextClearStatus

decContext* decContextDefault | ( | decContext * | context,
 |  | Int | kind
 | ) |  |

Définition à la ligne 77 du fichier decContext.c.

Références decContext::clamp, DEC_Errors, DEC_INIT_BASE, DEC_INIT_DECIMAL128, DEC_INIT_DECIMAL32, DEC_INIT_DECIMAL64, DEC_Invalid_operation, DEC_MAX_EMAX, DEC_MIN_EMIN, DEC_ROUND_HALF_EVEN, DEC_ROUND_HALF_UP, decContextSetStatus(), decContext::digits, decContext::emax, decContext::emin, decContext::round, decContext::status, et decContext::traps.

Référencé par decExpOp(), DecFloatContext::DecFloatContext(), decLnOp(), decNumberLog10(), decNumberPower(), decNumberSquareRoot(), et decNumberTrim().

00077                                                               {
00078   // set defaults...
00079   context->digits=9;                         // 9 digits
00080   context->emax=DEC_MAX_EMAX;                // 9-digit exponents
00081   context->emin=DEC_MIN_EMIN;                // .. balanced
00082   context->round=DEC_ROUND_HALF_UP;          // 0.5 rises
00083   context->traps=DEC_Errors;                 // all but informational
00084   context->status=0;                         // cleared
00085   context->clamp=0;                          // no clamping
00086   #if DECSUBSET
00087   context->extended=0;                       // cleared
00088   #endif
00089   switch (kind) {
00090     case DEC_INIT_BASE:
00091       // [use defaults]
00092       break;
00093     case DEC_INIT_DECIMAL32:
00094       context->digits=7;                     // digits
00095       context->emax=96;                      // Emax
00096       context->emin=-95;                     // Emin
00097       context->round=DEC_ROUND_HALF_EVEN;    // 0.5 to nearest even
00098       context->traps=0;                      // no traps set
00099       context->clamp=1;                      // clamp exponents
00100       #if DECSUBSET
00101       context->extended=1;                   // set
00102       #endif
00103       break;
00104     case DEC_INIT_DECIMAL64:
00105       context->digits=16;                    // digits
00106       context->emax=384;                     // Emax
00107       context->emin=-383;                    // Emin
00108       context->round=DEC_ROUND_HALF_EVEN;    // 0.5 to nearest even
00109       context->traps=0;                      // no traps set
00110       context->clamp=1;                      // clamp exponents
00111       #if DECSUBSET
00112       context->extended=1;                   // set
00113       #endif
00114       break;
00115     case DEC_INIT_DECIMAL128:
00116       context->digits=34;                    // digits
00117       context->emax=6144;                    // Emax
00118       context->emin=-6143;                   // Emin
00119       context->round=DEC_ROUND_HALF_EVEN;    // 0.5 to nearest even
00120       context->traps=0;                      // no traps set
00121       context->clamp=1;                      // clamp exponents
00122       #if DECSUBSET
00123       context->extended=1;                   // set
00124       #endif
00125       break;
00126
00127     default:                                 // invalid Kind
00128       // use defaults, and ..
00129       decContextSetStatus(context, DEC_Invalid_operation); // trap
00130     }
00131
00132   return context;} // decContextDefault

enum rounding decContextGetRounding ( decContext * context )

Définition à la ligne 142 du fichier decContext.c.

Références decContext::round.

00142                                                          {
00143   return context->round;
00144   } // decContextGetRounding

uInt decContextGetStatus ( decContext * context )

Définition à la ligne 154 du fichier decContext.c.

Références decContext::status.

00154                                               {
00155   return context->status;
00156   } // decContextGetStatus

decContext* decContextRestoreStatus | ( | decContext * | context,
 |  | uInt | newstatus,
 |  | uInt | mask
 | ) |  |

Définition à la ligne 170 du fichier decContext.c.

Références decContext::status.

00171                                                                {
00172   context->status&=~mask;               // clear the selected bits
00173   context->status|=(mask&newstatus);    // or in the new bits
00174   return context;
00175   } // decContextRestoreStatus

uInt decContextSaveStatus | ( | decContext * | context,
 |  | uInt | mask
 | ) |  |

Définition à la ligne 187 du fichier decContext.c.

Références decContext::status.

00187                                                           {
00188   return context->status&mask;
00189   } // decContextSaveStatus

decContext* decContextSetRounding | ( | decContext * | context,
 |  | enum rounding | newround
 | ) |  |

Définition à la ligne 200 du fichier decContext.c.

Références decContext::round.

00201                                                           {
00202   context->round=newround;
00203   return context;
00204   } // decContextSetRounding

decContext* decContextSetStatus | ( | decContext * | context,
 |  | uInt | status
 | ) |  |

Définition à la ligne 216 du fichier decContext.c.

Références decContext::status, et decContext::traps.

Référencé par decContextDefault(), decContextSetStatusFromString(), decNumberToInt32(), decNumberToUInt32(), et decStatus().

00216                                                                    {
00217   context->status|=status;
00218   if (status & context->traps) raise(SIGFPE);
00219   return context;} // decContextSetStatus

decContext* decContextSetStatusFromString | ( | decContext * | context,
 |  | const char * | string
 | ) |  |

Définition à la ligne 235 du fichier decContext.c.

Références DEC_Clamped, DEC_Condition_CS, DEC_Condition_DI, DEC_Condition_DU, DEC_Condition_DZ, DEC_Condition_IC, DEC_Condition_IE, DEC_Condition_IO, DEC_Condition_IS, DEC_Condition_OV, DEC_Condition_PA, DEC_Condition_RO, DEC_Condition_SU, DEC_Condition_UN, DEC_Condition_ZE, DEC_Conversion_syntax, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_context, DEC_Invalid_operation, DEC_Overflow, DEC_Rounded, DEC_Subnormal, DEC_Underflow, et decContextSetStatus().

00236                                                                {
00237   if (strcmp(string, DEC_Condition_CS)==0)
00238     return decContextSetStatus(context, DEC_Conversion_syntax);
00239   if (strcmp(string, DEC_Condition_DZ)==0)
00240     return decContextSetStatus(context, DEC_Division_by_zero);
00241   if (strcmp(string, DEC_Condition_DI)==0)
00242     return decContextSetStatus(context, DEC_Division_impossible);
00243   if (strcmp(string, DEC_Condition_DU)==0)
00244     return decContextSetStatus(context, DEC_Division_undefined);
00245   if (strcmp(string, DEC_Condition_IE)==0)
00246     return decContextSetStatus(context, DEC_Inexact);
00247   if (strcmp(string, DEC_Condition_IS)==0)
00248     return decContextSetStatus(context, DEC_Insufficient_storage);
00249   if (strcmp(string, DEC_Condition_IC)==0)
00250     return decContextSetStatus(context, DEC_Invalid_context);
00251   if (strcmp(string, DEC_Condition_IO)==0)
00252     return decContextSetStatus(context, DEC_Invalid_operation);
00253   #if DECSUBSET
00254   if (strcmp(string, DEC_Condition_LD)==0)
00255     return decContextSetStatus(context, DEC_Lost_digits);
00256   #endif
00257   if (strcmp(string, DEC_Condition_OV)==0)
00258     return decContextSetStatus(context, DEC_Overflow);
00259   if (strcmp(string, DEC_Condition_PA)==0)
00260     return decContextSetStatus(context, DEC_Clamped);
00261   if (strcmp(string, DEC_Condition_RO)==0)
00262     return decContextSetStatus(context, DEC_Rounded);
00263   if (strcmp(string, DEC_Condition_SU)==0)
00264     return decContextSetStatus(context, DEC_Subnormal);
00265   if (strcmp(string, DEC_Condition_UN)==0)
00266     return decContextSetStatus(context, DEC_Underflow);
00267   if (strcmp(string, DEC_Condition_ZE)==0)
00268     return context;
00269   return NULL;  // Multiple status, or unknown
00270   } // decContextSetStatusFromString

decContext* decContextSetStatusFromStringQuiet | ( | decContext * | context,
 |  | const char * | string
 | ) |  |

Définition à la ligne 286 du fichier decContext.c.

Références DEC_Clamped, DEC_Condition_CS, DEC_Condition_DI, DEC_Condition_DU, DEC_Condition_DZ, DEC_Condition_IC, DEC_Condition_IE, DEC_Condition_IO, DEC_Condition_IS, DEC_Condition_OV, DEC_Condition_PA, DEC_Condition_RO, DEC_Condition_SU, DEC_Condition_UN, DEC_Condition_ZE, DEC_Conversion_syntax, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_context, DEC_Invalid_operation, DEC_Overflow, DEC_Rounded, DEC_Subnormal, DEC_Underflow, et decContextSetStatusQuiet().

00287                                                                     {
00288   if (strcmp(string, DEC_Condition_CS)==0)
00289     return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
00290   if (strcmp(string, DEC_Condition_DZ)==0)
00291     return decContextSetStatusQuiet(context, DEC_Division_by_zero);
00292   if (strcmp(string, DEC_Condition_DI)==0)
00293     return decContextSetStatusQuiet(context, DEC_Division_impossible);
00294   if (strcmp(string, DEC_Condition_DU)==0)
00295     return decContextSetStatusQuiet(context, DEC_Division_undefined);
00296   if (strcmp(string, DEC_Condition_IE)==0)
00297     return decContextSetStatusQuiet(context, DEC_Inexact);
00298   if (strcmp(string, DEC_Condition_IS)==0)
00299     return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
00300   if (strcmp(string, DEC_Condition_IC)==0)
00301     return decContextSetStatusQuiet(context, DEC_Invalid_context);
00302   if (strcmp(string, DEC_Condition_IO)==0)
00303     return decContextSetStatusQuiet(context, DEC_Invalid_operation);
00304   #if DECSUBSET
00305   if (strcmp(string, DEC_Condition_LD)==0)
00306     return decContextSetStatusQuiet(context, DEC_Lost_digits);
00307   #endif
00308   if (strcmp(string, DEC_Condition_OV)==0)
00309     return decContextSetStatusQuiet(context, DEC_Overflow);
00310   if (strcmp(string, DEC_Condition_PA)==0)
00311     return decContextSetStatusQuiet(context, DEC_Clamped);
00312   if (strcmp(string, DEC_Condition_RO)==0)
00313     return decContextSetStatusQuiet(context, DEC_Rounded);
00314   if (strcmp(string, DEC_Condition_SU)==0)
00315     return decContextSetStatusQuiet(context, DEC_Subnormal);
00316   if (strcmp(string, DEC_Condition_UN)==0)
00317     return decContextSetStatusQuiet(context, DEC_Underflow);
00318   if (strcmp(string, DEC_Condition_ZE)==0)
00319     return context;
00320   return NULL;  // Multiple status, or unknown
00321   } // decContextSetStatusFromStringQuiet

decContext* decContextSetStatusQuiet | ( | decContext * | context,
 |  | uInt | status
 | ) |  |

Définition à la ligne 332 du fichier decContext.c.

Références decContext::status.

Référencé par decContextSetStatusFromStringQuiet().

00332                                                                         {
00333   context->status|=status;
00334   return context;} // decContextSetStatusQuiet

const char* decContextStatusToString ( const decContext * context )

Définition à la ligne 344 du fichier decContext.c.

Références DEC_Clamped, DEC_Condition_CS, DEC_Condition_DI, DEC_Condition_DU, DEC_Condition_DZ, DEC_Condition_IC, DEC_Condition_IE, DEC_Condition_IO, DEC_Condition_IS, DEC_Condition_MU, DEC_Condition_OV, DEC_Condition_PA, DEC_Condition_RO, DEC_Condition_SU, DEC_Condition_UN, DEC_Condition_ZE, DEC_Conversion_syntax, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_context, DEC_Invalid_operation, DEC_Overflow, DEC_Rounded, DEC_Subnormal, DEC_Underflow, Int, et decContext::status.

Référencé par DecFloatContext::StatusToString().

00344                                                                 {
00345   Int status=context->status;
00346
00347   // test the five IEEE first, as some of the others are ambiguous when
00348   // DECEXTFLAG=0
00349   if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
00350   if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
00351   if (status==DEC_Overflow             ) return DEC_Condition_OV;
00352   if (status==DEC_Underflow            ) return DEC_Condition_UN;
00353   if (status==DEC_Inexact              ) return DEC_Condition_IE;
00354
00355   if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
00356   if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
00357   if (status==DEC_Rounded              ) return DEC_Condition_RO;
00358   if (status==DEC_Clamped              ) return DEC_Condition_PA;
00359   if (status==DEC_Subnormal            ) return DEC_Condition_SU;
00360   if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
00361   if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
00362   if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
00363   #if DECSUBSET
00364   if (status==DEC_Lost_digits          ) return DEC_Condition_LD;
00365   #endif
00366   if (status==0                        ) return DEC_Condition_ZE;
00367   return DEC_Condition_MU;  // Multiple errors
00368   } // decContextStatusToString

Int decContextTestEndian ( Flag quiet )

Définition à la ligne 382 du fichier decContext.c.

Références DECLITEND, Int, LITEND, et uInt.

00382                                      {
00383   Int res=0;                  // optimist
00384   uInt dle=(uInt)DECLITEND;   // unsign
00385   if (dle>1) dle=1;           // ensure 0 or 1
00386
00387   if (LITEND!=DECLITEND) {
00388     const char *adj;
00389     if (!quiet) {
00390       if (LITEND) adj="little";
00391              else adj="big";
00392       printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
00393              DECLITEND, adj);
00394       }
00395     res=(Int)LITEND-dle;
00396     }
00397   return res;
00398   } // decContextTestEndian

uInt decContextTestSavedStatus | ( | uInt | oldstatus,
 |  | uInt | mask
 | ) |  |

Définition à la ligne 410 du fichier decContext.c.

00410                                                           {
00411   return (oldstatus&mask)!=0;
00412   } // decContextTestSavedStatus

uInt decContextTestStatus | ( | decContext * | context,
 |  | uInt | mask
 | ) |  |

Définition à la ligne 424 du fichier decContext.c.

Références decContext::status.

00424                                                           {
00425   return (context->status&mask)!=0;
00426   } // decContextTestStatus

decContext* decContextZeroStatus ( decContext * context )

Définition à la ligne 436 du fichier decContext.c.

Références decContext::status.

00436                                                       {
00437   context->status=0;
00438   return context;
00439   } // decContextZeroStatus

Documentation des variables

const uInt DECPOWERS[10]

Valeur initiale :

{1, 10, 100, 1000, 10000, 100000, 1000000,
                          10000000, 100000000, 1000000000}

Définition à la ligne 46 du fichier decContext.c.

const uByte DECSTICKYTAB[10] = {1,1,2,3,4,6,6,7,8,9}

Définition à la ligne 41 du fichier decContext.c.

const Int mfcone = 1 [static]

Définition à la ligne 34 du fichier decContext.c.

const Flag* mfctop = (Flag *)&mfcone [static]

Définition à la ligne 35 du fichier decContext.c.

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


Decimal: Fichier source de P:/wx_LIB/Dcml/decContext.c

P:/wx_LIB/Dcml/decContext.c

Aller à la documentation de ce fichier.
00001 /* ------------------------------------------------------------------ */
00002 /* Decimal Context module                                             */
00003 /* ------------------------------------------------------------------ */
00004 /* Copyright (c) IBM Corporation, 2000, 2005.  All rights reserved.   */
00005 /*                                                                    */
00006 /* This software is made available under the terms of the IBM         */
00007 /* alphaWorks License Agreement (distributed with this software as    */
00008 /* alphaWorks-License.txt).  Your use of this software indicates      */
00009 /* your acceptance of the terms and conditions of that Agreement.     */
00010 /*                                                                    */
00011 /* The description and User's Guide ("The decNumber C Library") for   */
00012 /* this software is called decNumber.pdf.  This document is           */
00013 /* available, together with arithmetic and format specifications,     */
00014 /* testcases, and Web links, on the General Decimal Arithmetic page.  */
00015 /*                                                                    */
00016 /* Please send comments, suggestions, and corrections to the author:  */
00017 /*   mfc@uk.ibm.com                                                   */
00018 /*   Mike Cowlishaw, IBM Fellow                                       */
00019 /*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
00020 /* ------------------------------------------------------------------ */
00021 /* This module comprises the routines for handling arithmetic         */
00022 /* context structures.                                                */
00023 /* ------------------------------------------------------------------ */
00024
00025 #include <string.h>           // for strcmp
00026 #include <stdio.h>            // for printf if DECCHECK
00027 #include "decContext.h"       // context and base types
00028 #include "decNumberLocal.h"   // decNumber local types, etc.
00029
00030
00031
00032
00033 /* compile-time endian tester [assumes sizeof(Int)>1] */
00034 static  const  Int mfcone=1;                 // constant 1
00035 static  const  Flag *mfctop=(Flag *)&mfcone; // -> top byte
00036 #define LITEND *mfctop             // named flag; 1=little-endian
00037
00038 /* ------------------------------------------------------------------ */
00039 /* round-for-reround digits                                           */
00040 /* ------------------------------------------------------------------ */
00041 const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
00042
00043 /* ------------------------------------------------------------------ */
00044 /* Powers of ten (powers[n]==10**n, 0<=n<=9)                          */
00045 /* ------------------------------------------------------------------ */
00046 const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
00047                           10000000, 100000000, 1000000000};
00048
00049 /* ------------------------------------------------------------------ */
00050 /* decContextClearStatus -- clear bits in current status              */
00051 /*                                                                    */
00052 /*  context is the context structure to be queried                    */
00053 /*  mask indicates the bits to be cleared (the status bit that        */
00054 /*    corresponds to each 1 bit in the mask is cleared)               */
00055 /*  returns context                                                   */
00056 /*                                                                    */
00057 /* No error is possible.                                              */
00058 /* ------------------------------------------------------------------ */
00059 decContext *decContextClearStatus(decContext *context, uInt mask) {
00060   context->status&=~mask;
00061   return context;
00062   } // decContextClearStatus
00063
00064 /* ------------------------------------------------------------------ */
00065 /* decContextDefault -- initialize a context structure                */
00066 /*                                                                    */
00067 /*  context is the structure to be initialized                        */
00068 /*  kind selects the required set of default values, one of:          */
00069 /*      DEC_INIT_BASE       -- select ANSI X3-274 defaults            */
00070 /*      DEC_INIT_DECIMAL32  -- select IEEE 754 defaults, 32-bit       */
00071 /*      DEC_INIT_DECIMAL64  -- select IEEE 754 defaults, 64-bit       */
00072 /*      DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit      */
00073 /*      For any other value a valid context is returned, but with     */
00074 /*      Invalid_operation set in the status field.                    */
00075 /*  returns a context structure with the appropriate initial values.  */
00076 /* ------------------------------------------------------------------ */
00077 decContext * decContextDefault(decContext *context, Int kind) {
00078   // set defaults...
00079   context->digits=9;                         // 9 digits
00080   context->emax=DEC_MAX_EMAX;                // 9-digit exponents
00081   context->emin=DEC_MIN_EMIN;                // .. balanced
00082   context->round=DEC_ROUND_HALF_UP;          // 0.5 rises
00083   context->traps=DEC_Errors;                 // all but informational
00084   context->status=0;                         // cleared
00085   context->clamp=0;                          // no clamping
00086   #if DECSUBSET
00087   context->extended=0;                       // cleared
00088   #endif
00089   switch (kind) {
00090     case DEC_INIT_BASE:
00091       // [use defaults]
00092       break;
00093     case DEC_INIT_DECIMAL32:
00094       context->digits=7;                     // digits
00095       context->emax=96;                      // Emax
00096       context->emin=-95;                     // Emin
00097       context->round=DEC_ROUND_HALF_EVEN;    // 0.5 to nearest even
00098       context->traps=0;                      // no traps set
00099       context->clamp=1;                      // clamp exponents
00100       #if DECSUBSET
00101       context->extended=1;                   // set
00102       #endif
00103       break;
00104     case DEC_INIT_DECIMAL64:
00105       context->digits=16;                    // digits
00106       context->emax=384;                     // Emax
00107       context->emin=-383;                    // Emin
00108       context->round=DEC_ROUND_HALF_EVEN;    // 0.5 to nearest even
00109       context->traps=0;                      // no traps set
00110       context->clamp=1;                      // clamp exponents
00111       #if DECSUBSET
00112       context->extended=1;                   // set
00113       #endif
00114       break;
00115     case DEC_INIT_DECIMAL128:
00116       context->digits=34;                    // digits
00117       context->emax=6144;                    // Emax
00118       context->emin=-6143;                   // Emin
00119       context->round=DEC_ROUND_HALF_EVEN;    // 0.5 to nearest even
00120       context->traps=0;                      // no traps set
00121       context->clamp=1;                      // clamp exponents
00122       #if DECSUBSET
00123       context->extended=1;                   // set
00124       #endif
00125       break;
00126
00127     default:                                 // invalid Kind
00128       // use defaults, and ..
00129       decContextSetStatus(context, DEC_Invalid_operation); // trap
00130     }
00131
00132   return context;} // decContextDefault
00133
00134 /* ------------------------------------------------------------------ */
00135 /* decContextGetRounding -- return current rounding mode              */
00136 /*                                                                    */
00137 /*  context is the context structure to be queried                    */
00138 /*  returns the rounding mode                                         */
00139 /*                                                                    */
00140 /* No error is possible.                                              */
00141 /* ------------------------------------------------------------------ */
00142 enum rounding decContextGetRounding(decContext *context) {
00143   return context->round;
00144   } // decContextGetRounding
00145
00146 /* ------------------------------------------------------------------ */
00147 /* decContextGetStatus -- return current status                       */
00148 /*                                                                    */
00149 /*  context is the context structure to be queried                    */
00150 /*  returns status                                                    */
00151 /*                                                                    */
00152 /* No error is possible.                                              */
00153 /* ------------------------------------------------------------------ */
00154 uInt decContextGetStatus(decContext *context) {
00155   return context->status;
00156   } // decContextGetStatus
00157
00158 /* ------------------------------------------------------------------ */
00159 /* decContextRestoreStatus -- restore bits in current status          */
00160 /*                                                                    */
00161 /*  context is the context structure to be updated                    */
00162 /*  newstatus is the source for the bits to be restored               */
00163 /*  mask indicates the bits to be restored (the status bit that       */
00164 /*    corresponds to each 1 bit in the mask is set to the value of    */
00165 /*    the correspnding bit in newstatus)                              */
00166 /*  returns context                                                   */
00167 /*                                                                    */
00168 /* No error is possible.                                              */
00169 /* ------------------------------------------------------------------ */
00170 decContext *decContextRestoreStatus(decContext *context,
00171                                     uInt newstatus, uInt mask) {
00172   context->status&=~mask;               // clear the selected bits
00173   context->status|=(mask&newstatus);    // or in the new bits
00174   return context;
00175   } // decContextRestoreStatus
00176
00177 /* ------------------------------------------------------------------ */
00178 /* decContextSaveStatus -- save bits in current status                */
00179 /*                                                                    */
00180 /*  context is the context structure to be queried                    */
00181 /*  mask indicates the bits to be saved (the status bits that         */
00182 /*    correspond to each 1 bit in the mask are saved)                 */
00183 /*  returns the AND of the mask and the current status                */
00184 /*                                                                    */
00185 /* No error is possible.                                              */
00186 /* ------------------------------------------------------------------ */
00187 uInt decContextSaveStatus(decContext *context, uInt mask) {
00188   return context->status&mask;
00189   } // decContextSaveStatus
00190
00191 /* ------------------------------------------------------------------ */
00192 /* decContextSetRounding -- set current rounding mode                 */
00193 /*                                                                    */
00194 /*  context is the context structure to be updated                    */
00195 /*  newround is the value which will replace the current mode         */
00196 /*  returns context                                                   */
00197 /*                                                                    */
00198 /* No error is possible.                                              */
00199 /* ------------------------------------------------------------------ */
00200 decContext *decContextSetRounding(decContext *context,
00201                                   enum rounding newround) {
00202   context->round=newround;
00203   return context;
00204   } // decContextSetRounding
00205
00206 /* ------------------------------------------------------------------ */
00207 /* decContextSetStatus -- set status and raise trap if appropriate    */
00208 /*                                                                    */
00209 /*  context is the context structure to be updated                    */
00210 /*  status  is the DEC_ exception code                                */
00211 /*  returns the context structure                                     */
00212 /*                                                                    */
00213 /* Control may never return from this routine, if there is a signal   */
00214 /* handler and it takes a long jump.                                  */
00215 /* ------------------------------------------------------------------ */
00216 decContext * decContextSetStatus(decContext *context, uInt status) {
00217   context->status|=status;
00218   if (status & context->traps) raise(SIGFPE);
00219   return context;} // decContextSetStatus
00220
00221 /* ------------------------------------------------------------------ */
00222 /* decContextSetStatusFromString -- set status from a string + trap   */
00223 /*                                                                    */
00224 /*  context is the context structure to be updated                    */
00225 /*  string is a string exactly equal to one that might be returned    */
00226 /*            by decContextStatusToString                             */
00227 /*                                                                    */
00228 /*  The status bit corresponding to the string is set, and a trap     */
00229 /*  is raised if appropriate.                                         */
00230 /*                                                                    */
00231 /*  returns the context structure, unless the string is equal to      */
00232 /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
00233 /*    returned.                                                       */
00234 /* ------------------------------------------------------------------ */
00235 decContext * decContextSetStatusFromString(decContext *context,
00236                                            const char *string) {
00237   if (strcmp(string, DEC_Condition_CS)==0)
00238     return decContextSetStatus(context, DEC_Conversion_syntax);
00239   if (strcmp(string, DEC_Condition_DZ)==0)
00240     return decContextSetStatus(context, DEC_Division_by_zero);
00241   if (strcmp(string, DEC_Condition_DI)==0)
00242     return decContextSetStatus(context, DEC_Division_impossible);
00243   if (strcmp(string, DEC_Condition_DU)==0)
00244     return decContextSetStatus(context, DEC_Division_undefined);
00245   if (strcmp(string, DEC_Condition_IE)==0)
00246     return decContextSetStatus(context, DEC_Inexact);
00247   if (strcmp(string, DEC_Condition_IS)==0)
00248     return decContextSetStatus(context, DEC_Insufficient_storage);
00249   if (strcmp(string, DEC_Condition_IC)==0)
00250     return decContextSetStatus(context, DEC_Invalid_context);
00251   if (strcmp(string, DEC_Condition_IO)==0)
00252     return decContextSetStatus(context, DEC_Invalid_operation);
00253   #if DECSUBSET
00254   if (strcmp(string, DEC_Condition_LD)==0)
00255     return decContextSetStatus(context, DEC_Lost_digits);
00256   #endif
00257   if (strcmp(string, DEC_Condition_OV)==0)
00258     return decContextSetStatus(context, DEC_Overflow);
00259   if (strcmp(string, DEC_Condition_PA)==0)
00260     return decContextSetStatus(context, DEC_Clamped);
00261   if (strcmp(string, DEC_Condition_RO)==0)
00262     return decContextSetStatus(context, DEC_Rounded);
00263   if (strcmp(string, DEC_Condition_SU)==0)
00264     return decContextSetStatus(context, DEC_Subnormal);
00265   if (strcmp(string, DEC_Condition_UN)==0)
00266     return decContextSetStatus(context, DEC_Underflow);
00267   if (strcmp(string, DEC_Condition_ZE)==0)
00268     return context;
00269   return NULL;  // Multiple status, or unknown
00270   } // decContextSetStatusFromString
00271
00272 /* ------------------------------------------------------------------ */
00273 /* decContextSetStatusFromStringQuiet -- set status from a string     */
00274 /*                                                                    */
00275 /*  context is the context structure to be updated                    */
00276 /*  string is a string exactly equal to one that might be returned    */
00277 /*            by decContextStatusToString                             */
00278 /*                                                                    */
00279 /*  The status bit corresponding to the string is set; no trap is     */
00280 /*  raised.                                                           */
00281 /*                                                                    */
00282 /*  returns the context structure, unless the string is equal to      */
00283 /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
00284 /*    returned.                                                       */
00285 /* ------------------------------------------------------------------ */
00286 decContext * decContextSetStatusFromStringQuiet(decContext *context,
00287                                                 const char *string) {
00288   if (strcmp(string, DEC_Condition_CS)==0)
00289     return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
00290   if (strcmp(string, DEC_Condition_DZ)==0)
00291     return decContextSetStatusQuiet(context, DEC_Division_by_zero);
00292   if (strcmp(string, DEC_Condition_DI)==0)
00293     return decContextSetStatusQuiet(context, DEC_Division_impossible);
00294   if (strcmp(string, DEC_Condition_DU)==0)
00295     return decContextSetStatusQuiet(context, DEC_Division_undefined);
00296   if (strcmp(string, DEC_Condition_IE)==0)
00297     return decContextSetStatusQuiet(context, DEC_Inexact);
00298   if (strcmp(string, DEC_Condition_IS)==0)
00299     return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
00300   if (strcmp(string, DEC_Condition_IC)==0)
00301     return decContextSetStatusQuiet(context, DEC_Invalid_context);
00302   if (strcmp(string, DEC_Condition_IO)==0)
00303     return decContextSetStatusQuiet(context, DEC_Invalid_operation);
00304   #if DECSUBSET
00305   if (strcmp(string, DEC_Condition_LD)==0)
00306     return decContextSetStatusQuiet(context, DEC_Lost_digits);
00307   #endif
00308   if (strcmp(string, DEC_Condition_OV)==0)
00309     return decContextSetStatusQuiet(context, DEC_Overflow);
00310   if (strcmp(string, DEC_Condition_PA)==0)
00311     return decContextSetStatusQuiet(context, DEC_Clamped);
00312   if (strcmp(string, DEC_Condition_RO)==0)
00313     return decContextSetStatusQuiet(context, DEC_Rounded);
00314   if (strcmp(string, DEC_Condition_SU)==0)
00315     return decContextSetStatusQuiet(context, DEC_Subnormal);
00316   if (strcmp(string, DEC_Condition_UN)==0)
00317     return decContextSetStatusQuiet(context, DEC_Underflow);
00318   if (strcmp(string, DEC_Condition_ZE)==0)
00319     return context;
00320   return NULL;  // Multiple status, or unknown
00321   } // decContextSetStatusFromStringQuiet
00322
00323 /* ------------------------------------------------------------------ */
00324 /* decContextSetStatusQuiet -- set status without trap                */
00325 /*                                                                    */
00326 /*  context is the context structure to be updated                    */
00327 /*  status  is the DEC_ exception code                                */
00328 /*  returns the context structure                                     */
00329 /*                                                                    */
00330 /* No error is possible.                                              */
00331 /* ------------------------------------------------------------------ */
00332 decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
00333   context->status|=status;
00334   return context;} // decContextSetStatusQuiet
00335
00336 /* ------------------------------------------------------------------ */
00337 /* decContextStatusToString -- convert status flags to a string       */
00338 /*                                                                    */
00339 /*  context is a context with valid status field                      */
00340 /*                                                                    */
00341 /*  returns a constant string describing the condition.  If multiple  */
00342 /*    (or no) flags are set, a generic constant message is returned.  */
00343 /* ------------------------------------------------------------------ */
00344 const char *decContextStatusToString(const decContext *context) {
00345   Int status=context->status;
00346
00347   // test the five IEEE first, as some of the others are ambiguous when
00348   // DECEXTFLAG=0
00349   if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
00350   if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
00351   if (status==DEC_Overflow             ) return DEC_Condition_OV;
00352   if (status==DEC_Underflow            ) return DEC_Condition_UN;
00353   if (status==DEC_Inexact              ) return DEC_Condition_IE;
00354
00355   if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
00356   if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
00357   if (status==DEC_Rounded              ) return DEC_Condition_RO;
00358   if (status==DEC_Clamped              ) return DEC_Condition_PA;
00359   if (status==DEC_Subnormal            ) return DEC_Condition_SU;
00360   if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
00361   if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
00362   if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
00363   #if DECSUBSET
00364   if (status==DEC_Lost_digits          ) return DEC_Condition_LD;
00365   #endif
00366   if (status==0                        ) return DEC_Condition_ZE;
00367   return DEC_Condition_MU;  // Multiple errors
00368   } // decContextStatusToString
00369
00370 /* ------------------------------------------------------------------ */
00371 /* decContextTestEndian -- test whether DECLITEND is set correctly    */
00372 /*                                                                    */
00373 /*  quiet is 1 to suppress message; 0 otherwise                       */
00374 /*  returns 0 if DECLITEND is correct                                 */
00375 /*          1 if DECLITEND is incorrect and should be 1               */
00376 /*         -1 if DECLITEND is incorrect and should be 0               */
00377 /*                                                                    */
00378 /* A message is displayed if the return value is not 0 and quiet==0.  */
00379 /*                                                                    */
00380 /* No error is possible.                                              */
00381 /* ------------------------------------------------------------------ */
00382 Int decContextTestEndian(Flag quiet) {
00383   Int res=0;                  // optimist
00384   uInt dle=(uInt)DECLITEND;   // unsign
00385   if (dle>1) dle=1;           // ensure 0 or 1
00386
00387   if (LITEND!=DECLITEND) {
00388     const char *adj;
00389     if (!quiet) {
00390       if (LITEND) adj="little";
00391              else adj="big";
00392       printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
00393              DECLITEND, adj);
00394       }
00395     res=(Int)LITEND-dle;
00396     }
00397   return res;
00398   } // decContextTestEndian
00399
00400 /* ------------------------------------------------------------------ */
00401 /* decContextTestSavedStatus -- test bits in saved status             */
00402 /*                                                                    */
00403 /*  oldstatus is the status word to be tested                         */
00404 /*  mask indicates the bits to be tested (the oldstatus bits that     */
00405 /*    correspond to each 1 bit in the mask are tested)                */
00406 /*  returns 1 if any of the tested bits are 1, or 0 otherwise         */
00407 /*                                                                    */
00408 /* No error is possible.                                              */
00409 /* ------------------------------------------------------------------ */
00410 uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
00411   return (oldstatus&mask)!=0;
00412   } // decContextTestSavedStatus
00413
00414 /* ------------------------------------------------------------------ */
00415 /* decContextTestStatus -- test bits in current status                */
00416 /*                                                                    */
00417 /*  context is the context structure to be updated                    */
00418 /*  mask indicates the bits to be tested (the status bits that        */
00419 /*    correspond to each 1 bit in the mask are tested)                */
00420 /*  returns 1 if any of the tested bits are 1, or 0 otherwise         */
00421 /*                                                                    */
00422 /* No error is possible.                                              */
00423 /* ------------------------------------------------------------------ */
00424 uInt decContextTestStatus(decContext *context, uInt mask) {
00425   return (context->status&mask)!=0;
00426   } // decContextTestStatus
00427
00428 /* ------------------------------------------------------------------ */
00429 /* decContextZeroStatus -- clear all status bits                      */
00430 /*                                                                    */
00431 /*  context is the context structure to be updated                    */
00432 /*  returns context                                                   */
00433 /*                                                                    */
00434 /* No error is possible.                                              */
00435 /* ------------------------------------------------------------------ */
00436 decContext *decContextZeroStatus(decContext *context) {
00437   context->status=0;
00438   return context;
00439   } // decContextZeroStatus
00440
00441
00442
00443
00444
Généré le Mon Jul 20 18:22:14 2009 pour Decimal par doxygen 1.5.1-p1


Decimal: Référence du fichier P:/wx_LIB/Dcml/decContext.h

Référence du fichier P:/wx_LIB/Dcml/decContext.h

#include <stdint.h>
#include <stdio.h>
#include <signal.h>

Aller au code source de ce fichier.

Classes

struct | decContext

Macros

#define | DECCONTEXT
#define | DECCNAME "decContext"
#define | DECCFULLNAME "Decimal Context Descriptor"
#define | DECCAUTHOR "Mike Cowlishaw"
#define | DECEXTFLAG 1
#define | DECSUBSET 0
#define | DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
#define | DEC_MAX_DIGITS 999999999
#define | DEC_MIN_DIGITS 1
#define | DEC_MAX_EMAX 999999999
#define | DEC_MIN_EMAX 0
#define | DEC_MAX_EMIN 0
#define | DEC_MIN_EMIN -999999999
#define | DEC_MAX_MATH 999999
#define | DEC_ClassString_SN "sNaN"
#define | DEC_ClassString_QN "NaN"
#define | DEC_ClassString_NI "-Infinity"
#define | DEC_ClassString_NN "-Normal"
#define | DEC_ClassString_NS "-Subnormal"
#define | DEC_ClassString_NZ "-Zero"
#define | DEC_ClassString_PZ "+Zero"
#define | DEC_ClassString_PS "+Subnormal"
#define | DEC_ClassString_PN "+Normal"
#define | DEC_ClassString_PI "+Infinity"
#define | DEC_ClassString_UN "Invalid"
#define | DEC_Conversion_syntax 0x00000001
#define | DEC_Division_by_zero 0x00000002
#define | DEC_Division_impossible 0x00000004
#define | DEC_Division_undefined 0x00000008
#define | DEC_Insufficient_storage 0x00000010
#define | DEC_Inexact 0x00000020
#define | DEC_Invalid_context 0x00000040
#define | DEC_Invalid_operation 0x00000080
#define | DEC_Overflow 0x00000200
#define | DEC_Clamped 0x00000400
#define | DEC_Rounded 0x00000800
#define | DEC_Subnormal 0x00001000
#define | DEC_Underflow 0x00002000
#define | DEC_IEEE_754_Division_by_zero (DEC_Division_by_zero)
#define | DEC_IEEE_754_Inexact (DEC_Inexact)
#define | DEC_IEEE_754_Invalid_operation
#define | DEC_IEEE_754_Overflow (DEC_Overflow)
#define | DEC_IEEE_754_Underflow (DEC_Underflow)
#define | DEC_Errors
#define | DEC_NaNs DEC_IEEE_754_Invalid_operation
#define | DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
#define | DEC_IEEE_854_Division_by_zero DEC_IEEE_754_Division_by_zero
#define | DEC_IEEE_854_Inexact DEC_IEEE_754_Inexact
#define | DEC_IEEE_854_Invalid_operation DEC_IEEE_754_Invalid_operation
#define | DEC_IEEE_854_Overflow DEC_IEEE_754_Overflow
#define | DEC_IEEE_854_Underflow DEC_IEEE_754_Underflow
#define | DEC_Condition_CS "Conversion syntax"
#define | DEC_Condition_DZ "Division by zero"
#define | DEC_Condition_DI "Division impossible"
#define | DEC_Condition_DU "Division undefined"
#define | DEC_Condition_IE "Inexact"
#define | DEC_Condition_IS "Insufficient storage"
#define | DEC_Condition_IC "Invalid context"
#define | DEC_Condition_IO "Invalid operation"
#define | DEC_Condition_OV "Overflow"
#define | DEC_Condition_PA "Clamped"
#define | DEC_Condition_RO "Rounded"
#define | DEC_Condition_SU "Subnormal"
#define | DEC_Condition_UN "Underflow"
#define | DEC_Condition_ZE "No status"
#define | DEC_Condition_MU "Multiple status"
#define | DEC_Condition_Length 21
#define | DEC_INIT_BASE 0
#define | DEC_INIT_DECIMAL32 32
#define | DEC_INIT_DECIMAL64 64
#define | DEC_INIT_DECIMAL128 128
#define | DEC_INIT_DECSINGLE DEC_INIT_DECIMAL32
#define | DEC_INIT_DECDOUBLE DEC_INIT_DECIMAL64
#define | DEC_INIT_DECQUAD DEC_INIT_DECIMAL128

Énumérations

enum rounding {
DEC_ROUND_CEILING, DEC_ROUND_UP, DEC_ROUND_HALF_UP, DEC_ROUND_HALF_EVEN,
DEC_ROUND_HALF_DOWN, DEC_ROUND_DOWN, DEC_ROUND_FLOOR, DEC_ROUND_05UP,
DEC_ROUND_MAX
}
enum decClass {
DEC_CLASS_SNAN, DEC_CLASS_QNAN, DEC_CLASS_NEG_INF, DEC_CLASS_NEG_NORMAL,
DEC_CLASS_NEG_SUBNORMAL, DEC_CLASS_NEG_ZERO, DEC_CLASS_POS_ZERO, DEC_CLASS_POS_SUBNORMAL,
DEC_CLASS_POS_NORMAL, DEC_CLASS_POS_INF
}

Fonctions

decContext * | decContextClearStatus (decContext *, uint32_t)
decContext * | decContextDefault (decContext *, int32_t)
enum rounding | decContextGetRounding (decContext *)
uint32_t | decContextGetStatus (decContext *)
decContext * | decContextRestoreStatus (decContext *, uint32_t, uint32_t)
uint32_t | decContextSaveStatus (decContext *, uint32_t)
decContext * | decContextSetRounding (decContext *, enum rounding)
decContext * | decContextSetStatus (decContext *, uint32_t)
decContext * | decContextSetStatusFromString (decContext *, const char *)
decContext * | decContextSetStatusFromStringQuiet (decContext *, const char *)
decContext * | decContextSetStatusQuiet (decContext *, uint32_t)
const char * | decContextStatusToString (const decContext *)
int32_t | decContextTestEndian (uint8_t)
uint32_t | decContextTestSavedStatus (uint32_t, uint32_t)
uint32_t | decContextTestStatus (decContext *, uint32_t)
decContext * decContextZeroStatus (decContext *)

Documentation des macros

#define DEC_Clamped 0x00000400

Définition à la ligne 142 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), decDivideOp(), DecErrStatus(), decFinalize(), decNumberSquareRoot(), decSetOverflow(), et decSetSubnormal().

#define DEC_ClassString_NI "-Infinity"

Définition à la ligne 116 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_NN "-Normal"

Définition à la ligne 117 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_NS "-Subnormal"

Définition à la ligne 118 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_NZ "-Zero"

Définition à la ligne 119 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_PI "+Infinity"

Définition à la ligne 123 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_PN "+Normal"

Définition à la ligne 122 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_PS "+Subnormal"

Définition à la ligne 121 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_PZ "+Zero"

Définition à la ligne 120 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_QN "NaN"

Définition à la ligne 115 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_SN "sNaN"

Définition à la ligne 114 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_ClassString_UN "Invalid"

Définition à la ligne 124 du fichier decContext.h.

Référencé par decNumberClassToString().

#define DEC_Condition_CS "Conversion syntax"

Définition à la ligne 207 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_DI "Division impossible"

Définition à la ligne 209 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_DU "Division undefined"

Définition à la ligne 210 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_DZ "Division by zero"

Définition à la ligne 208 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_IC "Invalid context"

Définition à la ligne 213 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_IE "Inexact"

Définition à la ligne 211 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_IO "Invalid operation"

Définition à la ligne 214 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_IS "Insufficient storage"

Définition à la ligne 212 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_Length 21

Définition à la ligne 225 du fichier decContext.h.

#define DEC_Condition_MU "Multiple status"

Définition à la ligne 224 du fichier decContext.h.

Référencé par decContextStatusToString().

#define DEC_Condition_OV "Overflow"

Définition à la ligne 218 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_PA "Clamped"

Définition à la ligne 219 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_RO "Rounded"

Définition à la ligne 220 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_SU "Subnormal"

Définition à la ligne 221 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_UN "Underflow"

Définition à la ligne 222 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), et decContextStatusToString().

#define DEC_Condition_ZE "No status"

Définition à la ligne 223 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), et decContextStatusToString().

#define DEC_Conversion_syntax 0x00000001

Définition à la ligne 130 du fichier decContext.h.

Référencé par DecFloatContext::Clear_Conversion_syntax_status(), DecFloatContext::Conversion_syntax_status(), decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), DecErrStatus(), et decNumberFromString().

#define DEC_Division_by_zero 0x00000002

Définition à la ligne 131 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), decDivideOp(), DecErrStatus(), et decNumberLogB().

#define DEC_Division_impossible 0x00000004

Définition à la ligne 132 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), decDivideOp(), et DecErrStatus().

#define DEC_Division_undefined 0x00000008

Définition à la ligne 133 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), decDivideOp(), et DecErrStatus().

#define DEC_Errors

Valeur :

(DEC_IEEE_754_Division_by_zero |                 \
                      DEC_IEEE_754_Invalid_operation |                \
                      DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)

Définition à la ligne 185 du fichier decContext.h.

Référencé par decContextDefault().

#define DEC_IEEE_754_Division_by_zero (DEC_Division_by_zero)

Définition à la ligne 169 du fichier decContext.h.

#define DEC_IEEE_754_Inexact (DEC_Inexact)

Définition à la ligne 173 du fichier decContext.h.

#define DEC_IEEE_754_Invalid_operation

Valeur :

(DEC_Conversion_syntax |     \
                                          DEC_Division_impossible |   \
                                          DEC_Division_undefined |    \
                                          DEC_Insufficient_storage |  \
                                          DEC_Invalid_context |       \
                                          DEC_Invalid_operation)

Définition à la ligne 175 du fichier decContext.h.

#define DEC_IEEE_754_Overflow (DEC_Overflow)

Définition à la ligne 181 du fichier decContext.h.

#define DEC_IEEE_754_Underflow (DEC_Underflow)

Définition à la ligne 182 du fichier decContext.h.

#define DEC_IEEE_854_Division_by_zero DEC_IEEE_754_Division_by_zero

Définition à la ligne 200 du fichier decContext.h.

#define DEC_IEEE_854_Inexact DEC_IEEE_754_Inexact

Définition à la ligne 201 du fichier decContext.h.

#define DEC_IEEE_854_Invalid_operation DEC_IEEE_754_Invalid_operation

Définition à la ligne 202 du fichier decContext.h.

#define DEC_IEEE_854_Overflow DEC_IEEE_754_Overflow

Définition à la ligne 203 du fichier decContext.h.

#define DEC_IEEE_854_Underflow DEC_IEEE_754_Underflow

Définition à la ligne 204 du fichier decContext.h.

#define DEC_Inexact 0x00000020

Définition à la ligne 135 du fichier decContext.h.

Référencé par decAddOp(), decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), DecErrStatus(), decExpOp(), decLnOp(), decNumberLog10(), decNumberPower(), decNumberSquareRoot(), decQuantizeOp(), decSetCoeff(), decSetOverflow(), et decSetSubnormal().

#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)

Définition à la ligne 196 du fichier decContext.h.

#define DEC_INIT_BASE 0

Définition à la ligne 229 du fichier decContext.h.

Référencé par decContextDefault(), et decNumberTrim().

#define DEC_INIT_DECDOUBLE DEC_INIT_DECIMAL64

Définition à la ligne 235 du fichier decContext.h.

#define DEC_INIT_DECIMAL128 128

Définition à la ligne 232 du fichier decContext.h.

Référencé par decContextDefault().

#define DEC_INIT_DECIMAL32 32

Définition à la ligne 230 du fichier decContext.h.

Référencé par decContextDefault().

#define DEC_INIT_DECIMAL64 64

Définition à la ligne 231 du fichier decContext.h.

Référencé par decContextDefault(), decExpOp(), decLnOp(), decNumberLog10(), decNumberPower(), et decNumberSquareRoot().

#define DEC_INIT_DECQUAD DEC_INIT_DECIMAL128

Définition à la ligne 236 du fichier decContext.h.

#define DEC_INIT_DECSINGLE DEC_INIT_DECIMAL32

Définition à la ligne 234 du fichier decContext.h.

#define DEC_Insufficient_storage 0x00000010

Définition à la ligne 134 du fichier decContext.h.

Référencé par decAddOp(), decCompareOp(), decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), decDivideOp(), DecErrStatus(), decExpOp(), decFinalize(), decLnOp(), decMultiplyOp(), decNumberCompareTotalMag(), decNumberFMA(), decNumberLog10(), decNumberNextToward(), decNumberPower(), et decNumberSquareRoot().

#define DEC_Invalid_context 0x00000040

Définition à la ligne 136 du fichier decContext.h.

Référencé par decApplyRound(), decCheckMath(), decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), et DecErrStatus().

#define DEC_Invalid_operation 0x00000080

Définition à la ligne 137 du fichier decContext.h.

Référencé par decAddOp(), decCheckMath(), decCompareOp(), decContextDefault(), decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), decDivideOp(), DecErrStatus(), decLnOp(), decMultiplyOp(), decNaNs(), decNumberAnd(), decNumberFMA(), decNumberInvert(), decNumberLn(), decNumberLog10(), decNumberNextMinus(), decNumberNextPlus(), decNumberOr(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToInt32(), decNumberToIntegralValue(), decNumberToUInt32(), decNumberXor(), decQuantizeOp(), et decSetSubnormal().

#define DEC_MAX_DIGITS 999999999

Définition à la ligne 90 du fichier decContext.h.

#define DEC_MAX_EMAX 999999999

Définition à la ligne 92 du fichier decContext.h.

Référencé par decContextDefault(), decNumberFMA(), et decNumberSquareRoot().

#define DEC_MAX_EMIN 0

Définition à la ligne 94 du fichier decContext.h.

#define DEC_MAX_MATH 999999

Définition à la ligne 96 du fichier decContext.h.

Référencé par decCheckMath(), decLnOp(), decNumberLog10(), et decNumberPower().

#define DEC_MIN_DIGITS 1

Définition à la ligne 91 du fichier decContext.h.

#define DEC_MIN_EMAX 0

Définition à la ligne 93 du fichier decContext.h.

#define DEC_MIN_EMIN -999999999

Définition à la ligne 95 du fichier decContext.h.

Référencé par decContextDefault(), decExpOp(), decNumberFMA(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), et decNumberSquareRoot().

#define DEC_NaNs DEC_IEEE_754_Invalid_operation

Définition à la ligne 189 du fichier decContext.h.

Référencé par decNumberLog10(), et decStatus().

#define DEC_Overflow 0x00000200

Définition à la ligne 141 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), DecErrStatus(), decExpOp(), decNumberPower(), decNumberSquareRoot(), et decSetOverflow().

#define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;

Définition à la ligne 74 du fichier decContext.h.

#define DEC_Rounded 0x00000800

Définition à la ligne 143 du fichier decContext.h.

Référencé par decAddOp(), decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), DecErrStatus(), decExpOp(), decLnOp(), decNumberPower(), decNumberSquareRoot(), decQuantizeOp(), decSetCoeff(), decSetOverflow(), et decSetSubnormal().

#define DEC_Subnormal 0x00001000

Définition à la ligne 144 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), DecErrStatus(), decNumberPower(), decNumberSquareRoot(), et decSetSubnormal().

#define DEC_Underflow 0x00002000

Définition à la ligne 145 du fichier decContext.h.

Référencé par decContextSetStatusFromString(), decContextSetStatusFromStringQuiet(), DecContextStatusString(), decContextStatusToString(), DecErrStatus(), decExpOp(), decNumberPower(), decNumberSquareRoot(), decQuantizeOp(), et decSetSubnormal().

#define DECCAUTHOR "Mike Cowlishaw"

Définition à la ligne 44 du fichier decContext.h.

#define DECCFULLNAME "Decimal Context Descriptor"

Définition à la ligne 43 du fichier decContext.h.

#define DECCNAME "decContext"

Définition à la ligne 42 du fichier decContext.h.

#define DECCONTEXT

Définition à la ligne 41 du fichier decContext.h.

#define DECEXTFLAG 1

Définition à la ligne 54 du fichier decContext.h.

#define DECSUBSET 0

Définition à la ligne 59 du fichier decContext.h.

Référencé par decAddOp().

Documentation du type de l'énumération

enum decClass

Valeurs énumérées:
DEC_CLASS_SNAN
DEC_CLASS_QNAN
DEC_CLASS_NEG_INF
DEC_CLASS_NEG_NORMAL
DEC_CLASS_NEG_SUBNORMAL
DEC_CLASS_NEG_ZERO
DEC_CLASS_POS_ZERO
DEC_CLASS_POS_SUBNORMAL
DEC_CLASS_POS_NORMAL
DEC_CLASS_POS_INF

Définition à la ligne 101 du fichier decContext.h.

00101                 {
00102     DEC_CLASS_SNAN,
00103     DEC_CLASS_QNAN,
00104     DEC_CLASS_NEG_INF,
00105     DEC_CLASS_NEG_NORMAL,
00106     DEC_CLASS_NEG_SUBNORMAL,
00107     DEC_CLASS_NEG_ZERO,
00108     DEC_CLASS_POS_ZERO,
00109     DEC_CLASS_POS_SUBNORMAL,
00110     DEC_CLASS_POS_NORMAL,
00111     DEC_CLASS_POS_INF
00112     };

enum rounding

Valeurs énumérées:
DEC_ROUND_CEILING
DEC_ROUND_UP
DEC_ROUND_HALF_UP
DEC_ROUND_HALF_EVEN
DEC_ROUND_HALF_DOWN
DEC_ROUND_DOWN
DEC_ROUND_FLOOR
DEC_ROUND_05UP
DEC_ROUND_MAX

Définition à la ligne 63 du fichier decContext.h.

00063                 {
00064     DEC_ROUND_CEILING,             /* round towards +infinity         */
00065     DEC_ROUND_UP,                  /* round away from 0               */
00066     DEC_ROUND_HALF_UP,             /* 0.5 rounds up                   */
00067     DEC_ROUND_HALF_EVEN,           /* 0.5 rounds to nearest even      */
00068     DEC_ROUND_HALF_DOWN,           /* 0.5 rounds down                 */
00069     DEC_ROUND_DOWN,                /* round towards 0 (truncate)      */
00070     DEC_ROUND_FLOOR,               /* round towards -infinity         */
00071     DEC_ROUND_05UP,                /* round for reround               */
00072     DEC_ROUND_MAX                  /* enum must be less than this     */
00073     };

Documentation des fonctions

decContext* decContextClearStatus | ( | decContext * | ,
 |  | uint32_t |
 | ) |  |

decContext* decContextDefault | ( | decContext * | ,
 |  | int32_t |
 | ) |  |

enum rounding decContextGetRounding ( decContext * )

Définition à la ligne 142 du fichier decContext.c.

Références decContext::round.

00142                                                          {
00143   return context->round;
00144   } // decContextGetRounding

uint32_t decContextGetStatus ( decContext * )

Définition à la ligne 154 du fichier decContext.c.

Références decContext::status.

00154                                               {
00155   return context->status;
00156   } // decContextGetStatus

decContext* decContextRestoreStatus | ( | decContext * | ,
 |  | uint32_t | ,
 |  | uint32_t |
 | ) |  |

uint32_t decContextSaveStatus | ( | decContext * | ,
 |  | uint32_t |
 | ) |  |

decContext* decContextSetRounding | ( | decContext * | ,
 |  | enum | rounding
 | ) |  |

Définition à la ligne 200 du fichier decContext.c.

Références decContext::round.

00201                                                           {
00202   context->round=newround;
00203   return context;
00204   } // decContextSetRounding

decContext* decContextSetStatus | ( | decContext * | ,
 |  | uint32_t |
 | ) |  |

decContext* decContextSetStatusFromString | ( | decContext * | ,
 |  | const char * |
 | ) |  |

Définition à la ligne 235 du fichier decContext.c.

Références DEC_Clamped, DEC_Condition_CS, DEC_Condition_DI, DEC_Condition_DU, DEC_Condition_DZ, DEC_Condition_IC, DEC_Condition_IE, DEC_Condition_IO, DEC_Condition_IS, DEC_Condition_OV, DEC_Condition_PA, DEC_Condition_RO, DEC_Condition_SU, DEC_Condition_UN, DEC_Condition_ZE, DEC_Conversion_syntax, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_context, DEC_Invalid_operation, DEC_Overflow, DEC_Rounded, DEC_Subnormal, DEC_Underflow, et decContextSetStatus().

00236                                                                {
00237   if (strcmp(string, DEC_Condition_CS)==0)
00238     return decContextSetStatus(context, DEC_Conversion_syntax);
00239   if (strcmp(string, DEC_Condition_DZ)==0)
00240     return decContextSetStatus(context, DEC_Division_by_zero);
00241   if (strcmp(string, DEC_Condition_DI)==0)
00242     return decContextSetStatus(context, DEC_Division_impossible);
00243   if (strcmp(string, DEC_Condition_DU)==0)
00244     return decContextSetStatus(context, DEC_Division_undefined);
00245   if (strcmp(string, DEC_Condition_IE)==0)
00246     return decContextSetStatus(context, DEC_Inexact);
00247   if (strcmp(string, DEC_Condition_IS)==0)
00248     return decContextSetStatus(context, DEC_Insufficient_storage);
00249   if (strcmp(string, DEC_Condition_IC)==0)
00250     return decContextSetStatus(context, DEC_Invalid_context);
00251   if (strcmp(string, DEC_Condition_IO)==0)
00252     return decContextSetStatus(context, DEC_Invalid_operation);
00253   #if DECSUBSET
00254   if (strcmp(string, DEC_Condition_LD)==0)
00255     return decContextSetStatus(context, DEC_Lost_digits);
00256   #endif
00257   if (strcmp(string, DEC_Condition_OV)==0)
00258     return decContextSetStatus(context, DEC_Overflow);
00259   if (strcmp(string, DEC_Condition_PA)==0)
00260     return decContextSetStatus(context, DEC_Clamped);
00261   if (strcmp(string, DEC_Condition_RO)==0)
00262     return decContextSetStatus(context, DEC_Rounded);
00263   if (strcmp(string, DEC_Condition_SU)==0)
00264     return decContextSetStatus(context, DEC_Subnormal);
00265   if (strcmp(string, DEC_Condition_UN)==0)
00266     return decContextSetStatus(context, DEC_Underflow);
00267   if (strcmp(string, DEC_Condition_ZE)==0)
00268     return context;
00269   return NULL;  // Multiple status, or unknown
00270   } // decContextSetStatusFromString

decContext* decContextSetStatusFromStringQuiet | ( | decContext * | ,
 |  | const char * |
 | ) |  |

Définition à la ligne 286 du fichier decContext.c.

Références DEC_Clamped, DEC_Condition_CS, DEC_Condition_DI, DEC_Condition_DU, DEC_Condition_DZ, DEC_Condition_IC, DEC_Condition_IE, DEC_Condition_IO, DEC_Condition_IS, DEC_Condition_OV, DEC_Condition_PA, DEC_Condition_RO, DEC_Condition_SU, DEC_Condition_UN, DEC_Condition_ZE, DEC_Conversion_syntax, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_context, DEC_Invalid_operation, DEC_Overflow, DEC_Rounded, DEC_Subnormal, DEC_Underflow, et decContextSetStatusQuiet().

00287                                                                     {
00288   if (strcmp(string, DEC_Condition_CS)==0)
00289     return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
00290   if (strcmp(string, DEC_Condition_DZ)==0)
00291     return decContextSetStatusQuiet(context, DEC_Division_by_zero);
00292   if (strcmp(string, DEC_Condition_DI)==0)
00293     return decContextSetStatusQuiet(context, DEC_Division_impossible);
00294   if (strcmp(string, DEC_Condition_DU)==0)
00295     return decContextSetStatusQuiet(context, DEC_Division_undefined);
00296   if (strcmp(string, DEC_Condition_IE)==0)
00297     return decContextSetStatusQuiet(context, DEC_Inexact);
00298   if (strcmp(string, DEC_Condition_IS)==0)
00299     return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
00300   if (strcmp(string, DEC_Condition_IC)==0)
00301     return decContextSetStatusQuiet(context, DEC_Invalid_context);
00302   if (strcmp(string, DEC_Condition_IO)==0)
00303     return decContextSetStatusQuiet(context, DEC_Invalid_operation);
00304   #if DECSUBSET
00305   if (strcmp(string, DEC_Condition_LD)==0)
00306     return decContextSetStatusQuiet(context, DEC_Lost_digits);
00307   #endif
00308   if (strcmp(string, DEC_Condition_OV)==0)
00309     return decContextSetStatusQuiet(context, DEC_Overflow);
00310   if (strcmp(string, DEC_Condition_PA)==0)
00311     return decContextSetStatusQuiet(context, DEC_Clamped);
00312   if (strcmp(string, DEC_Condition_RO)==0)
00313     return decContextSetStatusQuiet(context, DEC_Rounded);
00314   if (strcmp(string, DEC_Condition_SU)==0)
00315     return decContextSetStatusQuiet(context, DEC_Subnormal);
00316   if (strcmp(string, DEC_Condition_UN)==0)
00317     return decContextSetStatusQuiet(context, DEC_Underflow);
00318   if (strcmp(string, DEC_Condition_ZE)==0)
00319     return context;
00320   return NULL;  // Multiple status, or unknown
00321   } // decContextSetStatusFromStringQuiet

decContext* decContextSetStatusQuiet | ( | decContext * | ,
 |  | uint32_t |
 | ) |  |

const char* decContextStatusToString ( const decContext * )

Définition à la ligne 344 du fichier decContext.c.

Références DEC_Clamped, DEC_Condition_CS, DEC_Condition_DI, DEC_Condition_DU, DEC_Condition_DZ, DEC_Condition_IC, DEC_Condition_IE, DEC_Condition_IO, DEC_Condition_IS, DEC_Condition_MU, DEC_Condition_OV, DEC_Condition_PA, DEC_Condition_RO, DEC_Condition_SU, DEC_Condition_UN, DEC_Condition_ZE, DEC_Conversion_syntax, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_context, DEC_Invalid_operation, DEC_Overflow, DEC_Rounded, DEC_Subnormal, DEC_Underflow, Int, et decContext::status.

Référencé par DecFloatContext::StatusToString().

00344                                                                 {
00345   Int status=context->status;
00346
00347   // test the five IEEE first, as some of the others are ambiguous when
00348   // DECEXTFLAG=0
00349   if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
00350   if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
00351   if (status==DEC_Overflow             ) return DEC_Condition_OV;
00352   if (status==DEC_Underflow            ) return DEC_Condition_UN;
00353   if (status==DEC_Inexact              ) return DEC_Condition_IE;
00354
00355   if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
00356   if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
00357   if (status==DEC_Rounded              ) return DEC_Condition_RO;
00358   if (status==DEC_Clamped              ) return DEC_Condition_PA;
00359   if (status==DEC_Subnormal            ) return DEC_Condition_SU;
00360   if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
00361   if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
00362   if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
00363   #if DECSUBSET
00364   if (status==DEC_Lost_digits          ) return DEC_Condition_LD;
00365   #endif
00366   if (status==0                        ) return DEC_Condition_ZE;
00367   return DEC_Condition_MU;  // Multiple errors
00368   } // decContextStatusToString

int32_t decContextTestEndian ( uint8_t )

uint32_t decContextTestSavedStatus | ( | uint32_t | ,
 |  | uint32_t |
 | ) |  |

uint32_t decContextTestStatus | ( | decContext * | ,
 |  | uint32_t |
 | ) |  |

decContext* decContextZeroStatus ( decContext * )

Définition à la ligne 436 du fichier decContext.c.

Références decContext::status.

00436                                                       {
00437   context->status=0;
00438   return context;
00439   } // decContextZeroStatus

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


Decimal: Fichier source de P:/wx_LIB/Dcml/decContext.h

P:/wx_LIB/Dcml/decContext.h

Aller à la documentation de ce fichier.
00001 /* ------------------------------------------------------------------ */
00002 /* Decimal Context module header                                      */
00003 /* ------------------------------------------------------------------ */
00004 /* Copyright (c) IBM Corporation, 2000, 2008.  All rights reserved.   */
00005 /*                                                                    */
00006 /* This software is made available under the terms of the IBM         */
00007 /* alphaWorks License Agreement (distributed with this software as    */
00008 /* alphaWorks-License.txt).  Your use of this software indicates      */
00009 /* your acceptance of the terms and conditions of that Agreement.     */
00010 /*                                                                    */
00011 /* The description and User's Guide ("The decNumber C Library") for   */
00012 /* this software is called decNumber.pdf.  This document is           */
00013 /* available, together with arithmetic and format specifications,     */
00014 /* testcases, and Web links, on the General Decimal Arithmetic page.  */
00015 /*                                                                    */
00016 /* Please send comments, suggestions, and corrections to the author:  */
00017 /*   mfc@uk.ibm.com                                                   */
00018 /*   Mike Cowlishaw, IBM Fellow                                       */
00019 /*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
00020 /* ------------------------------------------------------------------ */
00021 /*                                                                    */
00022 /* Context variables must always have valid values:                   */
00023 /*                                                                    */
00024 /*  status   -- [any bits may be cleared, but not set, by user]       */
00025 /*  round    -- must be one of the enumerated rounding modes          */
00026 /*                                                                    */
00027 /* The following variables are implied for fixed size formats (i.e.,  */
00028 /* they are ignored) but should still be set correctly in case used   */
00029 /* with decNumber functions:                                          */
00030 /*                                                                    */
00031 /*  clamp    -- must be either 0 or 1                                 */
00032 /*  digits   -- must be in the range 1 through 999999999              */
00033 /*  emax     -- must be in the range 0 through 999999999              */
00034 /*  emin     -- must be in the range 0 through -999999999             */
00035 /*  extended -- must be either 0 or 1 [present only if DECSUBSET]     */
00036 /*  traps    -- only defined bits may be set                          */
00037 /*                                                                    */
00038 /* ------------------------------------------------------------------ */
00039
00040 #if !defined(DECCONTEXT)
00041   #define DECCONTEXT
00042   #define DECCNAME     "decContext"                     /* Short name */
00043   #define DECCFULLNAME "Decimal Context Descriptor"   /* Verbose name */
00044   #define DECCAUTHOR   "Mike Cowlishaw"               /* Who to blame */
00045
00046   #if !defined(int32_t)
00047     #include <stdint.h>            /* C99 standard integers           */
00048   #endif
00049   #include <stdio.h>               /* for printf, etc.                */
00050   #include <signal.h>              /* for traps                       */
00051
00052   /* Extended flags setting -- set this to 0 to use only IEEE flags   */
00053   #if !defined(DECEXTFLAG)
00054   #define DECEXTFLAG 1             /* 1=enable extended flags         */
00055   #endif
00056
00057   /* Conditional code flag -- set this to 0 for best performance      */
00058   #if !defined(DECSUBSET)
00059   #define DECSUBSET  0             /* 1=enable subset arithmetic      */
00060   #endif
00061
00062   /* Context for operations, with associated constants                */
00063   enum rounding {
00064     DEC_ROUND_CEILING,             /* round towards +infinity         */
00065     DEC_ROUND_UP,                  /* round away from 0               */
00066     DEC_ROUND_HALF_UP,             /* 0.5 rounds up                   */
00067     DEC_ROUND_HALF_EVEN,           /* 0.5 rounds to nearest even      */
00068     DEC_ROUND_HALF_DOWN,           /* 0.5 rounds down                 */
00069     DEC_ROUND_DOWN,                /* round towards 0 (truncate)      */
00070     DEC_ROUND_FLOOR,               /* round towards -infinity         */
00071     DEC_ROUND_05UP,                /* round for reround               */
00072     DEC_ROUND_MAX                  /* enum must be less than this     */
00073     };
00074   #define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
00075
00076   typedef struct {
00077     int32_t  digits;               /* working precision               */
00078     int32_t  emax;                 /* maximum positive exponent       */
00079     int32_t  emin;                 /* minimum negative exponent       */
00080     enum     rounding round;       /* rounding mode                   */
00081     uint32_t traps;                /* trap-enabler flags              */
00082     uint32_t status;               /* status flags                    */
00083     uint8_t  clamp;                /* flag: apply IEEE exponent clamp */
00084     #if DECSUBSET
00085     uint8_t  extended;             /* flag: special-values allowed    */
00086     #endif
00087     } decContext;
00088
00089   /* Maxima and Minima for context settings                           */
00090   #define DEC_MAX_DIGITS 999999999
00091   #define DEC_MIN_DIGITS         1
00092   #define DEC_MAX_EMAX   999999999
00093   #define DEC_MIN_EMAX           0
00094   #define DEC_MAX_EMIN           0
00095   #define DEC_MIN_EMIN  -999999999
00096   #define DEC_MAX_MATH      999999 /* max emax, etc., for math funcs. */
00097
00098   /* Classifications for decimal numbers, aligned with 754 (note that */
00099   /* 'normal' and 'subnormal' are meaningful only with a decContext   */
00100   /* or a fixed size format).                                         */
00101   enum decClass {
00102     DEC_CLASS_SNAN,
00103     DEC_CLASS_QNAN,
00104     DEC_CLASS_NEG_INF,
00105     DEC_CLASS_NEG_NORMAL,
00106     DEC_CLASS_NEG_SUBNORMAL,
00107     DEC_CLASS_NEG_ZERO,
00108     DEC_CLASS_POS_ZERO,
00109     DEC_CLASS_POS_SUBNORMAL,
00110     DEC_CLASS_POS_NORMAL,
00111     DEC_CLASS_POS_INF
00112     };
00113   /* Strings for the decClasses */
00114   #define DEC_ClassString_SN  "sNaN"
00115   #define DEC_ClassString_QN  "NaN"
00116   #define DEC_ClassString_NI  "-Infinity"
00117   #define DEC_ClassString_NN  "-Normal"
00118   #define DEC_ClassString_NS  "-Subnormal"
00119   #define DEC_ClassString_NZ  "-Zero"
00120   #define DEC_ClassString_PZ  "+Zero"
00121   #define DEC_ClassString_PS  "+Subnormal"
00122   #define DEC_ClassString_PN  "+Normal"
00123   #define DEC_ClassString_PI  "+Infinity"
00124   #define DEC_ClassString_UN  "Invalid"
00125
00126   /* Trap-enabler and Status flags (exceptional conditions), and      */
00127   /* their names.  The top byte is reserved for internal use          */
00128   #if DECEXTFLAG
00129     /* Extended flags */
00130     #define DEC_Conversion_syntax    0x00000001
00131     #define DEC_Division_by_zero     0x00000002
00132     #define DEC_Division_impossible  0x00000004
00133     #define DEC_Division_undefined   0x00000008
00134     #define DEC_Insufficient_storage 0x00000010 /* [when malloc fails]  */
00135     #define DEC_Inexact              0x00000020
00136     #define DEC_Invalid_context      0x00000040
00137     #define DEC_Invalid_operation    0x00000080
00138     #if DECSUBSET
00139     #define DEC_Lost_digits          0x00000100
00140     #endif
00141     #define DEC_Overflow             0x00000200
00142     #define DEC_Clamped              0x00000400
00143     #define DEC_Rounded              0x00000800
00144     #define DEC_Subnormal            0x00001000
00145     #define DEC_Underflow            0x00002000
00146   #else
00147     /* IEEE flags only */
00148     #define DEC_Conversion_syntax    0x00000010
00149     #define DEC_Division_by_zero     0x00000002
00150     #define DEC_Division_impossible  0x00000010
00151     #define DEC_Division_undefined   0x00000010
00152     #define DEC_Insufficient_storage 0x00000010 /* [when malloc fails]  */
00153     #define DEC_Inexact              0x00000001
00154     #define DEC_Invalid_context      0x00000010
00155     #define DEC_Invalid_operation    0x00000010
00156     #if DECSUBSET
00157     #define DEC_Lost_digits          0x00000000
00158     #endif
00159     #define DEC_Overflow             0x00000008
00160     #define DEC_Clamped              0x00000000
00161     #define DEC_Rounded              0x00000000
00162     #define DEC_Subnormal            0x00000000
00163     #define DEC_Underflow            0x00000004
00164   #endif
00165
00166   /* IEEE 754 groupings for the flags                                 */
00167   /* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal    */
00168   /* are not in IEEE 754]                                             */
00169   #define DEC_IEEE_754_Division_by_zero  (DEC_Division_by_zero)
00170   #if DECSUBSET
00171   #define DEC_IEEE_754_Inexact           (DEC_Inexact | DEC_Lost_digits)
00172   #else
00173   #define DEC_IEEE_754_Inexact           (DEC_Inexact)
00174   #endif
00175   #define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax |     \
00176                                           DEC_Division_impossible |   \
00177                                           DEC_Division_undefined |    \
00178                                           DEC_Insufficient_storage |  \
00179                                           DEC_Invalid_context |       \
00180                                           DEC_Invalid_operation)
00181   #define DEC_IEEE_754_Overflow          (DEC_Overflow)
00182   #define DEC_IEEE_754_Underflow         (DEC_Underflow)
00183
00184   /* flags which are normally errors (result is qNaN, infinite, or 0) */
00185   #define DEC_Errors (DEC_IEEE_754_Division_by_zero |                 \
00186                       DEC_IEEE_754_Invalid_operation |                \
00187                       DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)
00188   /* flags which cause a result to become qNaN                        */
00189   #define DEC_NaNs    DEC_IEEE_754_Invalid_operation
00190
00191   /* flags which are normally for information only (finite results)   */
00192   #if DECSUBSET
00193   #define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact    \
00194                           | DEC_Lost_digits)
00195   #else
00196   #define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
00197   #endif
00198
00199   /* IEEE 854 names (for compatibility with older decNumber versions) */
00200   #define DEC_IEEE_854_Division_by_zero  DEC_IEEE_754_Division_by_zero
00201   #define DEC_IEEE_854_Inexact           DEC_IEEE_754_Inexact
00202   #define DEC_IEEE_854_Invalid_operation DEC_IEEE_754_Invalid_operation
00203   #define DEC_IEEE_854_Overflow          DEC_IEEE_754_Overflow
00204   #define DEC_IEEE_854_Underflow         DEC_IEEE_754_Underflow
00205
00206   /* Name strings for the exceptional conditions                      */
00207   #define DEC_Condition_CS "Conversion syntax"
00208   #define DEC_Condition_DZ "Division by zero"
00209   #define DEC_Condition_DI "Division impossible"
00210   #define DEC_Condition_DU "Division undefined"
00211   #define DEC_Condition_IE "Inexact"
00212   #define DEC_Condition_IS "Insufficient storage"
00213   #define DEC_Condition_IC "Invalid context"
00214   #define DEC_Condition_IO "Invalid operation"
00215   #if DECSUBSET
00216   #define DEC_Condition_LD "Lost digits"
00217   #endif
00218   #define DEC_Condition_OV "Overflow"
00219   #define DEC_Condition_PA "Clamped"
00220   #define DEC_Condition_RO "Rounded"
00221   #define DEC_Condition_SU "Subnormal"
00222   #define DEC_Condition_UN "Underflow"
00223   #define DEC_Condition_ZE "No status"
00224   #define DEC_Condition_MU "Multiple status"
00225   #define DEC_Condition_Length 21  /* length of the longest string,   */
00226                                    /* including terminator            */
00227
00228   /* Initialization descriptors, used by decContextDefault            */
00229   #define DEC_INIT_BASE         0
00230   #define DEC_INIT_DECIMAL32   32
00231   #define DEC_INIT_DECIMAL64   64
00232   #define DEC_INIT_DECIMAL128 128
00233   /* Synonyms */
00234   #define DEC_INIT_DECSINGLE  DEC_INIT_DECIMAL32
00235   #define DEC_INIT_DECDOUBLE  DEC_INIT_DECIMAL64
00236   #define DEC_INIT_DECQUAD    DEC_INIT_DECIMAL128
00237
00238   /* decContext routines                                              */
00239   extern decContext  * decContextClearStatus(decContext *, uint32_t);
00240   extern decContext  * decContextDefault(decContext *, int32_t);
00241   extern enum rounding decContextGetRounding(decContext *);
00242   extern uint32_t      decContextGetStatus(decContext *);
00243   extern decContext  * decContextRestoreStatus(decContext *, uint32_t, uint32_t);
00244   extern uint32_t      decContextSaveStatus(decContext *, uint32_t);
00245   extern decContext  * decContextSetRounding(decContext *, enum rounding);
00246   extern decContext  * decContextSetStatus(decContext *, uint32_t);
00247   extern decContext  * decContextSetStatusFromString(decContext *, const char *);
00248   extern decContext  * decContextSetStatusFromStringQuiet(decContext *, const char *);
00249   extern decContext  * decContextSetStatusQuiet(decContext *, uint32_t);
00250   extern const char  * decContextStatusToString(const decContext *);
00251   extern int32_t       decContextTestEndian(uint8_t);
00252   extern uint32_t      decContextTestSavedStatus(uint32_t, uint32_t);
00253   extern uint32_t      decContextTestStatus(decContext *, uint32_t);
00254   extern decContext  * decContextZeroStatus(decContext *);
00255
00256 #endif
Généré le Mon Jul 20 18:22:14 2009 pour Decimal par doxygen 1.5.1-p1


Decimal: Référence du fichier P:/wx_LIB/Dcml/decDPD.h

Référence du fichier P:/wx_LIB/Dcml/decDPD.h

Aller au code source de ce fichier.

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


Decimal: Référence du fichier P:/wx_LIB/Dcml/DecFloat.hpp

Référence du fichier P:/wx_LIB/Dcml/DecFloat.hpp

#include <cstring>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <Dcml/decNumber.c>
#include <Dcml/decContext.c>

Aller au code source de ce fichier.

Espaces de nommage

namespace | std

Classes

class | DecFloatContext
class | DecFloat_

Macros

#define | DECNUMDIGITS 128
#define | DEC_English 56
#define | DEC_French 78

Définition de type

typedef DecFloat_ | DCML

Fonctions

string | DecContextStatusString ()
bool | DecErrStatus ()
bool | operator== (const DecFloat_ &lhs, const DecFloat_ &rhs)
bool | operator< (const DecFloat_ &lhs, const DecFloat_ &rhs)
bool | operator!= (const DecFloat_ &x, const DecFloat_ &y)
bool | operator> (const DecFloat_ &x, const DecFloat_ &y)
bool | operator<= (const DecFloat_ &x, const DecFloat_ &y)
bool | operator>= (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | operator+ (const DecFloat_ &a, const DecFloat_ &b)
DecFloat_ | operator * (const DecFloat_ &a, const DecFloat_ &b)
DecFloat_ | operator- (const DecFloat_ &a, const DecFloat_ &b)
DecFloat_ | operator/ (const DecFloat_ &a, const DecFloat_ &b)
DecFloat_ | operator% (const DecFloat_ &a, const DecFloat_ &b)
DecFloat_ | abs (const DecFloat_ &a)
DecFloat_ | pow (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | DivideInteger (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | RemainderNear (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | min (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | max (const DecFloat_ &x, const DecFloat_ &y)
DecFloat_ | sqrt (const DecFloat_ &x)
ostream & | operator<< (ostream &f, const DecFloat_ &b)
istream & | operator>> (istream &f, DecFloat_ &b)

Variables

int | _EnFr_ = DEC_English
DecFloatContext | Context (DEC_INIT_DECIMAL128)

Documentation des macros

#define DEC_English 56

Définition à la ligne 38 du fichier DecFloat.hpp.

Référencé par DecFloat_::DecFloat_(), decNumberFromString(), DecFloat_::operator=(), DecFloat_::ToChar(), et DecFloat_::ToStr().

#define DEC_French 78

Définition à la ligne 39 du fichier DecFloat.hpp.

Référencé par DecFloat_::DecFloat_(), decNumberFromString(), DecFloat_::operator=(), DecFloat_::ToChar(), et DecFloat_::ToStr().

#define DECNUMDIGITS 128

Définition à la ligne 37 du fichier DecFloat.hpp.

Référencé par DecFloatContext::DecFloatContext(), DecFloat_::ToChar(), et DecFloat_::ToStr().

Documentation des définition de type

typedef DecFloat_ DCML

Définition à la ligne 642 du fichier DecFloat.hpp.

Documentation des fonctions

DecFloat_ abs ( const DecFloat_ & a ) [inline]

Définition à la ligne 578 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberAbs(), et DecFloatContext::get().

Référencé par decNumberRotate(), decNumberScaleB(), et decNumberShift().

00579 {
00580 DecFloat_ result, x=a;
00581 decNumberAbs(&(result.d), &(x.d), Context.get());
00582 return result;
00583 }

string DecContextStatusString ( )

Définition à la ligne 131 du fichier DecFloat.hpp.

Références Context, DEC_Clamped, DEC_Condition_CS, DEC_Condition_DI, DEC_Condition_DU, DEC_Condition_DZ, DEC_Condition_IC, DEC_Condition_IE, DEC_Condition_IO, DEC_Condition_IS, DEC_Condition_OV, DEC_Condition_PA, DEC_Condition_RO, DEC_Condition_SU, DEC_Condition_UN, DEC_Conversion_syntax, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_context, DEC_Invalid_operation, DEC_Overflow, DEC_Rounded, DEC_Subnormal, DEC_Underflow, et DecFloatContext::status().

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 }

bool DecErrStatus ( )

Définition à la ligne 157 du fichier DecFloat.hpp.

Références Context, DEC_Clamped, DEC_Conversion_syntax, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_context, DEC_Invalid_operation, DEC_Overflow, DEC_Rounded, DEC_Subnormal, DEC_Underflow, et DecFloatContext::status().

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 }

DecFloat_ DivideInteger | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 592 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberDivideInteger(), et DecFloatContext::get().

00593 {
00594 DecFloat_ result, a=x, b=y;
00595 decNumberDivideInteger(&(result.d), &(a.d), &(b.d), Context.get());
00596 return result;
00597 }

DecFloat_ max | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 613 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberMax(), et DecFloatContext::get().

00614 {
00615 DecFloat_ result, a=x, b=y;
00616 decNumberMax(&(result.d), &(a.d), &(b.d), Context.get());
00617 return result;
00618 }

DecFloat_ min | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 606 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberMin(), et DecFloatContext::get().

00607 {
00608 DecFloat_ result, a=x, b=y;
00609 decNumberMin(&(result.d), &(a.d), &(b.d), Context.get());
00610 return result;
00611 }

DecFloat_ operator * | ( | const DecFloat_ & | a,
 |  | const DecFloat_ & | b |
 | ) |  |  | [inline]

Définition à la ligne 554 du fichier DecFloat.hpp.

00555 {
00556 DecFloat_ x=a;
00557 return x*=b;
00558 }

bool operator!= | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 526 du fichier DecFloat.hpp.

00527 {
00528 return !(x == y);
00529 }

DecFloat_ operator% | ( | const DecFloat_ & | a,
 |  | const DecFloat_ & | b |
 | ) |  |  | [inline]

Définition à la ligne 572 du fichier DecFloat.hpp.

00573 {
00574 DecFloat_ x=a;
00575 return x%=b;
00576 }

DecFloat_ operator+ | ( | const DecFloat_ & | a,
 |  | const DecFloat_ & | b |
 | ) |  |  | [inline]

Définition à la ligne 548 du fichier DecFloat.hpp.

00549 {
00550 DecFloat_ x=a;
00551 return x+=b;
00552 }

DecFloat_ operator- | ( | const DecFloat_ & | a,
 |  | const DecFloat_ & | b |
 | ) |  |  | [inline]

Définition à la ligne 560 du fichier DecFloat.hpp.

00561 {
00562 DecFloat_ x=a;
00563 return x-=b;
00564 }

DecFloat_ operator/ | ( | const DecFloat_ & | a,
 |  | const DecFloat_ & | b |
 | ) |  |  | [inline]

Définition à la ligne 566 du fichier DecFloat.hpp.

00567 {
00568 DecFloat_ x=a;
00569 return x/=b;
00570 }

bool operator< | ( | const DecFloat_ & | lhs,
 |  | const DecFloat_ & | rhs |
 | ) |  |  | [inline]

Définition à la ligne 511 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberCompare(), decNumberCopy_(), decNumberIsNegative, decNumberIsZero, et DecFloatContext::get().

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 }

ostream& operator<< | ( | ostream & | f,
 |  | const DecFloat_ & | b |
 | ) |  |  | [inline]

Définition à la ligne 627 du fichier DecFloat.hpp.

Références DecFloat_::ToStr().

00628 {
00629
00630 return f<<b.ToStr();
00631 }

bool operator<= | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 536 du fichier DecFloat.hpp.

00537 {
00538 return !(y < x);
00539 }

bool operator== | ( | const DecFloat_ & | lhs,
 |  | const DecFloat_ & | rhs |
 | ) |  |  | [inline]

Définition à la ligne 497 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberCompare(), decNumberCopy_(), decNumberIsZero, et DecFloatContext::get().

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 }

bool operator> | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 531 du fichier DecFloat.hpp.

00532 {
00533 return y < x;
00534 }

bool operator>= | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 541 du fichier DecFloat.hpp.

00542 {
00543 return !(x < y);
00544 }

istream& operator>> | ( | istream & | f,
 |  | DecFloat_ & | b |
 | ) |  |  | [inline]

Définition à la ligne 633 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberFromString(), et DecFloatContext::get().

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 }

DecFloat_ pow | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 585 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberPower(), et DecFloatContext::get().

Référencé par decDivideOp(), decGetDigits(), et decToString().

00586 {
00587 DecFloat_ result, a=x, b=y;
00588 decNumberPower(&(result.d), &(a.d), &(b.d), Context.get());
00589 return result;
00590 }

DecFloat_ RemainderNear | ( | const DecFloat_ & | x,
 |  | const DecFloat_ & | y |
 | ) |  |  | [inline]

Définition à la ligne 599 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberRemainderNear(), et DecFloatContext::get().

00600 {
00601 DecFloat_ result, a=x, b=y;
00602 decNumberRemainderNear(&(result.d), &(a.d), &(b.d), Context.get());
00603 return result;
00604 }

DecFloat_ sqrt ( const DecFloat_ & x ) [inline]

Définition à la ligne 620 du fichier DecFloat.hpp.

Références Context, DecFloat_::d, decNumberSquareRoot(), et DecFloatContext::get().

00621 {
00622 DecFloat_ result, a=x;
00623 decNumberSquareRoot(&(result.d), &(a.d), Context.get());
00624 return result;
00625 }

Documentation des variables

int _EnFr_ = DEC_English

Définition à la ligne 40 du fichier DecFloat.hpp.

Référencé par DecFloat_::DecFloat_(), decNumberFromString(), DecFloat_::operator=(), DecFloat_::ToChar(), et DecFloat_::ToStr().

DecFloatContext Context(DEC_INIT_DECIMAL128)

Référencé par abs(), DecContextStatusString(), DecErrStatus(), DecFloat_::DecFloat_(), DivideInteger(), max(), min(), DecFloat_::Normalize(), DecFloat_::operator *=(), DecFloat_::operator%=(), DecFloat_::operator+(), DecFloat_::operator+=(), DecFloat_::operator-(), DecFloat_::operator-=(), DecFloat_::operator/=(), operator<(), DecFloat_::operator=(), operator==(), operator>>(), pow(), DecFloat_::Quantize(), RemainderNear(), DecFloat_::Rescale(), sqrt(), DecFloat_::ToChar(), et DecFloat_::ToIntegralValue().

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


Decimal: Fichier source de P:/wx_LIB/Dcml/DecFloat.hpp

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


Decimal: Référence du fichier P:/wx_LIB/Dcml/decNumber.c

Référence du fichier P:/wx_LIB/Dcml/decNumber.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "decNumber.h"
#include "decNumberLocal.h"

Aller au code source de ce fichier.

Macros

#define | DECVERB 1
#define | powers DECPOWERS
#define | DIVIDE 0x80
#define | REMAINDER 0x40
#define | DIVIDEINT 0x20
#define | REMNEAR 0x10
#define | COMPARE 0x01
#define | COMPMAX 0x02
#define | COMPMIN 0x03
#define | COMPTOTAL 0x04
#define | COMPNAN 0x05
#define | COMPSIG 0x06
#define | COMPMAXMAG 0x07
#define | COMPMINMAG 0x08
#define | DEC_sNaN 0x40000000
#define | BADINT (Int)0x80000000
#define | BIGEVEN (Int)0x80000002
#define | BIGODD (Int)0x80000003
#define | eInt Int
#define | ueInt uInt
#define | QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
#define | decFinish(a, b, c, d) decFinalize(a,b,c,d)
#define | SPECIALARG (rhs->bits & DECSPECIAL)
#define | SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)
#define | FASTMUL (DECUSE64 && DECDPUN<5)
#define | FASTBASE 1000000000
#define | FASTDIGS 9
#define | FASTLAZY 18
#define | NEEDTWO (DECDPUN*2)
#define | LN10 "2.302585092994045684017991454684364207601"
#define | LN2 "0.6931471805599453094172321214581765680755"

Fonctions

static decNumber * | decAddOp (decNumber *, const decNumber *, const decNumber *, decContext *, uByte, uInt *)
static Flag | decBiStr (const char *, const char *, const char *)
static uInt | decCheckMath (const decNumber *, decContext *, uInt *)
static void | decApplyRound (decNumber *, decContext *, Int, uInt *)
static Int | decCompare (const decNumber *lhs, const decNumber *rhs, Flag)
static decNumber * | decCompareOp (decNumber *, const decNumber *, const decNumber *, decContext *, Flag, uInt *)
static void | decCopyFit (decNumber *, const decNumber *, decContext *, Int *, uInt *)
static decNumber * | decDecap (decNumber *, Int)
static decNumber * | decDivideOp (decNumber *, const decNumber *, const decNumber *, decContext *, Flag, uInt *)
static decNumber * | decExpOp (decNumber *, const decNumber *, decContext *, uInt *)
static void | decFinalize (decNumber *, decContext *, Int *, uInt *)
static Int | decGetDigits (Unit *, Int)
static Int | decGetInt (const decNumber *)
static decNumber * | decLnOp (decNumber *, const decNumber *, decContext *, uInt *)
static decNumber * | decMultiplyOp (decNumber *, const decNumber *, const decNumber *, decContext *, uInt *)
static decNumber * | decNaNs (decNumber *, const decNumber *, const decNumber *, decContext *, uInt *)
static decNumber * | decQuantizeOp (decNumber *, const decNumber *, const decNumber *, decContext *, Flag, uInt *)
static void | decReverse (Unit *, Unit *)
static void | decSetCoeff (decNumber *, decContext *, const Unit *, Int, Int *, uInt *)
static void | decSetMaxValue (decNumber *, decContext *)
static void | decSetOverflow (decNumber *, decContext *, uInt *)
static void | decSetSubnormal (decNumber *, decContext *, Int *, uInt *)
static Int | decShiftToLeast (Unit *, Int, Int)
static Int | decShiftToMost (Unit *, Int, Int)
static void | decStatus (decNumber *, uInt, decContext *)
static void | decToString (const decNumber *, char[], Flag)
static decNumber * | decTrim (decNumber *, decContext *, Flag, Flag, Int *)
static Int | decUnitAddSub (const Unit *, Int, const Unit *, Int, Int, Unit *, Int)
static Int | decUnitCompare (const Unit *, Int, const Unit *, Int, Int)
decNumber * | decNumberFromInt32 (decNumber *dn, Int in)
decNumber * | decNumberFromUInt32 (decNumber *dn, uInt uin)
Int | decNumberToInt32 (const decNumber *dn, decContext *set)
uInt | decNumberToUInt32 (const decNumber *dn, decContext *set)
char * | decNumberToString (const decNumber *dn, char *string)
char * | decNumberToEngString (const decNumber *dn, char *string)
decNumber * | decNumberFromString (decNumber *dn, const char chars[], decContext *set)
decNumber * | decNumberAbs (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberAdd (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberAnd (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberCompare (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberCompareSignal (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberCompareTotal (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberCompareTotalMag (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberDivide (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberDivideInteger (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberExp (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberFMA (decNumber *res, const decNumber *lhs, const decNumber *rhs, const decNumber *fhs, decContext *set)
decNumber * | decNumberInvert (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberLn (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberLogB (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberLog10 (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberMax (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberMaxMag (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberMin (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberMinMag (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberMinus (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberNextMinus (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberNextPlus (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberNextToward (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberOr (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberPlus (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberMultiply (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberPower (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberQuantize (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberNormalize (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberReduce (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberRescale (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberRemainder (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberRemainderNear (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberRotate (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberSameQuantum (decNumber *res, const decNumber *lhs, const decNumber *rhs)
decNumber * | decNumberScaleB (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberShift (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberSquareRoot (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberSubtract (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumber * | decNumberToIntegralExact (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberToIntegralValue (decNumber *res, const decNumber *rhs, decContext *set)
decNumber * | decNumberXor (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
enum decClass | decNumberClass (const decNumber *dn, decContext *set)
const char * | decNumberClassToString (enum decClass eclass)
decNumber * | decNumberCopy (decNumber *dest, const decNumber *src)
decNumber * | decNumberCopyAbs (decNumber *res, const decNumber *rhs)
decNumber * | decNumberCopyNegate (decNumber *res, const decNumber *rhs)
decNumber * | decNumberCopySign (decNumber *res, const decNumber *lhs, const decNumber *rhs)
uByte * | decNumberGetBCD (const decNumber *dn, uByte *bcd)
decNumber * | decNumberSetBCD (decNumber *dn, const uByte *bcd, uInt n)
Int | decNumberIsNormal (const decNumber *dn, decContext *set)
Int | decNumberIsSubnormal (const decNumber *dn, decContext *set)
decNumber * | decNumberTrim (decNumber *dn)
const char * | decNumberVersion (void)
decNumber * | decNumberZero (decNumber *dn)
static void | decToString (const decNumber *dn, char *string, Flag eng)

Variables

const uByte | d2utable [DECMAXD2U+1] = D2UTABLE
static Unit | uarrone [1] = {1}
static const uInt | multies [] = {131073, 26215, 5243, 1049, 210}
const uShort | LNnn [90]
static const uByte | resmap [10] = {0, 3, 3, 3, 3, 5, 7, 7, 7, 7}

Documentation des macros

#define BADINT (Int)0x80000000

Définition à la ligne 196 du fichier decNumber.c.

Référencé par decCompare(), decCompareOp(), decDivideOp(), decExpOp(), decFinalize(), decGetInt(), decNumberFromInt32(), decNumberNextToward(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decQuantizeOp(), et decUnitCompare().

#define BIGEVEN (Int)0x80000002

Définition à la ligne 198 du fichier decNumber.c.

Référencé par decGetInt(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), et decQuantizeOp().

#define BIGODD (Int)0x80000003

Définition à la ligne 199 du fichier decNumber.c.

Référencé par decGetInt(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), et decQuantizeOp().

#define COMPARE 0x01

Définition à la ligne 186 du fichier decNumber.c.

Référencé par decCompareOp(), decLnOp(), decNumberCompare(), et decNumberSquareRoot().

#define COMPMAX 0x02

Définition à la ligne 187 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberMax().

#define COMPMAXMAG 0x07

Définition à la ligne 192 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberMaxMag().

#define COMPMIN 0x03

Définition à la ligne 188 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberMin().

#define COMPMINMAG 0x08

Définition à la ligne 193 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberMinMag().

#define COMPNAN 0x05

Définition à la ligne 190 du fichier decNumber.c.

Référencé par decCompareOp().

#define COMPSIG 0x06

Définition à la ligne 191 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberCompareSignal().

#define COMPTOTAL 0x04

Définition à la ligne 189 du fichier decNumber.c.

Référencé par decCompareOp(), decNumberCompareTotal(), et decNumberCompareTotalMag().

#define DEC_sNaN 0x40000000

Définition à la ligne 195 du fichier decNumber.c.

Référencé par decCompareOp(), decNaNs(), decNumberFMA(), decNumberLog10(), decNumberNextMinus(), decNumberNextPlus(), et decStatus().

#define decFinish | ( | a,
 |  | b,
 |  | c,
 |  | d | ) | decFinalize(a,b,c,d)

Définition à la ligne 269 du fichier decNumber.c.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decLnOp(), decMultiplyOp(), decNumberLog10(), decNumberPower(), decNumberReduce(), et decNumberSquareRoot().

#define DECVERB 1

Définition à la ligne 178 du fichier decNumber.c.

#define DIVIDE 0x80

Définition à la ligne 182 du fichier decNumber.c.

Référencé par decDivideOp(), decExpOp(), decNumberDivide(), decNumberLog10(), decNumberPower(), et decNumberSquareRoot().

#define DIVIDEINT 0x20

Définition à la ligne 184 du fichier decNumber.c.

Référencé par decDivideOp(), et decNumberDivideInteger().

#define eInt Int

Définition à la ligne 205 du fichier decNumber.c.

Référencé par decDivideOp(), et decUnitAddSub().

#define FASTBASE 1000000000

Référencé par decMultiplyOp().

#define FASTDIGS 9

Référencé par decMultiplyOp().

#define FASTLAZY 18

Référencé par decMultiplyOp().

#define FASTMUL (DECUSE64 && DECDPUN<5)

Définition à la ligne 4849 du fichier decNumber.c.

#define LN10 "2.302585092994045684017991454684364207601"

Référencé par decLnOp().

#define LN2 "0.6931471805599453094172321214581765680755"

Référencé par decLnOp().

#define NEEDTWO (DECDPUN*2)

Référencé par decMultiplyOp().

#define powers DECPOWERS

Définition à la ligne 179 du fichier decNumber.c.

Référencé par decAddOp(), decDivideOp(), decExpOp(), decMultiplyOp(), decNumberAnd(), decNumberInvert(), decNumberOr(), decNumberRotate(), decNumberToInt32(), decNumberToUInt32(), decNumberXor(), decSetCoeff(), decShiftToLeast(), decShiftToMost(), decTrim(), et decUnitCompare().

#define QUOT10 | ( | u,
 |  | n | ) | ((((uInt)(u)>>(n))*multies[n])>>17)

Définition à la ligne 212 du fichier decNumber.c.

Référencé par decDivideOp(), decGetInt(), decShiftToLeast(), decShiftToMost(), decTrim(), et decUnitAddSub().

#define REMAINDER 0x40

Définition à la ligne 183 du fichier decNumber.c.

Référencé par decDivideOp(), et decNumberRemainder().

#define REMNEAR 0x10

Définition à la ligne 185 du fichier decNumber.c.

Référencé par decDivideOp(), et decNumberRemainderNear().

#define SPECIALARG (rhs->bits & DECSPECIAL)

Définition à la ligne 277 du fichier decNumber.c.

Référencé par decExpOp(), decLnOp(), decNumberSquareRoot(), et decNumberToIntegralExact().

#define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)

Définition à la ligne 278 du fichier decNumber.c.

Référencé par decAddOp(), decDivideOp(), decMultiplyOp(), decNumberPower(), decNumberSameQuantum(), et decQuantizeOp().

#define ueInt uInt

Définition à la ligne 206 du fichier decNumber.c.

Référencé par decUnitAddSub().

Documentation des fonctions

static decNumber * decAddOp | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | uByte | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 3816 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_ROUND_FLOOR, DEC_Rounded, decApplyRound(), DECBUFFER, decCopyFit(), DECDPUN, decFinish, decGetDigits(), DECINF, DECNAN, decNaNs(), DECNEG, decNumberCopy(), decNumberIsInfinite, decNumberZero(), decSetCoeff(), decShiftToMost(), DECSNAN, DECSUBSET, decUnitAddSub(), decNumber::digits, decContext::digits, decContext::emax, decContext::emin, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, powers, decContext::round, SD2U, SPECIALARGS, et uByte.

Référencé par decExpOp(), decLnOp(), decNumberAbs(), decNumberAdd(), decNumberFMA(), decNumberMinus(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPlus(), decNumberSquareRoot(), et decNumberSubtract().

03818                                                         {
03819   #if DECSUBSET
03820   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
03821   decNumber *allocrhs=NULL;        // .., rhs
03822   #endif
03823   Int   rhsshift;                  // working shift (in Units)
03824   Int   maxdigits;                 // longest logical length
03825   Int   mult;                      // multiplier
03826   Int   residue;                   // rounding accumulator
03827   uByte bits;                      // result bits
03828   Flag  diffsign;                  // non-0 if arguments have different sign
03829   Unit  *acc;                      // accumulator for result
03830   Unit  accbuff[SD2U(DECBUFFER*2+20)]; // local buffer [*2+20 reduces many
03831                                    // allocations when called from
03832                                    // other operations, notable exp]
03833   Unit  *allocacc=NULL;            // -> allocated acc buffer, iff allocated
03834   Int   reqdigits=set->digits;     // local copy; requested DIGITS
03835   Int   padding;                   // work
03836
03837   #if DECCHECK
03838   if (decCheckOperands(res, lhs, rhs, set)) return res;
03839   #endif
03840
03841   do {                             // protect allocated storage
03842     #if DECSUBSET
03843     if (!set->extended) {
03844       // reduce operands and set lostDigits status, as needed
03845       if (lhs->digits>reqdigits) {
03846         alloclhs=decRoundOperand(lhs, set, status);
03847         if (alloclhs==NULL) break;
03848         lhs=alloclhs;
03849         }
03850       if (rhs->digits>reqdigits) {
03851         allocrhs=decRoundOperand(rhs, set, status);
03852         if (allocrhs==NULL) break;
03853         rhs=allocrhs;
03854         }
03855       }
03856     #endif
03857     // [following code does not require input rounding]
03858
03859     // note whether signs differ [used all paths]
03860     diffsign=(Flag)((lhs->bits^rhs->bits^negate)&DECNEG);
03861
03862     // handle infinities and NaNs
03863     if (SPECIALARGS) {                  // a special bit set
03864       if (SPECIALARGS & (DECSNAN | DECNAN))  // a NaN
03865         decNaNs(res, lhs, rhs, set, status);
03866        else { // one or two infinities
03867         if (decNumberIsInfinite(lhs)) { // LHS is infinity
03868           // two infinities with different signs is invalid
03869           if (decNumberIsInfinite(rhs) && diffsign) {
03870             *status|=DEC_Invalid_operation;
03871             break;
03872             }
03873           bits=lhs->bits & DECNEG;      // get sign from LHS
03874           }
03875          else bits=(rhs->bits^negate) & DECNEG;// RHS must be Infinity
03876         bits|=DECINF;
03877         decNumberZero(res);
03878         res->bits=bits;                 // set +/- infinity
03879         } // an infinity
03880       break;
03881       }
03882
03883     // Quick exit for add 0s; return the non-0, modified as need be
03884     if (ISZERO(lhs)) {
03885       Int adjust;                       // work
03886       Int lexp=lhs->exponent;           // save in case LHS==RES
03887       bits=lhs->bits;                   // ..
03888       residue=0;                        // clear accumulator
03889       decCopyFit(res, rhs, set, &residue, status); // copy (as needed)
03890       res->bits^=negate;                // flip if rhs was negated
03891       #if DECSUBSET
03892       if (set->extended) {              // exponents on zeros count
03893       #endif
03894         // exponent will be the lower of the two
03895         adjust=lexp-res->exponent;      // adjustment needed [if -ve]
03896         if (ISZERO(res)) {              // both 0: special IEEE 754 rules
03897           if (adjust<0) res->exponent=lexp;  // set exponent
03898           // 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0
03899           if (diffsign) {
03900             if (set->round!=DEC_ROUND_FLOOR) res->bits=0;
03901              else res->bits=DECNEG;     // preserve 0 sign
03902             }
03903           }
03904          else { // non-0 res
03905           if (adjust<0) {     // 0-padding needed
03906             if ((res->digits-adjust)>set->digits) {
03907               adjust=res->digits-set->digits;     // to fit exactly
03908               *status|=DEC_Rounded;               // [but exact]
03909               }
03910             res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
03911             res->exponent+=adjust;                // set the exponent.
03912             }
03913           } // non-0 res
03914       #if DECSUBSET
03915         } // extended
03916       #endif
03917       decFinish(res, set, &residue, status);      // clean and finalize
03918       break;}
03919
03920     if (ISZERO(rhs)) {                  // [lhs is non-zero]
03921       Int adjust;                       // work
03922       Int rexp=rhs->exponent;           // save in case RHS==RES
03923       bits=rhs->bits;                   // be clean
03924       residue=0;                        // clear accumulator
03925       decCopyFit(res, lhs, set, &residue, status); // copy (as needed)
03926       #if DECSUBSET
03927       if (set->extended) {              // exponents on zeros count
03928       #endif
03929         // exponent will be the lower of the two
03930         // [0-0 case handled above]
03931         adjust=rexp-res->exponent;      // adjustment needed [if -ve]
03932         if (adjust<0) {     // 0-padding needed
03933           if ((res->digits-adjust)>set->digits) {
03934             adjust=res->digits-set->digits;     // to fit exactly
03935             *status|=DEC_Rounded;               // [but exact]
03936             }
03937           res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
03938           res->exponent+=adjust;                // set the exponent.
03939           }
03940       #if DECSUBSET
03941         } // extended
03942       #endif
03943       decFinish(res, set, &residue, status);      // clean and finalize
03944       break;}
03945
03946     // [NB: both fastpath and mainpath code below assume these cases
03947     // (notably 0-0) have already been handled]
03948
03949     // calculate the padding needed to align the operands
03950     padding=rhs->exponent-lhs->exponent;
03951
03952     // Fastpath cases where the numbers are aligned and normal, the RHS
03953     // is all in one unit, no operand rounding is needed, and no carry,
03954     // lengthening, or borrow is needed
03955     if (padding==0
03956         && rhs->digits<=DECDPUN
03957         && rhs->exponent>=set->emin     // [some normals drop through]
03958         && rhs->exponent<=set->emax-set->digits+1 // [could clamp]
03959         && rhs->digits<=reqdigits
03960         && lhs->digits<=reqdigits) {
03961       Int partial=*lhs->lsu;
03962       if (!diffsign) {                  // adding
03963         partial+=*rhs->lsu;
03964         if ((partial<=DECDPUNMAX)       // result fits in unit
03965          && (lhs->digits>=DECDPUN ||    // .. and no digits-count change
03966              partial<(Int)powers[lhs->digits])) { // ..
03967           if (res!=lhs) decNumberCopy(res, lhs);  // not in place
03968           *res->lsu=(Unit)partial;      // [copy could have overwritten RHS]
03969           break;
03970           }
03971         // else drop out for careful add
03972         }
03973        else {                           // signs differ
03974         partial-=*rhs->lsu;
03975         if (partial>0) { // no borrow needed, and non-0 result
03976           if (res!=lhs) decNumberCopy(res, lhs);  // not in place
03977           *res->lsu=(Unit)partial;
03978           // this could have reduced digits [but result>0]
03979           res->digits=decGetDigits(res->lsu, D2U(res->digits));
03980           break;
03981           }
03982         // else drop out for careful subtract
03983         }
03984       }
03985
03986     // Now align (pad) the lhs or rhs so they can be added or
03987     // subtracted, as necessary.  If one number is much larger than
03988     // the other (that is, if in plain form there is a least one
03989     // digit between the lowest digit of one and the highest of the
03990     // other) padding with up to DIGITS-1 trailing zeros may be
03991     // needed; then apply rounding (as exotic rounding modes may be
03992     // affected by the residue).
03993     rhsshift=0;               // rhs shift to left (padding) in Units
03994     bits=lhs->bits;           // assume sign is that of LHS
03995     mult=1;                   // likely multiplier
03996
03997     // [if padding==0 the operands are aligned; no padding is needed]
03998     if (padding!=0) {
03999       // some padding needed; always pad the RHS, as any required
04000       // padding can then be effected by a simple combination of
04001       // shifts and a multiply
04002       Flag swapped=0;
04003       if (padding<0) {                  // LHS needs the padding
04004         const decNumber *t;
04005         padding=-padding;               // will be +ve
04006         bits=(uByte)(rhs->bits^negate); // assumed sign is now that of RHS
04007         t=lhs; lhs=rhs; rhs=t;
04008         swapped=1;
04009         }
04010
04011       // If, after pad, rhs would be longer than lhs by digits+1 or
04012       // more then lhs cannot affect the answer, except as a residue,
04013       // so only need to pad up to a length of DIGITS+1.
04014       if (rhs->digits+padding > lhs->digits+reqdigits+1) {
04015         // The RHS is sufficient
04016         // for residue use the relative sign indication...
04017         Int shift=reqdigits-rhs->digits;     // left shift needed
04018         residue=1;                           // residue for rounding
04019         if (diffsign) residue=-residue;      // signs differ
04020         // copy, shortening if necessary
04021         decCopyFit(res, rhs, set, &residue, status);
04022         // if it was already shorter, then need to pad with zeros
04023         if (shift>0) {
04024           res->digits=decShiftToMost(res->lsu, res->digits, shift);
04025           res->exponent-=shift;              // adjust the exponent.
04026           }
04027         // flip the result sign if unswapped and rhs was negated
04028         if (!swapped) res->bits^=negate;
04029         decFinish(res, set, &residue, status);    // done
04030         break;}
04031
04032       // LHS digits may affect result
04033       rhsshift=D2U(padding+1)-1;        // this much by Unit shift ..
04034       mult=powers[padding-(rhsshift*DECDPUN)]; // .. this by multiplication
04035       } // padding needed
04036
04037     if (diffsign) mult=-mult;           // signs differ
04038
04039     // determine the longer operand
04040     maxdigits=rhs->digits+padding;      // virtual length of RHS
04041     if (lhs->digits>maxdigits) maxdigits=lhs->digits;
04042
04043     // Decide on the result buffer to use; if possible place directly
04044     // into result.
04045     acc=res->lsu;                       // assume add direct to result
04046     // If destructive overlap, or the number is too long, or a carry or
04047     // borrow to DIGITS+1 might be possible, a buffer must be used.
04048     // [Might be worth more sophisticated tests when maxdigits==reqdigits]
04049     if ((maxdigits>=reqdigits)          // is, or could be, too large
04050      || (res==rhs && rhsshift>0)) {     // destructive overlap
04051       // buffer needed, choose it; units for maxdigits digits will be
04052       // needed, +1 Unit for carry or borrow
04053       Int need=D2U(maxdigits)+1;
04054       acc=accbuff;                      // assume use local buffer
04055       if (need*sizeof(Unit)>sizeof(accbuff)) {
04056         // printf("malloc add %ld %ld\n", need, sizeof(accbuff));
04057         allocacc=(Unit *)malloc(need*sizeof(Unit));
04058         if (allocacc==NULL) {           // hopeless -- abandon
04059           *status|=DEC_Insufficient_storage;
04060           break;}
04061         acc=allocacc;
04062         }
04063       }
04064
04065     res->bits=(uByte)(bits&DECNEG);     // it's now safe to overwrite..
04066     res->exponent=lhs->exponent;        // .. operands (even if aliased)
04067
04068     #if DECTRACE
04069       decDumpAr('A', lhs->lsu, D2U(lhs->digits));
04070       decDumpAr('B', rhs->lsu, D2U(rhs->digits));
04071       printf("  :h: %ld %ld\n", rhsshift, mult);
04072     #endif
04073
04074     // add [A+B*m] or subtract [A+B*(-m)]
04075     res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits),
04076                               rhs->lsu, D2U(rhs->digits),
04077                               rhsshift, acc, mult)
04078                *DECDPUN;           // [units -> digits]
04079     if (res->digits<0) {           // borrowed...
04080       res->digits=-res->digits;
04081       res->bits^=DECNEG;           // flip the sign
04082       }
04083     #if DECTRACE
04084       decDumpAr('+', acc, D2U(res->digits));
04085     #endif
04086
04087     // If a buffer was used the result must be copied back, possibly
04088     // shortening.  (If no buffer was used then the result must have
04089     // fit, so can't need rounding and residue must be 0.)
04090     residue=0;                     // clear accumulator
04091     if (acc!=res->lsu) {
04092       #if DECSUBSET
04093       if (set->extended) {         // round from first significant digit
04094       #endif
04095         // remove leading zeros that were added due to rounding up to
04096         // integral Units -- before the test for rounding.
04097         if (res->digits>reqdigits)
04098           res->digits=decGetDigits(acc, D2U(res->digits));
04099         decSetCoeff(res, set, acc, res->digits, &residue, status);
04100       #if DECSUBSET
04101         }
04102        else { // subset arithmetic rounds from original significant digit
04103         // May have an underestimate.  This only occurs when both
04104         // numbers fit in DECDPUN digits and are padding with a
04105         // negative multiple (-10, -100...) and the top digit(s) become
04106         // 0.  (This only matters when using X3.274 rules where the
04107         // leading zero could be included in the rounding.)
04108         if (res->digits<maxdigits) {
04109           *(acc+D2U(res->digits))=0; // ensure leading 0 is there
04110           res->digits=maxdigits;
04111           }
04112          else {
04113           // remove leading zeros that added due to rounding up to
04114           // integral Units (but only those in excess of the original
04115           // maxdigits length, unless extended) before test for rounding.
04116           if (res->digits>reqdigits) {
04117             res->digits=decGetDigits(acc, D2U(res->digits));
04118             if (res->digits<maxdigits) res->digits=maxdigits;
04119             }
04120           }
04121         decSetCoeff(res, set, acc, res->digits, &residue, status);
04122         // Now apply rounding if needed before removing leading zeros.
04123         // This is safe because subnormals are not a possibility
04124         if (residue!=0) {
04125           decApplyRound(res, set, residue, status);
04126           residue=0;                 // did what needed to be done
04127           }
04128         } // subset
04129       #endif
04130       } // used buffer
04131
04132     // strip leading zeros [these were left on in case of subset subtract]
04133     res->digits=decGetDigits(res->lsu, D2U(res->digits));
04134
04135     // apply checks and rounding
04136     decFinish(res, set, &residue, status);
04137
04138     // "When the sum of two operands with opposite signs is exactly
04139     // zero, the sign of that sum shall be '+' in all rounding modes
04140     // except round toward -Infinity, in which mode that sign shall be
04141     // '-'."  [Subset zeros also never have '-', set by decFinish.]
04142     if (ISZERO(res) && diffsign
04143      #if DECSUBSET
04144      && set->extended
04145      #endif
04146      && (*status&DEC_Inexact)==0) {
04147       if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG;   // sign -
04148                                   else res->bits&=~DECNEG;  // sign +
04149       }
04150     } while(0);                              // end protected
04151
04152   if (allocacc!=NULL) free(allocacc);        // drop any storage used
04153   #if DECSUBSET
04154   if (allocrhs!=NULL) free(allocrhs);        // ..
04155   if (alloclhs!=NULL) free(alloclhs);        // ..
04156   #endif
04157   return res;
04158   } // decAddOp

static void decApplyRound | ( | decNumber * | ,
 |  | decContext * | ,
 |  | Int | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 7083 du fichier decNumber.c.

Références DEC_Invalid_context, DEC_ROUND_05UP, DEC_ROUND_CEILING, DEC_ROUND_DOWN, DEC_ROUND_FLOOR, DEC_ROUND_HALF_DOWN, DEC_ROUND_HALF_EVEN, DEC_ROUND_HALF_UP, DEC_ROUND_UP, DECDPUN, decNumberIsNegative, decSetOverflow(), decNumber::digits, decContext::emax, decNumber::exponent, Int, decNumber::lsu, decContext::round, et uInt.

Référencé par decAddOp(), decFinalize(), decQuantizeOp(), et decSetSubnormal().

07084                                         {
07085   Int  bump;                  // 1 if coefficient needs to be incremented
07086                               // -1 if coefficient needs to be decremented
07087
07088   if (residue==0) return;     // nothing to apply
07089
07090   bump=0;                     // assume a smooth ride
07091
07092   // now decide whether, and how, to round, depending on mode
07093   switch (set->round) {
07094     case DEC_ROUND_05UP: {    // round zero or five up (for reround)
07095       // This is the same as DEC_ROUND_DOWN unless there is a
07096       // positive residue and the lsd of dn is 0 or 5, in which case
07097       // it is bumped; when residue is <0, the number is therefore
07098       // bumped down unless the final digit was 1 or 6 (in which
07099       // case it is bumped down and then up -- a no-op)
07100       Int lsd5=*dn->lsu%5;     // get lsd and quintate
07101       if (residue<0 && lsd5!=1) bump=-1;
07102        else if (residue>0 && lsd5==0) bump=1;
07103       // [bump==1 could be applied directly; use common path for clarity]
07104       break;} // r-05
07105
07106     case DEC_ROUND_DOWN: {
07107       // no change, except if negative residue
07108       if (residue<0) bump=-1;
07109       break;} // r-d
07110
07111     case DEC_ROUND_HALF_DOWN: {
07112       if (residue>5) bump=1;
07113       break;} // r-h-d
07114
07115     case DEC_ROUND_HALF_EVEN: {
07116       if (residue>5) bump=1;            // >0.5 goes up
07117        else if (residue==5) {           // exactly 0.5000...
07118         // 0.5 goes up iff [new] lsd is odd
07119         if (*dn->lsu & 0x01) bump=1;
07120         }
07121       break;} // r-h-e
07122
07123     case DEC_ROUND_HALF_UP: {
07124       if (residue>=5) bump=1;
07125       break;} // r-h-u
07126
07127     case DEC_ROUND_UP: {
07128       if (residue>0) bump=1;
07129       break;} // r-u
07130
07131     case DEC_ROUND_CEILING: {
07132       // same as _UP for positive numbers, and as _DOWN for negatives
07133       // [negative residue cannot occur on 0]
07134       if (decNumberIsNegative(dn)) {
07135         if (residue<0) bump=-1;
07136         }
07137        else {
07138         if (residue>0) bump=1;
07139         }
07140       break;} // r-c
07141
07142     case DEC_ROUND_FLOOR: {
07143       // same as _UP for negative numbers, and as _DOWN for positive
07144       // [negative residue cannot occur on 0]
07145       if (!decNumberIsNegative(dn)) {
07146         if (residue<0) bump=-1;
07147         }
07148        else {
07149         if (residue>0) bump=1;
07150         }
07151       break;} // r-f
07152
07153     default: {      // e.g., DEC_ROUND_MAX
07154       *status|=DEC_Invalid_context;
07155       #if DECTRACE || (DECCHECK && DECVERB)
07156       printf("Unknown rounding mode: %d\n", set->round);
07157       #endif
07158       break;}
07159     } // switch
07160
07161   // now bump the number, up or down, if need be
07162   if (bump==0) return;                       // no action required
07163
07164   // Simply use decUnitAddSub unless bumping up and the number is
07165   // all nines.  In this special case set to 100... explicitly
07166   // and adjust the exponent by one (as otherwise could overflow
07167   // the array)
07168   // Similarly handle all-nines result if bumping down.
07169   if (bump>0) {
07170     Unit *up;                                // work
07171     uInt count=dn->digits;                   // digits to be checked
07172     for (up=dn->lsu; ; up++) {
07173       if (count<=DECDPUN) {
07174         // this is the last Unit (the msu)
07175         if (*up!=powers[count]-1) break;     // not still 9s
07176         // here if it, too, is all nines
07177         *up=(Unit)powers[count-1];           // here 999 -> 100 etc.
07178         for (up=up-1; up>=dn->lsu; up--) *up=0; // others all to 0
07179         dn->exponent++;                      // and bump exponent
07180         // [which, very rarely, could cause Overflow...]
07181         if ((dn->exponent+dn->digits)>set->emax+1) {
07182           decSetOverflow(dn, set, status);
07183           }
07184         return;                              // done
07185         }
07186       // a full unit to check, with more to come
07187       if (*up!=DECDPUNMAX) break;            // not still 9s
07188       count-=DECDPUN;
07189       } // up
07190     } // bump>0
07191    else {                                    // -1
07192     // here checking for a pre-bump of 1000... (leading 1, all
07193     // other digits zero)
07194     Unit *up, *sup;                          // work
07195     uInt count=dn->digits;                   // digits to be checked
07196     for (up=dn->lsu; ; up++) {
07197       if (count<=DECDPUN) {
07198         // this is the last Unit (the msu)
07199         if (*up!=powers[count-1]) break;     // not 100..
07200         // here if have the 1000... case
07201         sup=up;                              // save msu pointer
07202         *up=(Unit)powers[count]-1;           // here 100 in msu -> 999
07203         // others all to all-nines, too
07204         for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1;
07205         dn->exponent--;                      // and bump exponent
07206
07207         // iff the number was at the subnormal boundary (exponent=etiny)
07208         // then the exponent is now out of range, so it will in fact get
07209         // clamped to etiny and the final 9 dropped.
07210         // printf(">> emin=%d exp=%d sdig=%d\n", set->emin,
07211         //        dn->exponent, set->digits);
07212         if (dn->exponent+1==set->emin-set->digits+1) {
07213           if (count==1 && dn->digits==1) *sup=0;  // here 9 -> 0[.9]
07214            else {
07215             *sup=(Unit)powers[count-1]-1;    // here 999.. in msu -> 99..
07216             dn->digits--;
07217             }
07218           dn->exponent++;
07219           *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
07220           }
07221         return;                              // done
07222         }
07223
07224       // a full unit to check, with more to come
07225       if (*up!=0) break;                     // not still 0s
07226       count-=DECDPUN;
07227       } // up
07228
07229     } // bump<0
07230
07231   // Actual bump needed.  Do it.
07232   decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
07233   } // decApplyRound

static Flag decBiStr | ( | const char * | ,
 |  | const char * | ,
 |  | const char * |  |
 | ) |  |  | [static]

Définition à la ligne 7680 du fichier decNumber.c.

Référencé par decNumberFromString().

07680                                                                            {
07681   for (;;targ++, str1++, str2++) {
07682     if (*targ!=*str1 && *targ!=*str2) return 0;
07683     // *targ has a match in one (or both, if terminator)
07684     if (*targ=='\0') break;
07685     } // forever
07686   return 1;
07687   } // decBiStr

static uInt decCheckMath | ( | const decNumber * | ,
 |  | decContext * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 7527 du fichier decNumber.c.

Références DEC_Invalid_context, DEC_Invalid_operation, DEC_MAX_MATH, decNumber::digits, decContext::digits, decContext::emax, decContext::emin, decNumber::exponent, ISZERO, et uInt.

Référencé par decNumberExp(), decNumberFMA(), decNumberLn(), decNumberLog10(), et decNumberPower().

07528                                        {
07529   uInt save=*status;                         // record
07530   if (set->digits>DEC_MAX_MATH
07531    || set->emax>DEC_MAX_MATH
07532    || -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context;
07533    else if ((rhs->digits>DEC_MAX_MATH
07534      || rhs->exponent+rhs->digits>DEC_MAX_MATH+1
07535      || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH))
07536      && !ISZERO(rhs)) *status|=DEC_Invalid_operation;
07537   return (*status!=save);
07538   } // decCheckMath

static Int decCompare | ( | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | Flag |  |
 | ) |  |  | [static]

Définition à la ligne 6182 du fichier decNumber.c.

Références BADINT, decNumber::bits, D2U, DECINF, decNumberIsInfinite, decNumberIsNegative, decUnitCompare(), decNumber::digits, decNumber::exponent, Int, ISZERO, et decNumber::lsu.

Référencé par decCompareOp(), decExpOp(), decFinalize(), et decNumberNextToward().

06183                                 {
06184   Int   result;                    // result value
06185   Int   sigr;                      // rhs signum
06186   Int   compare;                   // work
06187
06188   result=1;                                  // assume signum(lhs)
06189   if (ISZERO(lhs)) result=0;
06190   if (abs) {
06191     if (ISZERO(rhs)) return result;          // LHS wins or both 0
06192     // RHS is non-zero
06193     if (result==0) return -1;                // LHS is 0; RHS wins
06194     // [here, both non-zero, result=1]
06195     }
06196    else {                                    // signs matter
06197     if (result && decNumberIsNegative(lhs)) result=-1;
06198     sigr=1;                                  // compute signum(rhs)
06199     if (ISZERO(rhs)) sigr=0;
06200      else if (decNumberIsNegative(rhs)) sigr=-1;
06201     if (result > sigr) return +1;            // L > R, return 1
06202     if (result < sigr) return -1;            // L < R, return -1
06203     if (result==0) return 0;                   // both 0
06204     }
06205
06206   // signums are the same; both are non-zero
06207   if ((lhs->bits | rhs->bits) & DECINF) {    // one or more infinities
06208     if (decNumberIsInfinite(rhs)) {
06209       if (decNumberIsInfinite(lhs)) result=0;// both infinite
06210        else result=-result;                  // only rhs infinite
06211       }
06212     return result;
06213     }
06214   // must compare the coefficients, allowing for exponents
06215   if (lhs->exponent>rhs->exponent) {         // LHS exponent larger
06216     // swap sides, and sign
06217     const decNumber *temp=lhs;
06218     lhs=rhs;
06219     rhs=temp;
06220     result=-result;
06221     }
06222   compare=decUnitCompare(lhs->lsu, D2U(lhs->digits),
06223                          rhs->lsu, D2U(rhs->digits),
06224                          rhs->exponent-lhs->exponent);
06225   if (compare!=BADINT) compare*=result;      // comparison succeeded
06226   return compare;
06227   } // decCompare

decNumber * decCompareOp | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | Flag | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 6017 du fichier decNumber.c.

Références BADINT, decNumber::bits, COMPARE, COMPMAX, COMPMAXMAG, COMPMIN, COMPMINMAG, COMPNAN, COMPSIG, COMPTOTAL, D2U, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_sNaN, decCompare(), decCopyFit(), decFinish, DECNAN, decNaNs(), DECNEG, decNumberIsNaN, decNumberIsNegative, decNumberIsQNaN, decNumberIsSNaN, decNumberZero(), DECSNAN, decUnitCompare(), decContext::digits, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, et uByte.

Référencé par decLnOp(), decNumberCompare(), decNumberCompareSignal(), decNumberCompareTotal(), decNumberCompareTotalMag(), decNumberMax(), decNumberMaxMag(), decNumberMin(), decNumberMinMag(), et decNumberSquareRoot().

06019                                                 {
06020   #if DECSUBSET
06021   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
06022   decNumber *allocrhs=NULL;        // .., rhs
06023   #endif
06024   Int   result=0;                  // default result value
06025   uByte merged;                    // work
06026
06027   #if DECCHECK
06028   if (decCheckOperands(res, lhs, rhs, set)) return res;
06029   #endif
06030
06031   do {                             // protect allocated storage
06032     #if DECSUBSET
06033     if (!set->extended) {
06034       // reduce operands and set lostDigits status, as needed
06035       if (lhs->digits>set->digits) {
06036         alloclhs=decRoundOperand(lhs, set, status);
06037         if (alloclhs==NULL) {result=BADINT; break;}
06038         lhs=alloclhs;
06039         }
06040       if (rhs->digits>set->digits) {
06041         allocrhs=decRoundOperand(rhs, set, status);
06042         if (allocrhs==NULL) {result=BADINT; break;}
06043         rhs=allocrhs;
06044         }
06045       }
06046     #endif
06047     // [following code does not require input rounding]
06048
06049     // If total ordering then handle differing signs 'up front'
06050     if (op==COMPTOTAL) {                // total ordering
06051       if (decNumberIsNegative(lhs) & !decNumberIsNegative(rhs)) {
06052         result=-1;
06053         break;
06054         }
06055       if (!decNumberIsNegative(lhs) & decNumberIsNegative(rhs)) {
06056         result=+1;
06057         break;
06058         }
06059       }
06060
06061     // handle NaNs specially; let infinities drop through
06062     // This assumes sNaN (even just one) leads to NaN.
06063     merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
06064     if (merged) {                       // a NaN bit set
06065       if (op==COMPARE);                 // result will be NaN
06066        else if (op==COMPSIG)            // treat qNaN as sNaN
06067         *status|=DEC_Invalid_operation | DEC_sNaN;
06068        else if (op==COMPTOTAL) {        // total ordering, always finite
06069         // signs are known to be the same; compute the ordering here
06070         // as if the signs are both positive, then invert for negatives
06071         if (!decNumberIsNaN(lhs)) result=-1;
06072          else if (!decNumberIsNaN(rhs)) result=+1;
06073          // here if both NaNs
06074          else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1;
06075          else if (decNumberIsQNaN(lhs) && decNumberIsSNaN(rhs)) result=+1;
06076          else { // both NaN or both sNaN
06077           // now it just depends on the payload
06078           result=decUnitCompare(lhs->lsu, D2U(lhs->digits),
06079                                 rhs->lsu, D2U(rhs->digits), 0);
06080           // [Error not possible, as these are 'aligned']
06081           } // both same NaNs
06082         if (decNumberIsNegative(lhs)) result=-result;
06083         break;
06084         } // total order
06085
06086        else if (merged & DECSNAN);           // sNaN -> qNaN
06087        else { // here if MIN or MAX and one or two quiet NaNs
06088         // min or max -- 754 rules ignore single NaN
06089         if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
06090           // just one NaN; force choice to be the non-NaN operand
06091           op=COMPMAX;
06092           if (lhs->bits & DECNAN) result=-1; // pick rhs
06093                              else result=+1; // pick lhs
06094           break;
06095           }
06096         } // max or min
06097       op=COMPNAN;                            // use special path
06098       decNaNs(res, lhs, rhs, set, status);   // propagate NaN
06099       break;
06100       }
06101     // have numbers
06102     if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1);
06103      else result=decCompare(lhs, rhs, 0);    // sign matters
06104     } while(0);                              // end protected
06105
06106   if (result==BADINT) *status|=DEC_Insufficient_storage; // rare
06107    else {
06108     if (op==COMPARE || op==COMPSIG ||op==COMPTOTAL) { // returning signum
06109       if (op==COMPTOTAL && result==0) {
06110         // operands are numerically equal or same NaN (and same sign,
06111         // tested first); if identical, leave result 0
06112         if (lhs->exponent!=rhs->exponent) {
06113           if (lhs->exponent<rhs->exponent) result=-1;
06114            else result=+1;
06115           if (decNumberIsNegative(lhs)) result=-result;
06116           } // lexp!=rexp
06117         } // total-order by exponent
06118       decNumberZero(res);               // [always a valid result]
06119       if (result!=0) {                  // must be -1 or +1
06120         *res->lsu=1;
06121         if (result<0) res->bits=DECNEG;
06122         }
06123       }
06124      else if (op==COMPNAN);             // special, drop through
06125      else {                             // MAX or MIN, non-NaN result
06126       Int residue=0;                    // rounding accumulator
06127       // choose the operand for the result
06128       const decNumber *choice;
06129       if (result==0) { // operands are numerically equal
06130         // choose according to sign then exponent (see 754)
06131         uByte slhs=(lhs->bits & DECNEG);
06132         uByte srhs=(rhs->bits & DECNEG);
06133         #if DECSUBSET
06134         if (!set->extended) {           // subset: force left-hand
06135           op=COMPMAX;
06136           result=+1;
06137           }
06138         else
06139         #endif
06140         if (slhs!=srhs) {          // signs differ
06141           if (slhs) result=-1;     // rhs is max
06142                else result=+1;     // lhs is max
06143           }
06144          else if (slhs && srhs) {  // both negative
06145           if (lhs->exponent<rhs->exponent) result=+1;
06146                                       else result=-1;
06147           // [if equal, use lhs, technically identical]
06148           }
06149          else {                    // both positive
06150           if (lhs->exponent>rhs->exponent) result=+1;
06151                                       else result=-1;
06152           // [ditto]
06153           }
06154         } // numerically equal
06155       // here result will be non-0; reverse if looking for MIN
06156       if (op==COMPMIN || op==COMPMINMAG) result=-result;
06157       choice=(result>0 ? lhs : rhs);    // choose
06158       // copy chosen to result, rounding if need be
06159       decCopyFit(res, choice, set, &residue, status);
06160       decFinish(res, set, &residue, status);
06161       }
06162     }
06163   #if DECSUBSET
06164   if (allocrhs!=NULL) free(allocrhs);   // free any storage used
06165   if (alloclhs!=NULL) free(alloclhs);   // ..
06166   #endif
06167   return res;
06168   } // decCompareOp

static void decCopyFit | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | Int * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 6856 du fichier decNumber.c.

Références decNumber::bits, decSetCoeff(), decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decLnOp(), decNumberLog10(), decNumberPower(), decNumberReduce(), decNumberSquareRoot(), et decQuantizeOp().

06857                                                                     {
06858   dest->bits=src->bits;
06859   dest->exponent=src->exponent;
06860   decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
06861   } // decCopyFit

static decNumber * decDecap | ( | decNumber * | ,
 |  | Int |  |
 | ) |  |  | [static]

Définition à la ligne 7644 du fichier decNumber.c.

Références D2U, DECDPUN, decGetDigits(), decNumber::digits, Int, decNumber::lsu, et MSUDIGITS.

Référencé par decNaNs(), et decNumberShift().

07644                                                     {
07645   Unit *msu;                            // -> target cut point
07646   Int cut;                              // work
07647   if (drop>=dn->digits) {               // losing the whole thing
07648     #if DECCHECK
07649     if (drop>dn->digits)
07650       printf("decDecap called with drop>digits [%ld>%ld]\n",
07651              (LI)drop, (LI)dn->digits);
07652     #endif
07653     dn->lsu[0]=0;
07654     dn->digits=1;
07655     return dn;
07656     }
07657   msu=dn->lsu+D2U(dn->digits-drop)-1;   // -> likely msu
07658   cut=MSUDIGITS(dn->digits-drop);       // digits to be in use in msu
07659   if (cut!=DECDPUN) *msu%=powers[cut];  // clear left digits
07660   // that may have left leading zero digits, so do a proper count...
07661   dn->digits=decGetDigits(dn->lsu, msu-dn->lsu+1);
07662   return dn;
07663   } // decDecap

static decNumber * decDivideOp | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | Flag | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 4230 du fichier decNumber.c.

Références BADINT, decNumber::bits, D2U, DEC_Clamped, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Insufficient_storage, DEC_Invalid_operation, DECBUFFER, decCopyFit(), DECDPUN, decFinalize(), decFinish, decGetDigits(), DECINF, DECNAN, decNaNs(), DECNEG, decNumberCopy(), decNumberIsInfinite, decNumberZero(), decSetCoeff(), decShiftToLeast(), DECSNAN, decTrim(), decUnitAddSub(), decUnitCompare(), decNumber::digits, decContext::digits, DIVIDE, DIVIDEINT, eInt, decContext::emin, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, pow(), powers, QUOT10, REMAINDER, REMNEAR, SD2U, SPECIALARGS, uByte, et uInt.

Référencé par decExpOp(), decNumberDivide(), decNumberDivideInteger(), decNumberLog10(), decNumberPower(), decNumberRemainder(), decNumberRemainderNear(), et decNumberSquareRoot().

04232                                                                        {
04233   #if DECSUBSET
04234   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
04235   decNumber *allocrhs=NULL;        // .., rhs
04236   #endif
04237   Unit  accbuff[SD2U(DECBUFFER+DECDPUN+10)]; // local buffer
04238   Unit  *acc=accbuff;              // -> accumulator array for result
04239   Unit  *allocacc=NULL;            // -> allocated buffer, iff allocated
04240   Unit  *accnext;                  // -> where next digit will go
04241   Int   acclength;                 // length of acc needed [Units]
04242   Int   accunits;                  // count of units accumulated
04243   Int   accdigits;                 // count of digits accumulated
04244
04245   Unit  varbuff[SD2U(DECBUFFER*2+DECDPUN)];  // buffer for var1
04246   Unit  *var1=varbuff;             // -> var1 array for long subtraction
04247   Unit  *varalloc=NULL;            // -> allocated buffer, iff used
04248   Unit  *msu1;                     // -> msu of var1
04249
04250   const Unit *var2;                // -> var2 array
04251   const Unit *msu2;                // -> msu of var2
04252   Int   msu2plus;                  // msu2 plus one [does not vary]
04253   eInt  msu2pair;                  // msu2 pair plus one [does not vary]
04254
04255   Int   var1units, var2units;      // actual lengths
04256   Int   var2ulen;                  // logical length (units)
04257   Int   var1initpad=0;             // var1 initial padding (digits)
04258   Int   maxdigits;                 // longest LHS or required acc length
04259   Int   mult;                      // multiplier for subtraction
04260   Unit  thisunit;                  // current unit being accumulated
04261   Int   residue;                   // for rounding
04262   Int   reqdigits=set->digits;     // requested DIGITS
04263   Int   exponent;                  // working exponent
04264   Int   maxexponent=0;             // DIVIDE maximum exponent if unrounded
04265   uByte bits;                      // working sign
04266   Unit  *target;                   // work
04267   const Unit *source;              // ..
04268   uInt  const *pow;                // ..
04269   Int   shift, cut;                // ..
04270   #if DECSUBSET
04271   Int   dropped;                   // work
04272   #endif
04273
04274   #if DECCHECK
04275   if (decCheckOperands(res, lhs, rhs, set)) return res;
04276   #endif
04277
04278   do {                             // protect allocated storage
04279     #if DECSUBSET
04280     if (!set->extended) {
04281       // reduce operands and set lostDigits status, as needed
04282       if (lhs->digits>reqdigits) {
04283         alloclhs=decRoundOperand(lhs, set, status);
04284         if (alloclhs==NULL) break;
04285         lhs=alloclhs;
04286         }
04287       if (rhs->digits>reqdigits) {
04288         allocrhs=decRoundOperand(rhs, set, status);
04289         if (allocrhs==NULL) break;
04290         rhs=allocrhs;
04291         }
04292       }
04293     #endif
04294     // [following code does not require input rounding]
04295
04296     bits=(lhs->bits^rhs->bits)&DECNEG;  // assumed sign for divisions
04297
04298     // handle infinities and NaNs
04299     if (SPECIALARGS) {                  // a special bit set
04300       if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
04301         decNaNs(res, lhs, rhs, set, status);
04302         break;
04303         }
04304       // one or two infinities
04305       if (decNumberIsInfinite(lhs)) {   // LHS (dividend) is infinite
04306         if (decNumberIsInfinite(rhs) || // two infinities are invalid ..
04307             op & (REMAINDER | REMNEAR)) { // as is remainder of infinity
04308           *status|=DEC_Invalid_operation;
04309           break;
04310           }
04311         // [Note that infinity/0 raises no exceptions]
04312         decNumberZero(res);
04313         res->bits=bits|DECINF;          // set +/- infinity
04314         break;
04315         }
04316        else {                           // RHS (divisor) is infinite
04317         residue=0;
04318         if (op&(REMAINDER|REMNEAR)) {
04319           // result is [finished clone of] lhs
04320           decCopyFit(res, lhs, set, &residue, status);
04321           }
04322          else {  // a division
04323           decNumberZero(res);
04324           res->bits=bits;               // set +/- zero
04325           // for DIVIDEINT the exponent is always 0.  For DIVIDE, result
04326           // is a 0 with infinitely negative exponent, clamped to minimum
04327           if (op&DIVIDE) {
04328             res->exponent=set->emin-set->digits+1;
04329             *status|=DEC_Clamped;
04330             }
04331           }
04332         decFinish(res, set, &residue, status);
04333         break;
04334         }
04335       }
04336
04337     // handle 0 rhs (x/0)
04338     if (ISZERO(rhs)) {                  // x/0 is always exceptional
04339       if (ISZERO(lhs)) {
04340         decNumberZero(res);             // [after lhs test]
04341         *status|=DEC_Division_undefined;// 0/0 will become NaN
04342         }
04343        else {
04344         decNumberZero(res);
04345         if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation;
04346          else {
04347           *status|=DEC_Division_by_zero; // x/0
04348           res->bits=bits|DECINF;         // .. is +/- Infinity
04349           }
04350         }
04351       break;}
04352
04353     // handle 0 lhs (0/x)
04354     if (ISZERO(lhs)) {                  // 0/x [x!=0]
04355       #if DECSUBSET
04356       if (!set->extended) decNumberZero(res);
04357        else {
04358       #endif
04359         if (op&DIVIDE) {
04360           residue=0;
04361           exponent=lhs->exponent-rhs->exponent; // ideal exponent
04362           decNumberCopy(res, lhs);      // [zeros always fit]
04363           res->bits=bits;               // sign as computed
04364           res->exponent=exponent;       // exponent, too
04365           decFinalize(res, set, &residue, status);   // check exponent
04366           }
04367          else if (op&DIVIDEINT) {
04368           decNumberZero(res);           // integer 0
04369           res->bits=bits;               // sign as computed
04370           }
04371          else {                         // a remainder
04372           exponent=rhs->exponent;       // [save in case overwrite]
04373           decNumberCopy(res, lhs);      // [zeros always fit]
04374           if (exponent<res->exponent) res->exponent=exponent; // use lower
04375           }
04376       #if DECSUBSET
04377         }
04378       #endif
04379       break;}
04380
04381     // Precalculate exponent.  This starts off adjusted (and hence fits
04382     // in 31 bits) and becomes the usual unadjusted exponent as the
04383     // division proceeds.  The order of evaluation is important, here,
04384     // to avoid wrap.
04385     exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits);
04386
04387     // If the working exponent is -ve, then some quick exits are
04388     // possible because the quotient is known to be <1
04389     // [for REMNEAR, it needs to be < -1, as -0.5 could need work]
04390     if (exponent<0 && !(op==DIVIDE)) {
04391       if (op&DIVIDEINT) {
04392         decNumberZero(res);                  // integer part is 0
04393         #if DECSUBSET
04394         if (set->extended)
04395         #endif
04396           res->bits=bits;                    // set +/- zero
04397         break;}
04398       // fastpath remainders so long as the lhs has the smaller
04399       // (or equal) exponent
04400       if (lhs->exponent<=rhs->exponent) {
04401         if (op&REMAINDER || exponent<-1) {
04402           // It is REMAINDER or safe REMNEAR; result is [finished
04403           // clone of] lhs  (r = x - 0*y)
04404           residue=0;
04405           decCopyFit(res, lhs, set, &residue, status);
04406           decFinish(res, set, &residue, status);
04407           break;
04408           }
04409         // [unsafe REMNEAR drops through]
04410         }
04411       } // fastpaths
04412
04413     /* Long (slow) division is needed; roll up the sleeves... */
04414
04415     // The accumulator will hold the quotient of the division.
04416     // If it needs to be too long for stack storage, then allocate.
04417     acclength=D2U(reqdigits+DECDPUN);   // in Units
04418     if (acclength*sizeof(Unit)>sizeof(accbuff)) {
04419       // printf("malloc dvacc %ld units\n", acclength);
04420       allocacc=(Unit *)malloc(acclength*sizeof(Unit));
04421       if (allocacc==NULL) {             // hopeless -- abandon
04422         *status|=DEC_Insufficient_storage;
04423         break;}
04424       acc=allocacc;                     // use the allocated space
04425       }
04426
04427     // var1 is the padded LHS ready for subtractions.
04428     // If it needs to be too long for stack storage, then allocate.
04429     // The maximum units needed for var1 (long subtraction) is:
04430     // Enough for
04431     //     (rhs->digits+reqdigits-1) -- to allow full slide to right
04432     // or  (lhs->digits)             -- to allow for long lhs
04433     // whichever is larger
04434     //   +1                -- for rounding of slide to right
04435     //   +1                -- for leading 0s
04436     //   +1                -- for pre-adjust if a remainder or DIVIDEINT
04437     // [Note: unused units do not participate in decUnitAddSub data]
04438     maxdigits=rhs->digits+reqdigits-1;
04439     if (lhs->digits>maxdigits) maxdigits=lhs->digits;
04440     var1units=D2U(maxdigits)+2;
04441     // allocate a guard unit above msu1 for REMAINDERNEAR
04442     if (!(op&DIVIDE)) var1units++;
04443     if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) {
04444       // printf("malloc dvvar %ld units\n", var1units+1);
04445       varalloc=(Unit *)malloc((var1units+1)*sizeof(Unit));
04446       if (varalloc==NULL) {             // hopeless -- abandon
04447         *status|=DEC_Insufficient_storage;
04448         break;}
04449       var1=varalloc;                    // use the allocated space
04450       }
04451
04452     // Extend the lhs and rhs to full long subtraction length.  The lhs
04453     // is truly extended into the var1 buffer, with 0 padding, so a
04454     // subtract in place is always possible.  The rhs (var2) has
04455     // virtual padding (implemented by decUnitAddSub).
04456     // One guard unit was allocated above msu1 for rem=rem+rem in
04457     // REMAINDERNEAR.
04458     msu1=var1+var1units-1;              // msu of var1
04459     source=lhs->lsu+D2U(lhs->digits)-1; // msu of input array
04460     for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;
04461     for (; target>=var1; target--) *target=0;
04462
04463     // rhs (var2) is left-aligned with var1 at the start
04464     var2ulen=var1units;                 // rhs logical length (units)
04465     var2units=D2U(rhs->digits);         // rhs actual length (units)
04466     var2=rhs->lsu;                      // -> rhs array
04467     msu2=var2+var2units-1;              // -> msu of var2 [never changes]
04468     // now set up the variables which will be used for estimating the
04469     // multiplication factor.  If these variables are not exact, add
04470     // 1 to make sure that the multiplier is never overestimated.
04471     msu2plus=*msu2;                     // it's value ..
04472     if (var2units>1) msu2plus++;        // .. +1 if any more
04473     msu2pair=(eInt)*msu2*(DECDPUNMAX+1);// top two pair ..
04474     if (var2units>1) {                  // .. [else treat 2nd as 0]
04475       msu2pair+=*(msu2-1);              // ..
04476       if (var2units>2) msu2pair++;      // .. +1 if any more
04477       }
04478
04479     // The calculation is working in units, which may have leading zeros,
04480     // but the exponent was calculated on the assumption that they are
04481     // both left-aligned.  Adjust the exponent to compensate: add the
04482     // number of leading zeros in var1 msu and subtract those in var2 msu.
04483     // [This is actually done by counting the digits and negating, as
04484     // lead1=DECDPUN-digits1, and similarly for lead2.]
04485     for (pow=&powers[1]; *msu1>=*pow; pow++) exponent--;
04486     for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++;
04487
04488     // Now, if doing an integer divide or remainder, ensure that
04489     // the result will be Unit-aligned.  To do this, shift the var1
04490     // accumulator towards least if need be.  (It's much easier to
04491     // do this now than to reassemble the residue afterwards, if
04492     // doing a remainder.)  Also ensure the exponent is not negative.
04493     if (!(op&DIVIDE)) {
04494       Unit *u;                          // work
04495       // save the initial 'false' padding of var1, in digits
04496       var1initpad=(var1units-D2U(lhs->digits))*DECDPUN;
04497       // Determine the shift to do.
04498       if (exponent<0) cut=-exponent;
04499        else cut=DECDPUN-exponent%DECDPUN;
04500       decShiftToLeast(var1, var1units, cut);
04501       exponent+=cut;                    // maintain numerical value
04502       var1initpad-=cut;                 // .. and reduce padding
04503       // clean any most-significant units which were just emptied
04504       for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;
04505       } // align
04506      else { // is DIVIDE
04507       maxexponent=lhs->exponent-rhs->exponent;    // save
04508       // optimization: if the first iteration will just produce 0,
04509       // preadjust to skip it [valid for DIVIDE only]
04510       if (*msu1<*msu2) {
04511         var2ulen--;                     // shift down
04512         exponent-=DECDPUN;              // update the exponent
04513         }
04514       }
04515
04516     // ---- start the long-division loops ------------------------------
04517     accunits=0;                         // no units accumulated yet
04518     accdigits=0;                        // .. or digits
04519     accnext=acc+acclength-1;            // -> msu of acc [NB: allows digits+1]
04520     for (;;) {                          // outer forever loop
04521       thisunit=0;                       // current unit assumed 0
04522       // find the next unit
04523       for (;;) {                        // inner forever loop
04524         // strip leading zero units [from either pre-adjust or from
04525         // subtract last time around].  Leave at least one unit.
04526         for (; *msu1==0 && msu1>var1; msu1--) var1units--;
04527
04528         if (var1units<var2ulen) break;       // var1 too low for subtract
04529         if (var1units==var2ulen) {           // unit-by-unit compare needed
04530           // compare the two numbers, from msu
04531           const Unit *pv1, *pv2;
04532           Unit v2;                           // units to compare
04533           pv2=msu2;                          // -> msu
04534           for (pv1=msu1; ; pv1--, pv2--) {
04535             // v1=*pv1 -- always OK
04536             v2=0;                            // assume in padding
04537             if (pv2>=var2) v2=*pv2;          // in range
04538             if (*pv1!=v2) break;             // no longer the same
04539             if (pv1==var1) break;            // done; leave pv1 as is
04540             }
04541           // here when all inspected or a difference seen
04542           if (*pv1<v2) break;                // var1 too low to subtract
04543           if (*pv1==v2) {                    // var1 == var2
04544             // reach here if var1 and var2 are identical; subtraction
04545             // would increase digit by one, and the residue will be 0 so
04546             // the calculation is done; leave the loop with residue=0.
04547             thisunit++;                      // as though subtracted
04548             *var1=0;                         // set var1 to 0
04549             var1units=1;                     // ..
04550             break;  // from inner
04551             } // var1 == var2
04552           // *pv1>v2.  Prepare for real subtraction; the lengths are equal
04553           // Estimate the multiplier (there's always a msu1-1)...
04554           // Bring in two units of var2 to provide a good estimate.
04555           mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2pair);
04556           } // lengths the same
04557          else { // var1units > var2ulen, so subtraction is safe
04558           // The var2 msu is one unit towards the lsu of the var1 msu,
04559           // so only one unit for var2 can be used.
04560           mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2plus);
04561           }
04562         if (mult==0) mult=1;                 // must always be at least 1
04563         // subtraction needed; var1 is > var2
04564         thisunit=(Unit)(thisunit+mult);      // accumulate
04565         // subtract var1-var2, into var1; only the overlap needs
04566         // processing, as this is an in-place calculation
04567         shift=var2ulen-var2units;
04568         #if DECTRACE
04569           decDumpAr('1', &var1[shift], var1units-shift);
04570           decDumpAr('2', var2, var2units);
04571           printf("m=%ld\n", -mult);
04572         #endif
04573         decUnitAddSub(&var1[shift], var1units-shift,
04574                       var2, var2units, 0,
04575                       &var1[shift], -mult);
04576         #if DECTRACE
04577           decDumpAr('#', &var1[shift], var1units-shift);
04578         #endif
04579         // var1 now probably has leading zeros; these are removed at the
04580         // top of the inner loop.
04581         } // inner loop
04582
04583       // The next unit has been calculated in full; unless it's a
04584       // leading zero, add to acc
04585       if (accunits!=0 || thisunit!=0) {      // is first or non-zero
04586         *accnext=thisunit;                   // store in accumulator
04587         // account exactly for the new digits
04588         if (accunits==0) {
04589           accdigits++;                       // at least one
04590           for (pow=&powers[1]; thisunit>=*pow; pow++) accdigits++;
04591           }
04592          else accdigits+=DECDPUN;
04593         accunits++;                          // update count
04594         accnext--;                           // ready for next
04595         if (accdigits>reqdigits) break;      // have enough digits
04596         }
04597
04598       // if the residue is zero, the operation is done (unless divide
04599       // or divideInteger and still not enough digits yet)
04600       if (*var1==0 && var1units==1) {        // residue is 0
04601         if (op&(REMAINDER|REMNEAR)) break;
04602         if ((op&DIVIDE) && (exponent<=maxexponent)) break;
04603         // [drop through if divideInteger]
04604         }
04605       // also done enough if calculating remainder or integer
04606       // divide and just did the last ('units') unit
04607       if (exponent==0 && !(op&DIVIDE)) break;
04608
04609       // to get here, var1 is less than var2, so divide var2 by the per-
04610       // Unit power of ten and go for the next digit
04611       var2ulen--;                            // shift down
04612       exponent-=DECDPUN;                     // update the exponent
04613       } // outer loop
04614
04615     // ---- division is complete ---------------------------------------
04616     // here: acc      has at least reqdigits+1 of good results (or fewer
04617     //                if early stop), starting at accnext+1 (its lsu)
04618     //       var1     has any residue at the stopping point
04619     //       accunits is the number of digits collected in acc
04620     if (accunits==0) {             // acc is 0
04621       accunits=1;                  // show have a unit ..
04622       accdigits=1;                 // ..
04623       *accnext=0;                  // .. whose value is 0
04624       }
04625      else accnext++;               // back to last placed
04626     // accnext now -> lowest unit of result
04627
04628     residue=0;                     // assume no residue
04629     if (op&DIVIDE) {
04630       // record the presence of any residue, for rounding
04631       if (*var1!=0 || var1units>1) residue=1;
04632        else { // no residue
04633         // Had an exact division; clean up spurious trailing 0s.
04634         // There will be at most DECDPUN-1, from the final multiply,
04635         // and then only if the result is non-0 (and even) and the
04636         // exponent is 'loose'.
04637         #if DECDPUN>1
04638         Unit lsu=*accnext;
04639         if (!(lsu&0x01) && (lsu!=0)) {
04640           // count the trailing zeros
04641           Int drop=0;
04642           for (;; drop++) {    // [will terminate because lsu!=0]
04643             if (exponent>=maxexponent) break;     // don't chop real 0s
04644             #if DECDPUN<=4
04645               if ((lsu-QUOT10(lsu, drop+1)
04646                   *powers[drop+1])!=0) break;     // found non-0 digit
04647             #else
04648               if (lsu%powers[drop+1]!=0) break;   // found non-0 digit
04649             #endif
04650             exponent++;
04651             }
04652           if (drop>0) {
04653             accunits=decShiftToLeast(accnext, accunits, drop);
04654             accdigits=decGetDigits(accnext, accunits);
04655             accunits=D2U(accdigits);
04656             // [exponent was adjusted in the loop]
04657             }
04658           } // neither odd nor 0
04659         #endif
04660         } // exact divide
04661       } // divide
04662      else /* op!=DIVIDE */ {
04663       // check for coefficient overflow
04664       if (accdigits+exponent>reqdigits) {
04665         *status|=DEC_Division_impossible;
04666         break;
04667         }
04668       if (op & (REMAINDER|REMNEAR)) {
04669         // [Here, the exponent will be 0, because var1 was adjusted
04670         // appropriately.]
04671         Int postshift;                       // work
04672         Flag wasodd=0;                       // integer was odd
04673         Unit *quotlsu;                       // for save
04674         Int  quotdigits;                     // ..
04675
04676         bits=lhs->bits;                      // remainder sign is always as lhs
04677
04678         // Fastpath when residue is truly 0 is worthwhile [and
04679         // simplifies the code below]
04680         if (*var1==0 && var1units==1) {      // residue is 0
04681           Int exp=lhs->exponent;             // save min(exponents)
04682           if (rhs->exponent<exp) exp=rhs->exponent;
04683           decNumberZero(res);                // 0 coefficient
04684           #if DECSUBSET
04685           if (set->extended)
04686           #endif
04687           res->exponent=exp;                 // .. with proper exponent
04688           res->bits=(uByte)(bits&DECNEG);          // [cleaned]
04689           decFinish(res, set, &residue, status);   // might clamp
04690           break;
04691           }
04692         // note if the quotient was odd
04693         if (*accnext & 0x01) wasodd=1;       // acc is odd
04694         quotlsu=accnext;                     // save in case need to reinspect
04695         quotdigits=accdigits;                // ..
04696
04697         // treat the residue, in var1, as the value to return, via acc
04698         // calculate the unused zero digits.  This is the smaller of:
04699         //   var1 initial padding (saved above)
04700         //   var2 residual padding, which happens to be given by:
04701         postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;
04702         // [the 'exponent' term accounts for the shifts during divide]
04703         if (var1initpad<postshift) postshift=var1initpad;
04704
04705         // shift var1 the requested amount, and adjust its digits
04706         var1units=decShiftToLeast(var1, var1units, postshift);
04707         accnext=var1;
04708         accdigits=decGetDigits(var1, var1units);
04709         accunits=D2U(accdigits);
04710
04711         exponent=lhs->exponent;         // exponent is smaller of lhs & rhs
04712         if (rhs->exponent<exponent) exponent=rhs->exponent;
04713
04714         // Now correct the result if doing remainderNear; if it
04715         // (looking just at coefficients) is > rhs/2, or == rhs/2 and
04716         // the integer was odd then the result should be rem-rhs.
04717         if (op&REMNEAR) {
04718           Int compare, tarunits;        // work
04719           Unit *up;                     // ..
04720           // calculate remainder*2 into the var1 buffer (which has
04721           // 'headroom' of an extra unit and hence enough space)
04722           // [a dedicated 'double' loop would be faster, here]
04723           tarunits=decUnitAddSub(accnext, accunits, accnext, accunits,
04724                                  0, accnext, 1);
04725           // decDumpAr('r', accnext, tarunits);
04726
04727           // Here, accnext (var1) holds tarunits Units with twice the
04728           // remainder's coefficient, which must now be compared to the
04729           // RHS.  The remainder's exponent may be smaller than the RHS's.
04730           compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits),
04731                                  rhs->exponent-exponent);
04732           if (compare==BADINT) {             // deep trouble
04733             *status|=DEC_Insufficient_storage;
04734             break;}
04735
04736           // now restore the remainder by dividing by two; the lsu
04737           // is known to be even.
04738           for (up=accnext; up<accnext+tarunits; up++) {
04739             Int half;              // half to add to lower unit
04740             half=*up & 0x01;
04741             *up/=2;                // [shift]
04742             if (!half) continue;
04743             *(up-1)+=(DECDPUNMAX+1)/2;
04744             }
04745           // [accunits still describes the original remainder length]
04746
04747           if (compare>0 || (compare==0 && wasodd)) { // adjustment needed
04748             Int exp, expunits, exprem;       // work
04749             // This is effectively causing round-up of the quotient,
04750             // so if it was the rare case where it was full and all
04751             // nines, it would overflow and hence division-impossible
04752             // should be raised
04753             Flag allnines=0;                 // 1 if quotient all nines
04754             if (quotdigits==reqdigits) {     // could be borderline
04755               for (up=quotlsu; ; up++) {
04756                 if (quotdigits>DECDPUN) {
04757                   if (*up!=DECDPUNMAX) break;// non-nines
04758                   }
04759                  else {                      // this is the last Unit
04760                   if (*up==powers[quotdigits]-1) allnines=1;
04761                   break;
04762                   }
04763                 quotdigits-=DECDPUN;         // checked those digits
04764                 } // up
04765               } // borderline check
04766             if (allnines) {
04767               *status|=DEC_Division_impossible;
04768               break;}
04769
04770             // rem-rhs is needed; the sign will invert.  Again, var1
04771             // can safely be used for the working Units array.
04772             exp=rhs->exponent-exponent;      // RHS padding needed
04773             // Calculate units and remainder from exponent.
04774             expunits=exp/DECDPUN;
04775             exprem=exp%DECDPUN;
04776             // subtract [A+B*(-m)]; the result will always be negative
04777             accunits=-decUnitAddSub(accnext, accunits,
04778                                     rhs->lsu, D2U(rhs->digits),
04779                                     expunits, accnext, -(Int)powers[exprem]);
04780             accdigits=decGetDigits(accnext, accunits); // count digits exactly
04781             accunits=D2U(accdigits);    // and recalculate the units for copy
04782             // [exponent is as for original remainder]
04783             bits^=DECNEG;               // flip the sign
04784             }
04785           } // REMNEAR
04786         } // REMAINDER or REMNEAR
04787       } // not DIVIDE
04788
04789     // Set exponent and bits
04790     res->exponent=exponent;
04791     res->bits=(uByte)(bits&DECNEG);          // [cleaned]
04792
04793     // Now the coefficient.
04794     decSetCoeff(res, set, accnext, accdigits, &residue, status);
04795
04796     decFinish(res, set, &residue, status);   // final cleanup
04797
04798     #if DECSUBSET
04799     // If a divide then strip trailing zeros if subset [after round]
04800     if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped);
04801     #endif
04802     } while(0);                              // end protected
04803
04804   if (varalloc!=NULL) free(varalloc);   // drop any storage used
04805   if (allocacc!=NULL) free(allocacc);   // ..
04806   #if DECSUBSET
04807   if (allocrhs!=NULL) free(allocrhs);   // ..
04808   if (alloclhs!=NULL) free(alloclhs);   // ..
04809   #endif
04810   return res;
04811   } // decDivideOp

decNumber * decExpOp | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 5240 du fichier decNumber.c.

Références BADINT, decContext::clamp, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_MIN_EMIN, DEC_Overflow, DEC_Rounded, DEC_Underflow, decAddOp(), DECBUFFER, DECCHECK, decCompare(), decContextDefault(), decCopyFit(), decDivideOp(), decFinish, decMultiplyOp(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNegative, decNumberZero(), decShiftToMost(), decNumber::digits, decContext::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, MAXI, MINI, powers, SPECIALARG, et uInt.

Référencé par decLnOp(), decNumberExp(), et decNumberPower().

05241                                                         {
05242   uInt ignore=0;                   // working status
05243   Int h;                           // adjusted exponent for 0.xxxx
05244   Int p;                           // working precision
05245   Int residue;                     // rounding residue
05246   uInt needbytes;                  // for space calculations
05247   const decNumber *x=rhs;          // (may point to safe copy later)
05248   decContext aset, tset, dset;     // working contexts
05249   Int comp;                        // work
05250
05251   // the argument is often copied to normalize it, so (unusually) it
05252   // is treated like other buffers, using DECBUFFER, +1 in case
05253   // DECBUFFER is 0
05254   decNumber bufr[D2N(DECBUFFER*2+1)];
05255   decNumber *allocrhs=NULL;        // non-NULL if rhs buffer allocated
05256
05257   // the working precision will be no more than set->digits+8+1
05258   // so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER
05259   // is 0 (and twice that for the accumulator)
05260
05261   // buffer for t, term (working precision plus)
05262   decNumber buft[D2N(DECBUFFER*2+9+1)];
05263   decNumber *allocbuft=NULL;       // -> allocated buft, iff allocated
05264   decNumber *t=buft;               // term
05265   // buffer for a, accumulator (working precision * 2), at least 9
05266   decNumber bufa[D2N(DECBUFFER*4+18+1)];
05267   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
05268   decNumber *a=bufa;               // accumulator
05269   // decNumber for the divisor term; this needs at most 9 digits
05270   // and so can be fixed size [16 so can use standard context]
05271   decNumber bufd[D2N(16)];
05272   decNumber *d=bufd;               // divisor
05273   decNumber numone;                // constant 1
05274
05275   #if DECCHECK
05276   Int iterations=0;                // for later sanity check
05277   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
05278   #endif
05279
05280   do {                                  // protect allocated storage
05281     if (SPECIALARG) {                   // handle infinities and NaNs
05282       if (decNumberIsInfinite(rhs)) {   // an infinity
05283         if (decNumberIsNegative(rhs))   // -Infinity -> +0
05284           decNumberZero(res);
05285          else decNumberCopy(res, rhs);  // +Infinity -> self
05286         }
05287        else decNaNs(res, rhs, NULL, set, status); // a NaN
05288       break;}
05289
05290     if (ISZERO(rhs)) {                  // zeros -> exact 1
05291       decNumberZero(res);               // make clean 1
05292       *res->lsu=1;                      // ..
05293       break;}                           // [no status to set]
05294
05295     // e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path
05296     // positive and negative tiny cases which will result in inexact
05297     // 1.  This also allows the later add-accumulate to always be
05298     // exact (because its length will never be more than twice the
05299     // working precision).
05300     // The comparator (tiny) needs just one digit, so use the
05301     // decNumber d for it (reused as the divisor, etc., below); its
05302     // exponent is such that if x is positive it will have
05303     // set->digits-1 zeros between the decimal point and the digit,
05304     // which is 4, and if x is negative one more zero there as the
05305     // more precise result will be of the form 0.9999999 rather than
05306     // 1.0000001.  Hence, tiny will be 0.0000004  if digits=7 and x>0
05307     // or 0.00000004 if digits=7 and x<0.  If RHS not larger than
05308     // this then the result will be 1.000000
05309     decNumberZero(d);                   // clean
05310     *d->lsu=4;                          // set 4 ..
05311     d->exponent=-set->digits;           // * 10**(-d)
05312     if (decNumberIsNegative(rhs)) d->exponent--;  // negative case
05313     comp=decCompare(d, rhs, 1);         // signless compare
05314     if (comp==BADINT) {
05315       *status|=DEC_Insufficient_storage;
05316       break;}
05317     if (comp>=0) {                      // rhs < d
05318       Int shift=set->digits-1;
05319       decNumberZero(res);               // set 1
05320       *res->lsu=1;                      // ..
05321       res->digits=decShiftToMost(res->lsu, 1, shift);
05322       res->exponent=-shift;                  // make 1.0000...
05323       *status|=DEC_Inexact | DEC_Rounded;    // .. inexactly
05324       break;} // tiny
05325
05326     // set up the context to be used for calculating a, as this is
05327     // used on both paths below
05328     decContextDefault(&aset, DEC_INIT_DECIMAL64);
05329     // accumulator bounds are as requested (could underflow)
05330     aset.emax=set->emax;                // usual bounds
05331     aset.emin=set->emin;                // ..
05332     aset.clamp=0;                       // and no concrete format
05333
05334     // calculate the adjusted (Hull & Abrham) exponent (where the
05335     // decimal point is just to the left of the coefficient msd)
05336     h=rhs->exponent+rhs->digits;
05337     // if h>8 then 10**h cannot be calculated safely; however, when
05338     // h=8 then exp(|rhs|) will be at least exp(1E+7) which is at
05339     // least 6.59E+4342944, so (due to the restriction on Emax/Emin)
05340     // overflow (or underflow to 0) is guaranteed -- so this case can
05341     // be handled by simply forcing the appropriate excess
05342     if (h>8) {                          // overflow/underflow
05343       // set up here so Power call below will over or underflow to
05344       // zero; set accumulator to either 2 or 0.02
05345       // [stack buffer for a is always big enough for this]
05346       decNumberZero(a);
05347       *a->lsu=2;                        // not 1 but < exp(1)
05348       if (decNumberIsNegative(rhs)) a->exponent=-2; // make 0.02
05349       h=8;                              // clamp so 10**h computable
05350       p=9;                              // set a working precision
05351       }
05352      else {                             // h<=8
05353       Int maxlever=(rhs->digits>8?1:0);
05354       // [could/should increase this for precisions >40 or so, too]
05355
05356       // if h is 8, cannot normalize to a lower upper limit because
05357       // the final result will not be computable (see notes above),
05358       // but leverage can be applied whenever h is less than 8.
05359       // Apply as much as possible, up to a MAXLEVER digits, which
05360       // sets the tradeoff against the cost of the later a**(10**h).
05361       // As h is increased, the working precision below also
05362       // increases to compensate for the "constant digits at the
05363       // front" effect.
05364       Int lever=MINI(8-h, maxlever);    // leverage attainable
05365       Int use=-rhs->digits-lever;       // exponent to use for RHS
05366       h+=lever;                         // apply leverage selected
05367       if (h<0) {                        // clamp
05368         use+=h;                         // [may end up subnormal]
05369         h=0;
05370         }
05371       // Take a copy of RHS if it needs normalization (true whenever x>=1)
05372       if (rhs->exponent!=use) {
05373         decNumber *newrhs=bufr;         // assume will fit on stack
05374         needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
05375         if (needbytes>sizeof(bufr)) {   // need malloc space
05376           allocrhs=(decNumber *)malloc(needbytes);
05377           if (allocrhs==NULL) {         // hopeless -- abandon
05378             *status|=DEC_Insufficient_storage;
05379             break;}
05380           newrhs=allocrhs;              // use the allocated space
05381           }
05382         decNumberCopy(newrhs, rhs);     // copy to safe space
05383         newrhs->exponent=use;           // normalize; now <1
05384         x=newrhs;                       // ready for use
05385         // decNumberShow(x);
05386         }
05387
05388       // Now use the usual power series to evaluate exp(x).  The
05389       // series starts as 1 + x + x^2/2 ... so prime ready for the
05390       // third term by setting the term variable t=x, the accumulator
05391       // a=1, and the divisor d=2.
05392
05393       // First determine the working precision.  From Hull & Abrham
05394       // this is set->digits+h+2.  However, if x is 'over-precise' we
05395       // need to allow for all its digits to potentially participate
05396       // (consider an x where all the excess digits are 9s) so in
05397       // this case use x->digits+h+2
05398       p=MAXI(x->digits, set->digits)+h+2;    // [h<=8]
05399
05400       // a and t are variable precision, and depend on p, so space
05401       // must be allocated for them if necessary
05402
05403       // the accumulator needs to be able to hold 2p digits so that
05404       // the additions on the second and subsequent iterations are
05405       // sufficiently exact.
05406       needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit);
05407       if (needbytes>sizeof(bufa)) {     // need malloc space
05408         allocbufa=(decNumber *)malloc(needbytes);
05409         if (allocbufa==NULL) {          // hopeless -- abandon
05410           *status|=DEC_Insufficient_storage;
05411           break;}
05412         a=allocbufa;                    // use the allocated space
05413         }
05414       // the term needs to be able to hold p digits (which is
05415       // guaranteed to be larger than x->digits, so the initial copy
05416       // is safe); it may also be used for the raise-to-power
05417       // calculation below, which needs an extra two digits
05418       needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit);
05419       if (needbytes>sizeof(buft)) {     // need malloc space
05420         allocbuft=(decNumber *)malloc(needbytes);
05421         if (allocbuft==NULL) {          // hopeless -- abandon
05422           *status|=DEC_Insufficient_storage;
05423           break;}
05424         t=allocbuft;                    // use the allocated space
05425         }
05426
05427       decNumberCopy(t, x);              // term=x
05428       decNumberZero(a); *a->lsu=1;      // accumulator=1
05429       decNumberZero(d); *d->lsu=2;      // divisor=2
05430       decNumberZero(&numone); *numone.lsu=1; // constant 1 for increment
05431
05432       // set up the contexts for calculating a, t, and d
05433       decContextDefault(&tset, DEC_INIT_DECIMAL64);
05434       dset=tset;
05435       // accumulator bounds are set above, set precision now
05436       aset.digits=p*2;                  // double
05437       // term bounds avoid any underflow or overflow
05438       tset.digits=p;
05439       tset.emin=DEC_MIN_EMIN;           // [emax is plenty]
05440       // [dset.digits=16, etc., are sufficient]
05441
05442       // finally ready to roll
05443       for (;;) {
05444         #if DECCHECK
05445         iterations++;
05446         #endif
05447         // only the status from the accumulation is interesting
05448         // [but it should remain unchanged after first add]
05449         decAddOp(a, a, t, &aset, 0, status);           // a=a+t
05450         decMultiplyOp(t, t, x, &tset, &ignore);        // t=t*x
05451         decDivideOp(t, t, d, &tset, DIVIDE, &ignore);  // t=t/d
05452         // the iteration ends when the term cannot affect the result,
05453         // if rounded to p digits, which is when its value is smaller
05454         // than the accumulator by p+1 digits.  There must also be
05455         // full precision in a.
05456         if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))
05457             && (a->digits>=p)) break;
05458         decAddOp(d, d, &numone, &dset, 0, &ignore);    // d=d+1
05459         } // iterate
05460
05461       #if DECCHECK
05462       // just a sanity check; comment out test to show always
05463       if (iterations>p+3)
05464         printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
05465                (LI)iterations, (LI)*status, (LI)p, (LI)x->digits);
05466       #endif
05467       } // h<=8
05468
05469     // apply postconditioning: a=a**(10**h) -- this is calculated
05470     // at a slightly higher precision than Hull & Abrham suggest
05471     if (h>0) {
05472       Int seenbit=0;               // set once a 1-bit is seen
05473       Int i;                       // counter
05474       Int n=powers[h];             // always positive
05475       aset.digits=p+2;             // sufficient precision
05476       // avoid the overhead and many extra digits of decNumberPower
05477       // as all that is needed is the short 'multipliers' loop; here
05478       // accumulate the answer into t
05479       decNumberZero(t); *t->lsu=1; // acc=1
05480       for (i=1;;i++){              // for each bit [top bit ignored]
05481         // abandon if have had overflow or terminal underflow
05482         if (*status & (DEC_Overflow|DEC_Underflow)) { // interesting?
05483           if (*status&DEC_Overflow || ISZERO(t)) break;}
05484         n=n<<1;                    // move next bit to testable position
05485         if (n<0) {                 // top bit is set
05486           seenbit=1;               // OK, have a significant bit
05487           decMultiplyOp(t, t, a, &aset, status); // acc=acc*x
05488           }
05489         if (i==31) break;          // that was the last bit
05490         if (!seenbit) continue;    // no need to square 1
05491         decMultiplyOp(t, t, t, &aset, status); // acc=acc*acc [square]
05492         } /*i*/ // 32 bits
05493       // decNumberShow(t);
05494       a=t;                         // and carry on using t instead of a
05495       }
05496
05497     // Copy and round the result to res
05498     residue=1;                          // indicate dirt to right ..
05499     if (ISZERO(a)) residue=0;           // .. unless underflowed to 0
05500     aset.digits=set->digits;            // [use default rounding]
05501     decCopyFit(res, a, &aset, &residue, status); // copy & shorten
05502     decFinish(res, set, &residue, status);       // cleanup/set flags
05503     } while(0);                         // end protected
05504
05505   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
05506   if (allocbufa!=NULL) free(allocbufa); // ..
05507   if (allocbuft!=NULL) free(allocbuft); // ..
05508   // [status is handled by caller]
05509   return res;
05510   } // decExpOp

static void decFinalize | ( | decNumber * | ,
 |  | decContext * | ,
 |  | Int * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 7287 du fichier decNumber.c.

Références BADINT, decContext::clamp, DEC_Clamped, DEC_Insufficient_storage, decApplyRound(), decCompare(), decNumberZero(), decSetOverflow(), decSetSubnormal(), decShiftToMost(), decContext::digits, decNumber::digits, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, et decNumber::lsu.

Référencé par decDivideOp(), decNumberPower(), decNumberScaleB(), et decQuantizeOp().

07288                                       {
07289   Int shift;                            // shift needed if clamping
07290   Int tinyexp=set->emin-dn->digits+1;   // precalculate subnormal boundary
07291
07292   // Must be careful, here, when checking the exponent as the
07293   // adjusted exponent could overflow 31 bits [because it may already
07294   // be up to twice the expected].
07295
07296   // First test for subnormal.  This must be done before any final
07297   // round as the result could be rounded to Nmin or 0.
07298   if (dn->exponent<=tinyexp) {          // prefilter
07299     Int comp;
07300     decNumber nmin;
07301     // A very nasty case here is dn == Nmin and residue<0
07302     if (dn->exponent<tinyexp) {
07303       // Go handle subnormals; this will apply round if needed.
07304       decSetSubnormal(dn, set, residue, status);
07305       return;
07306       }
07307     // Equals case: only subnormal if dn=Nmin and negative residue
07308     decNumberZero(&nmin);
07309     nmin.lsu[0]=1;
07310     nmin.exponent=set->emin;
07311     comp=decCompare(dn, &nmin, 1);                // (signless compare)
07312     if (comp==BADINT) {                           // oops
07313       *status|=DEC_Insufficient_storage;          // abandon...
07314       return;
07315       }
07316     if (*residue<0 && comp==0) {                  // neg residue and dn==Nmin
07317       decApplyRound(dn, set, *residue, status);   // might force down
07318       decSetSubnormal(dn, set, residue, status);
07319       return;
07320       }
07321     }
07322
07323   // now apply any pending round (this could raise overflow).
07324   if (*residue!=0) decApplyRound(dn, set, *residue, status);
07325
07326   // Check for overflow [redundant in the 'rare' case] or clamp
07327   if (dn->exponent<=set->emax-set->digits+1) return;   // neither needed
07328
07329
07330   // here when might have an overflow or clamp to do
07331   if (dn->exponent>set->emax-dn->digits+1) {           // too big
07332     decSetOverflow(dn, set, status);
07333     return;
07334     }
07335   // here when the result is normal but in clamp range
07336   if (!set->clamp) return;
07337
07338   // here when need to apply the IEEE exponent clamp (fold-down)
07339   shift=dn->exponent-(set->emax-set->digits+1);
07340
07341   // shift coefficient (if non-zero)
07342   if (!ISZERO(dn)) {
07343     dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
07344     }
07345   dn->exponent-=shift;   // adjust the exponent to match
07346   *status|=DEC_Clamped;  // and record the dirty deed
07347   return;
07348   } // decFinalize

static Int decGetDigits | ( | Unit * | ,
 |  | Int |  |
 | ) |  |  | [static]

Définition à la ligne 7780 du fichier decNumber.c.

Références DECDPUN, Int, pow(), et uInt.

Référencé par decAddOp(), decDecap(), decDivideOp(), decMultiplyOp(), decNumberAnd(), decNumberFromUInt32(), decNumberInvert(), decNumberOr(), decNumberRotate(), et decNumberXor().

07780                                             {
07781   Unit *up=uar+(len-1);            // -> msu
07782   Int  digits=(len-1)*DECDPUN+1;   // possible digits excluding msu
07783   #if DECDPUN>4
07784   uInt const *pow;                 // work
07785   #endif
07786                                    // (at least 1 in final msu)
07787   #if DECCHECK
07788   if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len);
07789   #endif
07790
07791   for (; up>=uar; up--) {
07792     if (*up==0) {                  // unit is all 0s
07793       if (digits==1) break;        // a zero has one digit
07794       digits-=DECDPUN;             // adjust for 0 unit
07795       continue;}
07796     // found the first (most significant) non-zero Unit
07797     #if DECDPUN>1                  // not done yet
07798     if (*up<10) break;             // is 1-9
07799     digits++;
07800     #if DECDPUN>2                  // not done yet
07801     if (*up<100) break;            // is 10-99
07802     digits++;
07803     #if DECDPUN>3                  // not done yet
07804     if (*up<1000) break;           // is 100-999
07805     digits++;
07806     #if DECDPUN>4                  // count the rest ...
07807     for (pow=&powers[4]; *up>=*pow; pow++) digits++;
07808     #endif
07809     #endif
07810     #endif
07811     #endif
07812     break;
07813     } // up
07814   return digits;
07815   } // decGetDigits

static Int decGetInt ( const decNumber * ) [static]

Définition à la ligne 7555 du fichier decNumber.c.

Références BADINT, BIGEVEN, BIGODD, DECDPUN, decNumberIsNegative, decNumber::digits, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, et QUOT10.

Référencé par decLnOp(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), et decQuantizeOp().

07555                                           {
07556   Int  theInt;                          // result accumulator
07557   const Unit *up;                       // work
07558   Int  got;                             // digits (real or not) processed
07559   Int  ilength=dn->digits+dn->exponent; // integral length
07560   Flag neg=decNumberIsNegative(dn);     // 1 if -ve
07561
07562   // The number must be an integer that fits in 10 digits
07563   // Assert, here, that 10 is enough for any rescale Etiny
07564   #if DEC_MAX_EMAX > 999999999
07565     #error GetInt may need updating [for Emax]
07566   #endif
07567   #if DEC_MIN_EMIN < -999999999
07568     #error GetInt may need updating [for Emin]
07569   #endif
07570   if (ISZERO(dn)) return 0;             // zeros are OK, with any exponent
07571
07572   up=dn->lsu;                           // ready for lsu
07573   theInt=0;                             // ready to accumulate
07574   if (dn->exponent>=0) {                // relatively easy
07575     // no fractional part [usual]; allow for positive exponent
07576     got=dn->exponent;
07577     }
07578    else { // -ve exponent; some fractional part to check and discard
07579     Int count=-dn->exponent;            // digits to discard
07580     // spin up whole units until reach the Unit with the unit digit
07581     for (; count>=DECDPUN; up++) {
07582       if (*up!=0) return BADINT;        // non-zero Unit to discard
07583       count-=DECDPUN;
07584       }
07585     if (count==0) got=0;                // [a multiple of DECDPUN]
07586      else {                             // [not multiple of DECDPUN]
07587       Int rem;                          // work
07588       // slice off fraction digits and check for non-zero
07589       #if DECDPUN<=4
07590         theInt=QUOT10(*up, count);
07591         rem=*up-theInt*powers[count];
07592       #else
07593         rem=*up%powers[count];          // slice off discards
07594         theInt=*up/powers[count];
07595       #endif
07596       if (rem!=0) return BADINT;        // non-zero fraction
07597       // it looks good
07598       got=DECDPUN-count;                // number of digits so far
07599       up++;                             // ready for next
07600       }
07601     }
07602   // now it's known there's no fractional part
07603
07604   // tricky code now, to accumulate up to 9.3 digits
07605   if (got==0) {theInt=*up; got+=DECDPUN; up++;} // ensure lsu is there
07606
07607   if (ilength<11) {
07608     Int save=theInt;
07609     // collect any remaining unit(s)
07610     for (; got<ilength; up++) {
07611       theInt+=*up*powers[got];
07612       got+=DECDPUN;
07613       }
07614     if (ilength==10) {                  // need to check for wrap
07615       if (theInt/(Int)powers[got-DECDPUN]!=(Int)*(up-1)) ilength=11;
07616          // [that test also disallows the BADINT result case]
07617        else if (neg && theInt>1999999997) ilength=11;
07618        else if (!neg && theInt>999999999) ilength=11;
07619       if (ilength==11) theInt=save;     // restore correct low bit
07620       }
07621     }
07622
07623   if (ilength>10) {                     // too big
07624     if (theInt&1) return BIGODD;        // bottom bit 1
07625     return BIGEVEN;                     // bottom bit 0
07626     }
07627
07628   if (neg) theInt=-theInt;              // apply sign
07629   return theInt;
07630   } // decGetInt

decNumber * decLnOp | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 5600 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, COMPARE, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_MATH, DEC_ROUND_DOWN, DEC_ROUND_HALF_EVEN, DEC_Rounded, decAddOp(), DECBUFFER, DECCHECK, decCompareOp(), decContextDefault(), decCopyFit(), decExpOp(), decFinish, decGetInt(), DECINF, decMultiplyOp(), decNaNs(), DECNEG, decNumberCopy(), decNumberFromInt32(), decNumberFromString(), decNumberIsInfinite, decNumberIsNegative, decNumberIsZero, decNumberZero(), decNumber::digits, decContext::digits, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, LN10, LN2, decNumber::lsu, MAXI, decContext::round, SPECIALARG, uInt, et X10.

Référencé par decNumberLn(), decNumberLog10(), et decNumberPower().

05601                                                    {
05602   uInt ignore=0;                   // working status accumulator
05603   uInt needbytes;                  // for space calculations
05604   Int residue;                     // rounding residue
05605   Int r;                           // rhs=f*10**r [see below]
05606   Int p;                           // working precision
05607   Int pp;                          // precision for iteration
05608   Int t;                           // work
05609
05610   // buffers for a (accumulator, typically precision+2) and b
05611   // (adjustment calculator, same size)
05612   decNumber bufa[D2N(DECBUFFER+12)];
05613   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
05614   decNumber *a=bufa;               // accumulator/work
05615   decNumber bufb[D2N(DECBUFFER*2+2)];
05616   decNumber *allocbufb=NULL;       // -> allocated bufa, iff allocated
05617   decNumber *b=bufb;               // adjustment/work
05618
05619   decNumber  numone;               // constant 1
05620   decNumber  cmp;                  // work
05621   decContext aset, bset;           // working contexts
05622
05623   #if DECCHECK
05624   Int iterations=0;                // for later sanity check
05625   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
05626   #endif
05627
05628   do {                                  // protect allocated storage
05629     if (SPECIALARG) {                   // handle infinities and NaNs
05630       if (decNumberIsInfinite(rhs)) {   // an infinity
05631         if (decNumberIsNegative(rhs))   // -Infinity -> error
05632           *status|=DEC_Invalid_operation;
05633          else decNumberCopy(res, rhs);  // +Infinity -> self
05634         }
05635        else decNaNs(res, rhs, NULL, set, status); // a NaN
05636       break;}
05637
05638     if (ISZERO(rhs)) {                  // +/- zeros -> -Infinity
05639       decNumberZero(res);               // make clean
05640       res->bits=DECINF|DECNEG;          // set - infinity
05641       break;}                           // [no status to set]
05642
05643     // Non-zero negatives are bad...
05644     if (decNumberIsNegative(rhs)) {     // -x -> error
05645       *status|=DEC_Invalid_operation;
05646       break;}
05647
05648     // Here, rhs is positive, finite, and in range
05649
05650     // lookaside fastpath code for ln(2) and ln(10) at common lengths
05651     if (rhs->exponent==0 && set->digits<=40) {
05652       #if DECDPUN==1
05653       if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { // ln(10)
05654       #else
05655       if (rhs->lsu[0]==10 && rhs->digits==2) {                  // ln(10)
05656       #endif
05657         aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
05658         #define LN10 "2.302585092994045684017991454684364207601"
05659         decNumberFromString(res, LN10, &aset);
05660         *status|=(DEC_Inexact | DEC_Rounded); // is inexact
05661         break;}
05662       if (rhs->lsu[0]==2 && rhs->digits==1) { // ln(2)
05663         aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
05664         #define LN2 "0.6931471805599453094172321214581765680755"
05665         decNumberFromString(res, LN2, &aset);
05666         *status|=(DEC_Inexact | DEC_Rounded);
05667         break;}
05668       } // integer and short
05669
05670     // Determine the working precision.  This is normally the
05671     // requested precision + 2, with a minimum of 9.  However, if
05672     // the rhs is 'over-precise' then allow for all its digits to
05673     // potentially participate (consider an rhs where all the excess
05674     // digits are 9s) so in this case use rhs->digits+2.
05675     p=MAXI(rhs->digits, MAXI(set->digits, 7))+2;
05676
05677     // Allocate space for the accumulator and the high-precision
05678     // adjustment calculator, if necessary.  The accumulator must
05679     // be able to hold p digits, and the adjustment up to
05680     // rhs->digits+p digits.  They are also made big enough for 16
05681     // digits so that they can be used for calculating the initial
05682     // estimate.
05683     needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))-1)*sizeof(Unit);
05684     if (needbytes>sizeof(bufa)) {     // need malloc space
05685       allocbufa=(decNumber *)malloc(needbytes);
05686       if (allocbufa==NULL) {          // hopeless -- abandon
05687         *status|=DEC_Insufficient_storage;
05688         break;}
05689       a=allocbufa;                    // use the allocated space
05690       }
05691     pp=p+rhs->digits;
05692     needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))-1)*sizeof(Unit);
05693     if (needbytes>sizeof(bufb)) {     // need malloc space
05694       allocbufb=(decNumber *)malloc(needbytes);
05695       if (allocbufb==NULL) {          // hopeless -- abandon
05696         *status|=DEC_Insufficient_storage;
05697         break;}
05698       b=allocbufb;                    // use the allocated space
05699       }
05700
05701     // Prepare an initial estimate in acc. Calculate this by
05702     // considering the coefficient of x to be a normalized fraction,
05703     // f, with the decimal point at far left and multiplied by
05704     // 10**r.  Then, rhs=f*10**r and 0.1<=f<1, and
05705     //   ln(x) = ln(f) + ln(10)*r
05706     // Get the initial estimate for ln(f) from a small lookup
05707     // table (see above) indexed by the first two digits of f,
05708     // truncated.
05709
05710     decContextDefault(&aset, DEC_INIT_DECIMAL64); // 16-digit extended
05711     r=rhs->exponent+rhs->digits;        // 'normalised' exponent
05712     decNumberFromInt32(a, r);           // a=r
05713     decNumberFromInt32(b, 2302585);     // b=ln(10) (2.302585)
05714     b->exponent=-6;                     //  ..
05715     decMultiplyOp(a, a, b, &aset, &ignore);  // a=a*b
05716     // now get top two digits of rhs into b by simple truncate and
05717     // force to integer
05718     residue=0;                          // (no residue)
05719     aset.digits=2; aset.round=DEC_ROUND_DOWN;
05720     decCopyFit(b, rhs, &aset, &residue, &ignore); // copy & shorten
05721     b->exponent=0;                      // make integer
05722     t=decGetInt(b);                     // [cannot fail]
05723     if (t<10) t=X10(t);                 // adjust single-digit b
05724     t=LNnn[t-10];                       // look up ln(b)
05725     decNumberFromInt32(b, t>>2);        // b=ln(b) coefficient
05726     b->exponent=-(t&3)-3;               // set exponent
05727     b->bits=DECNEG;                     // ln(0.10)->ln(0.99) always -ve
05728     aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; // restore
05729     decAddOp(a, a, b, &aset, 0, &ignore); // acc=a+b
05730     // the initial estimate is now in a, with up to 4 digits correct.
05731     // When rhs is at or near Nmax the estimate will be low, so we
05732     // will approach it from below, avoiding overflow when calling exp.
05733
05734     decNumberZero(&numone); *numone.lsu=1;   // constant 1 for adjustment
05735
05736     // accumulator bounds are as requested (could underflow, but
05737     // cannot overflow)
05738     aset.emax=set->emax;
05739     aset.emin=set->emin;
05740     aset.clamp=0;                       // no concrete format
05741     // set up a context to be used for the multiply and subtract
05742     bset=aset;
05743     bset.emax=DEC_MAX_MATH*2;           // use double bounds for the
05744     bset.emin=-DEC_MAX_MATH*2;          // adjustment calculation
05745                                         // [see decExpOp call below]
05746     // for each iteration double the number of digits to calculate,
05747     // up to a maximum of p
05748     pp=9;                               // initial precision
05749     // [initially 9 as then the sequence starts 7+2, 16+2, and
05750     // 34+2, which is ideal for standard-sized numbers]
05751     aset.digits=pp;                     // working context
05752     bset.digits=pp+rhs->digits;         // wider context
05753     for (;;) {                          // iterate
05754       #if DECCHECK
05755       iterations++;
05756       if (iterations>24) break;         // consider 9 * 2**24
05757       #endif
05758       // calculate the adjustment (exp(-a)*x-1) into b.  This is a
05759       // catastrophic subtraction but it really is the difference
05760       // from 1 that is of interest.
05761       // Use the internal entry point to Exp as it allows the double
05762       // range for calculating exp(-a) when a is the tiniest subnormal.
05763       a->bits^=DECNEG;                  // make -a
05764       decExpOp(b, a, &bset, &ignore);   // b=exp(-a)
05765       a->bits^=DECNEG;                  // restore sign of a
05766       // now multiply by rhs and subtract 1, at the wider precision
05767       decMultiplyOp(b, b, rhs, &bset, &ignore);        // b=b*rhs
05768       decAddOp(b, b, &numone, &bset, DECNEG, &ignore); // b=b-1
05769
05770       // the iteration ends when the adjustment cannot affect the
05771       // result by >=0.5 ulp (at the requested digits), which
05772       // is when its value is smaller than the accumulator by
05773       // set->digits+1 digits (or it is zero) -- this is a looser
05774       // requirement than for Exp because all that happens to the
05775       // accumulator after this is the final rounding (but note that
05776       // there must also be full precision in a, or a=0).
05777
05778       if (decNumberIsZero(b) ||
05779           (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {
05780         if (a->digits==p) break;
05781         if (decNumberIsZero(a)) {
05782           decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); // rhs=1 ?
05783           if (cmp.lsu[0]==0) a->exponent=0;            // yes, exact 0
05784            else *status|=(DEC_Inexact | DEC_Rounded);  // no, inexact
05785           break;
05786           }
05787         // force padding if adjustment has gone to 0 before full length
05788         if (decNumberIsZero(b)) b->exponent=a->exponent-p;
05789         }
05790
05791       // not done yet ...
05792       decAddOp(a, a, b, &aset, 0, &ignore);  // a=a+b for next estimate
05793       if (pp==p) continue;                   // precision is at maximum
05794       // lengthen the next calculation
05795       pp=pp*2;                               // double precision
05796       if (pp>p) pp=p;                        // clamp to maximum
05797       aset.digits=pp;                        // working context
05798       bset.digits=pp+rhs->digits;            // wider context
05799       } // Newton's iteration
05800
05801     #if DECCHECK
05802     // just a sanity check; remove the test to show always
05803     if (iterations>24)
05804       printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
05805             (LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits);
05806     #endif
05807
05808     // Copy and round the result to res
05809     residue=1;                          // indicate dirt to right
05810     if (ISZERO(a)) residue=0;           // .. unless underflowed to 0
05811     aset.digits=set->digits;            // [use default rounding]
05812     decCopyFit(res, a, &aset, &residue, status); // copy & shorten
05813     decFinish(res, set, &residue, status);       // cleanup/set flags
05814     } while(0);                         // end protected
05815
05816   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
05817   if (allocbufb!=NULL) free(allocbufb); // ..
05818   // [status is handled by caller]
05819   return res;
05820   } // decLnOp

static decNumber * decMultiplyOp | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 4850 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Insufficient_storage, DEC_Invalid_operation, DECBUFFER, DECDPUN, decFinish, decGetDigits(), DECINF, DECNAN, decNaNs(), DECNEG, decNumberZero(), DECNUMMAXE, decSetCoeff(), DECSNAN, decUnitAddSub(), decContext::digits, decNumber::digits, decNumber::exponent, FASTBASE, FASTDIGS, FASTLAZY, Int, ISZERO, decNumber::lsu, NEEDTWO, powers, SD2U, SPECIALARGS, uByte, uInt, et uLong.

Référencé par decExpOp(), decLnOp(), decNumberFMA(), decNumberMultiply(), decNumberPower(), et decNumberSquareRoot().

04852                                                {
04853   Int    accunits;                 // Units of accumulator in use
04854   Int    exponent;                 // work
04855   Int    residue=0;                // rounding residue
04856   uByte  bits;                     // result sign
04857   Unit  *acc;                      // -> accumulator Unit array
04858   Int    needbytes;                // size calculator
04859   void  *allocacc=NULL;            // -> allocated accumulator, iff allocated
04860   Unit  accbuff[SD2U(DECBUFFER*4+1)]; // buffer (+1 for DECBUFFER==0,
04861                                    // *4 for calls from other operations)
04862   const Unit *mer, *mermsup;       // work
04863   Int   madlength;                 // Units in multiplicand
04864   Int   shift;                     // Units to shift multiplicand by
04865
04866   #if FASTMUL
04867     // if DECDPUN is 1 or 3 work in base 10**9, otherwise
04868     // (DECDPUN is 2 or 4) then work in base 10**8
04869     #if DECDPUN & 1                // odd
04870       #define FASTBASE 1000000000  // base
04871       #define FASTDIGS          9  // digits in base
04872       #define FASTLAZY         18  // carry resolution point [1->18]
04873     #else
04874       #define FASTBASE  100000000
04875       #define FASTDIGS          8
04876       #define FASTLAZY       1844  // carry resolution point [1->1844]
04877     #endif
04878     // three buffers are used, two for chunked copies of the operands
04879     // (base 10**8 or base 10**9) and one base 2**64 accumulator with
04880     // lazy carry evaluation
04881     uInt   zlhibuff[(DECBUFFER*2+1)/8+1]; // buffer (+1 for DECBUFFER==0)
04882     uInt  *zlhi=zlhibuff;                 // -> lhs array
04883     uInt  *alloclhi=NULL;                 // -> allocated buffer, iff allocated
04884     uInt   zrhibuff[(DECBUFFER*2+1)/8+1]; // buffer (+1 for DECBUFFER==0)
04885     uInt  *zrhi=zrhibuff;                 // -> rhs array
04886     uInt  *allocrhi=NULL;                 // -> allocated buffer, iff allocated
04887     uLong  zaccbuff[(DECBUFFER*2+1)/4+2]; // buffer (+1 for DECBUFFER==0)
04888     // [allocacc is shared for both paths, as only one will run]
04889     uLong *zacc=zaccbuff;          // -> accumulator array for exact result
04890     #if DECDPUN==1
04891     Int    zoff;                   // accumulator offset
04892     #endif
04893     uInt  *lip, *rip;              // item pointers
04894     uInt  *lmsi, *rmsi;            // most significant items
04895     Int    ilhs, irhs, iacc;       // item counts in the arrays
04896     Int    lazy;                   // lazy carry counter
04897     uLong  lcarry;                 // uLong carry
04898     uInt   carry;                  // carry (NB not uLong)
04899     Int    count;                  // work
04900     const  Unit *cup;              // ..
04901     Unit  *up;                     // ..
04902     uLong *lp;                     // ..
04903     Int    p;                      // ..
04904   #endif
04905
04906   #if DECSUBSET
04907     decNumber *alloclhs=NULL;      // -> allocated buffer, iff allocated
04908     decNumber *allocrhs=NULL;      // -> allocated buffer, iff allocated
04909   #endif
04910
04911   #if DECCHECK
04912   if (decCheckOperands(res, lhs, rhs, set)) return res;
04913   #endif
04914
04915   // precalculate result sign
04916   bits=(uByte)((lhs->bits^rhs->bits)&DECNEG);
04917
04918   // handle infinities and NaNs
04919   if (SPECIALARGS) {               // a special bit set
04920     if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
04921       decNaNs(res, lhs, rhs, set, status);
04922       return res;}
04923     // one or two infinities; Infinity * 0 is invalid
04924     if (((lhs->bits & DECINF)==0 && ISZERO(lhs))
04925       ||((rhs->bits & DECINF)==0 && ISZERO(rhs))) {
04926       *status|=DEC_Invalid_operation;
04927       return res;}
04928     decNumberZero(res);
04929     res->bits=bits|DECINF;         // infinity
04930     return res;}
04931
04932   // For best speed, as in DMSRCN [the original Rexx numerics
04933   // module], use the shorter number as the multiplier (rhs) and
04934   // the longer as the multiplicand (lhs) to minimise the number of
04935   // adds (partial products)
04936   if (lhs->digits<rhs->digits) {   // swap...
04937     const decNumber *hold=lhs;
04938     lhs=rhs;
04939     rhs=hold;
04940     }
04941
04942   do {                             // protect allocated storage
04943     #if DECSUBSET
04944     if (!set->extended) {
04945       // reduce operands and set lostDigits status, as needed
04946       if (lhs->digits>set->digits) {
04947         alloclhs=decRoundOperand(lhs, set, status);
04948         if (alloclhs==NULL) break;
04949         lhs=alloclhs;
04950         }
04951       if (rhs->digits>set->digits) {
04952         allocrhs=decRoundOperand(rhs, set, status);
04953         if (allocrhs==NULL) break;
04954         rhs=allocrhs;
04955         }
04956       }
04957     #endif
04958     // [following code does not require input rounding]
04959
04960     #if FASTMUL                    // fastpath can be used
04961     // use the fast path if there are enough digits in the shorter
04962     // operand to make the setup and takedown worthwhile
04963     #define NEEDTWO (DECDPUN*2)    // within two decUnitAddSub calls
04964     if (rhs->digits>NEEDTWO) {     // use fastpath...
04965       // calculate the number of elements in each array
04966       ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; // [ceiling]
04967       irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; // ..
04968       iacc=ilhs+irhs;
04969
04970       // allocate buffers if required, as usual
04971       needbytes=ilhs*sizeof(uInt);
04972       if (needbytes>(Int)sizeof(zlhibuff)) {
04973         alloclhi=(uInt *)malloc(needbytes);
04974         zlhi=alloclhi;}
04975       needbytes=irhs*sizeof(uInt);
04976       if (needbytes>(Int)sizeof(zrhibuff)) {
04977         allocrhi=(uInt *)malloc(needbytes);
04978         zrhi=allocrhi;}
04979
04980       // Allocating the accumulator space needs a special case when
04981       // DECDPUN=1 because when converting the accumulator to Units
04982       // after the multiplication each 8-byte item becomes 9 1-byte
04983       // units.  Therefore iacc extra bytes are needed at the front
04984       // (rounded up to a multiple of 8 bytes), and the uLong
04985       // accumulator starts offset the appropriate number of units
04986       // to the right to avoid overwrite during the unchunking.
04987       needbytes=iacc*sizeof(uLong);
04988       #if DECDPUN==1
04989       zoff=(iacc+7)/8;        // items to offset by
04990       needbytes+=zoff*8;
04991       #endif
04992       if (needbytes>(Int)sizeof(zaccbuff)) {
04993         allocacc=(uLong *)malloc(needbytes);
04994         zacc=(uLong *)allocacc;}
04995       if (zlhi==NULL||zrhi==NULL||zacc==NULL) {
04996         *status|=DEC_Insufficient_storage;
04997         break;}
04998
04999       acc=(Unit *)zacc;       // -> target Unit array
05000       #if DECDPUN==1
05001       zacc+=zoff;             // start uLong accumulator to right
05002       #endif
05003
05004       // assemble the chunked copies of the left and right sides
05005       for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)
05006         for (p=0, *lip=0; p<FASTDIGS && count>0;
05007              p+=DECDPUN, cup++, count-=DECDPUN)
05008           *lip+=*cup*powers[p];
05009       lmsi=lip-1;     // save -> msi
05010       for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)
05011         for (p=0, *rip=0; p<FASTDIGS && count>0;
05012              p+=DECDPUN, cup++, count-=DECDPUN)
05013           *rip+=*cup*powers[p];
05014       rmsi=rip-1;     // save -> msi
05015
05016       // zero the accumulator
05017       for (lp=zacc; lp<zacc+iacc; lp++) *lp=0;
05018
05019       /* Start the multiplication */
05020       // Resolving carries can dominate the cost of accumulating the
05021       // partial products, so this is only done when necessary.
05022       // Each uLong item in the accumulator can hold values up to
05023       // 2**64-1, and each partial product can be as large as
05024       // (10**FASTDIGS-1)**2.  When FASTDIGS=9, this can be added to
05025       // itself 18.4 times in a uLong without overflowing, so during
05026       // the main calculation resolution is carried out every 18th
05027       // add -- every 162 digits.  Similarly, when FASTDIGS=8, the
05028       // partial products can be added to themselves 1844.6 times in
05029       // a uLong without overflowing, so intermediate carry
05030       // resolution occurs only every 14752 digits.  Hence for common
05031       // short numbers usually only the one final carry resolution
05032       // occurs.
05033       // (The count is set via FASTLAZY to simplify experiments to
05034       // measure the value of this approach: a 35% improvement on a
05035       // [34x34] multiply.)
05036       lazy=FASTLAZY;                         // carry delay count
05037       for (rip=zrhi; rip<=rmsi; rip++) {     // over each item in rhs
05038         lp=zacc+(rip-zrhi);                  // where to add the lhs
05039         for (lip=zlhi; lip<=lmsi; lip++, lp++) { // over each item in lhs
05040           *lp+=(uLong)(*lip)*(*rip);         // [this should in-line]
05041           } // lip loop
05042         lazy--;
05043         if (lazy>0 && rip!=rmsi) continue;
05044         lazy=FASTLAZY;                       // reset delay count
05045         // spin up the accumulator resolving overflows
05046         for (lp=zacc; lp<zacc+iacc; lp++) {
05047           if (*lp<FASTBASE) continue;        // it fits
05048           lcarry=*lp/FASTBASE;               // top part [slow divide]
05049           // lcarry can exceed 2**32-1, so check again; this check
05050           // and occasional extra divide (slow) is well worth it, as
05051           // it allows FASTLAZY to be increased to 18 rather than 4
05052           // in the FASTDIGS=9 case
05053           if (lcarry<FASTBASE) carry=(uInt)lcarry;  // [usual]
05054            else { // two-place carry [fairly rare]
05055             uInt carry2=(uInt)(lcarry/FASTBASE);    // top top part
05056             *(lp+2)+=carry2;                        // add to item+2
05057             *lp-=((uLong)FASTBASE*FASTBASE*carry2); // [slow]
05058             carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); // [inline]
05059             }
05060           *(lp+1)+=carry;                    // add to item above [inline]
05061           *lp-=((uLong)FASTBASE*carry);      // [inline]
05062           } // carry resolution
05063         } // rip loop
05064
05065       // The multiplication is complete; time to convert back into
05066       // units.  This can be done in-place in the accumulator and in
05067       // 32-bit operations, because carries were resolved after the
05068       // final add.  This needs N-1 divides and multiplies for
05069       // each item in the accumulator (which will become up to N
05070       // units, where 2<=N<=9).
05071       for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {
05072         uInt item=(uInt)*lp;                 // decapitate to uInt
05073         for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) {
05074           uInt part=item/(DECDPUNMAX+1);
05075           *up=(Unit)(item-(part*(DECDPUNMAX+1)));
05076           item=part;
05077           } // p
05078         *up=(Unit)item; up++;                // [final needs no division]
05079         } // lp
05080       accunits=up-acc;                       // count of units
05081       }
05082      else { // here to use units directly, without chunking ['old code']
05083     #endif
05084
05085       // if accumulator will be too long for local storage, then allocate
05086       acc=accbuff;                 // -> assume buffer for accumulator
05087       needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit);
05088       if (needbytes>(Int)sizeof(accbuff)) {
05089         allocacc=(Unit *)malloc(needbytes);
05090         if (allocacc==NULL) {*status|=DEC_Insufficient_storage; break;}
05091         acc=(Unit *)allocacc;                // use the allocated space
05092         }
05093
05094       /* Now the main long multiplication loop */
05095       // Unlike the equivalent in the IBM Java implementation, there
05096       // is no advantage in calculating from msu to lsu.  So, do it
05097       // by the book, as it were.
05098       // Each iteration calculates ACC=ACC+MULTAND*MULT
05099       accunits=1;                  // accumulator starts at '0'
05100       *acc=0;                      // .. (lsu=0)
05101       shift=0;                     // no multiplicand shift at first
05102       madlength=D2U(lhs->digits);  // this won't change
05103       mermsup=rhs->lsu+D2U(rhs->digits); // -> msu+1 of multiplier
05104
05105       for (mer=rhs->lsu; mer<mermsup; mer++) {
05106         // Here, *mer is the next Unit in the multiplier to use
05107         // If non-zero [optimization] add it...
05108         if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift,
05109                                             lhs->lsu, madlength, 0,
05110                                             &acc[shift], *mer)
05111                                             + shift;
05112          else { // extend acc with a 0; it will be used shortly
05113           *(acc+accunits)=0;       // [this avoids length of <=0 later]
05114           accunits++;
05115           }
05116         // multiply multiplicand by 10**DECDPUN for next Unit to left
05117         shift++;                   // add this for 'logical length'
05118         } // n
05119     #if FASTMUL
05120       } // unchunked units
05121     #endif
05122     // common end-path
05123     #if DECTRACE
05124       decDumpAr('*', acc, accunits);         // Show exact result
05125     #endif
05126
05127     // acc now contains the exact result of the multiplication,
05128     // possibly with a leading zero unit; build the decNumber from
05129     // it, noting if any residue
05130     res->bits=bits;                          // set sign
05131     res->digits=decGetDigits(acc, accunits); // count digits exactly
05132
05133     // There can be a 31-bit wrap in calculating the exponent.
05134     // This can only happen if both input exponents are negative and
05135     // both their magnitudes are large.  If there was a wrap, set a
05136     // safe very negative exponent, from which decFinalize() will
05137     // raise a hard underflow shortly.
05138     exponent=lhs->exponent+rhs->exponent;    // calculate exponent
05139     if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)
05140       exponent=-2*DECNUMMAXE;                // force underflow
05141     res->exponent=exponent;                  // OK to overwrite now
05142
05143
05144     // Set the coefficient.  If any rounding, residue records
05145     decSetCoeff(res, set, acc, res->digits, &residue, status);
05146     decFinish(res, set, &residue, status);   // final cleanup
05147     } while(0);                         // end protected
05148
05149   if (allocacc!=NULL) free(allocacc);   // drop any storage used
05150   #if DECSUBSET
05151   if (allocrhs!=NULL) free(allocrhs);   // ..
05152   if (alloclhs!=NULL) free(alloclhs);   // ..
05153   #endif
05154   #if FASTMUL
05155   if (allocrhi!=NULL) free(allocrhi);   // ..
05156   if (alloclhi!=NULL) free(alloclhi);   // ..
05157   #endif
05158   return res;
05159   } // decMultiplyOp

static decNumber * decNaNs | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 7703 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DEC_sNaN, decDecap(), DECDPUN, DECNAN, decNumberCopy(), DECSNAN, decContext::digits, decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decLnOp(), decMultiplyOp(), decNumberLogB(), decNumberNextToward(), decNumberPower(), decNumberReduce(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToIntegralExact(), et decQuantizeOp().

07705                                          {
07706   // This decision tree ends up with LHS being the source pointer,
07707   // and status updated if need be
07708   if (lhs->bits & DECSNAN)
07709     *status|=DEC_Invalid_operation | DEC_sNaN;
07710    else if (rhs==NULL);
07711    else if (rhs->bits & DECSNAN) {
07712     lhs=rhs;
07713     *status|=DEC_Invalid_operation | DEC_sNaN;
07714     }
07715    else if (lhs->bits & DECNAN);
07716    else lhs=rhs;
07717
07718   // propagate the payload
07719   if (lhs->digits<=set->digits) decNumberCopy(res, lhs); // easy
07720    else { // too long
07721     const Unit *ul;
07722     Unit *ur, *uresp1;
07723     // copy safe number of units, then decapitate
07724     res->bits=lhs->bits;                // need sign etc.
07725     uresp1=res->lsu+D2U(set->digits);
07726     for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul;
07727     res->digits=D2U(set->digits)*DECDPUN;
07728     // maybe still too long
07729     if (res->digits>set->digits) decDecap(res, res->digits-set->digits);
07730     }
07731
07732   res->bits&=~DECSNAN;        // convert any sNaN to NaN, while
07733   res->bits|=DECNAN;          // .. preserving sign
07734   res->exponent=0;            // clean exponent
07735                               // [coefficient was copied/decapitated]
07736   return res;
07737   } // decNaNs

decNumber* decNumberAbs | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 757 du fichier decNumber.c.

Références decNumber::bits, decAddOp(), DECNEG, decNumberZero(), decStatus(), decNumber::exponent, uByte, et uInt.

Référencé par abs().

00758                                           {
00759   decNumber dzero;                      // for 0
00760   uInt status=0;                        // accumulator
00761
00762   #if DECCHECK
00763   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
00764   #endif
00765
00766   decNumberZero(&dzero);                // set 0
00767   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
00768   decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
00769   if (status!=0) decStatus(res, status, set);
00770   #if DECCHECK
00771   decCheckInexact(res, set);
00772   #endif
00773   return res;
00774   } // decNumberAbs

decNumber* decNumberAdd | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 789 du fichier decNumber.c.

Références decAddOp(), decStatus(), et uInt.

Référencé par DecFloat_::operator+=().

00790                                                                 {
00791   uInt status=0;                        // accumulator
00792   decAddOp(res, lhs, rhs, set, 0, &status);
00793   if (status!=0) decStatus(res, status, set);
00794   #if DECCHECK
00795   decCheckInexact(res, set);
00796   #endif
00797   return res;
00798   } // decNumberAdd

decNumber* decNumberAnd | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 815 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

00816                                                                 {
00817   const Unit *ua, *ub;                  // -> operands
00818   const Unit *msua, *msub;              // -> operand msus
00819   Unit *uc,  *msuc;                     // -> result and its msu
00820   Int   msudigs;                        // digits in res msu
00821   #if DECCHECK
00822   if (decCheckOperands(res, lhs, rhs, set)) return res;
00823   #endif
00824
00825   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
00826    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
00827     decStatus(res, DEC_Invalid_operation, set);
00828     return res;
00829     }
00830
00831   // operands are valid
00832   ua=lhs->lsu;                          // bottom-up
00833   ub=rhs->lsu;                          // ..
00834   uc=res->lsu;                          // ..
00835   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
00836   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
00837   msuc=uc+D2U(set->digits)-1;           // -> msu of result
00838   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
00839   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
00840     Unit a, b;                          // extract units
00841     if (ua>msua) a=0;
00842      else a=*ua;
00843     if (ub>msub) b=0;
00844      else b=*ub;
00845     *uc=0;                              // can now write back
00846     if (a|b) {                          // maybe 1 bits to examine
00847       Int i, j;
00848       *uc=0;                            // can now write back
00849       // This loop could be unrolled and/or use BIN2BCD tables
00850       for (i=0; i<DECDPUN; i++) {
00851         if (a&b&1) *uc=*uc+(Unit)powers[i];  // effect AND
00852         j=a%10;
00853         a=a/10;
00854         j|=b%10;
00855         b=b/10;
00856         if (j>1) {
00857           decStatus(res, DEC_Invalid_operation, set);
00858           return res;
00859           }
00860         if (uc==msuc && i==msudigs-1) break; // just did final digit
00861         } // each digit
00862       } // both OK
00863     } // each unit
00864   // [here uc-1 is the msu of the result]
00865   res->digits=decGetDigits(res->lsu, uc-res->lsu);
00866   res->exponent=0;                      // integer
00867   res->bits=0;                          // sign=0
00868   return res;  // [no status to set]
00869   } // decNumberAnd

enum decClass decNumberClass | ( | const decNumber * | dn,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 3312 du fichier decNumber.c.

Références DEC_CLASS_NEG_INF, DEC_CLASS_NEG_NORMAL, DEC_CLASS_NEG_SUBNORMAL, DEC_CLASS_NEG_ZERO, DEC_CLASS_POS_INF, DEC_CLASS_POS_NORMAL, DEC_CLASS_POS_SUBNORMAL, DEC_CLASS_POS_ZERO, DEC_CLASS_QNAN, DEC_CLASS_SNAN, decNumberIsNegative, decNumberIsNormal(), decNumberIsQNaN, decNumberIsSNaN, decNumberIsSpecial, et decNumberIsZero.

03312                                                                    {
03313   if (decNumberIsSpecial(dn)) {
03314     if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN;
03315     if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN;
03316     // must be an infinity
03317     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF;
03318     return DEC_CLASS_POS_INF;
03319     }
03320   // is finite
03321   if (decNumberIsNormal(dn, set)) { // most common
03322     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL;
03323     return DEC_CLASS_POS_NORMAL;
03324     }
03325   // is subnormal or zero
03326   if (decNumberIsZero(dn)) {    // most common
03327     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO;
03328     return DEC_CLASS_POS_ZERO;
03329     }
03330   if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL;
03331   return DEC_CLASS_POS_SUBNORMAL;
03332   } // decNumberClass

const char* decNumberClassToString ( enum decClass eclass )

Définition à la ligne 3340 du fichier decNumber.c.

Références DEC_CLASS_NEG_INF, DEC_CLASS_NEG_NORMAL, DEC_CLASS_NEG_SUBNORMAL, DEC_CLASS_NEG_ZERO, DEC_CLASS_POS_INF, DEC_CLASS_POS_NORMAL, DEC_CLASS_POS_SUBNORMAL, DEC_CLASS_POS_ZERO, DEC_CLASS_QNAN, DEC_CLASS_SNAN, DEC_ClassString_NI, DEC_ClassString_NN, DEC_ClassString_NS, DEC_ClassString_NZ, DEC_ClassString_PI, DEC_ClassString_PN, DEC_ClassString_PS, DEC_ClassString_PZ, DEC_ClassString_QN, DEC_ClassString_SN, et DEC_ClassString_UN.

03340                                                          {
03341   if (eclass==DEC_CLASS_POS_NORMAL)    return DEC_ClassString_PN;
03342   if (eclass==DEC_CLASS_NEG_NORMAL)    return DEC_ClassString_NN;
03343   if (eclass==DEC_CLASS_POS_ZERO)      return DEC_ClassString_PZ;
03344   if (eclass==DEC_CLASS_NEG_ZERO)      return DEC_ClassString_NZ;
03345   if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS;
03346   if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS;
03347   if (eclass==DEC_CLASS_POS_INF)       return DEC_ClassString_PI;
03348   if (eclass==DEC_CLASS_NEG_INF)       return DEC_ClassString_NI;
03349   if (eclass==DEC_CLASS_QNAN)          return DEC_ClassString_QN;
03350   if (eclass==DEC_CLASS_SNAN)          return DEC_ClassString_SN;
03351   return DEC_ClassString_UN;           // Unknown
03352   } // decNumberClassToString

decNumber* decNumberCompare | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 883 du fichier decNumber.c.

Références COMPARE, decCompareOp(), decStatus(), et uInt.

Référencé par decNumberPower(), operator<(), et operator==().

00884                                                                     {
00885   uInt status=0;                        // accumulator
00886   decCompareOp(res, lhs, rhs, set, COMPARE, &status);
00887   if (status!=0) decStatus(res, status, set);
00888   return res;
00889   } // decNumberCompare

decNumber* decNumberCompareSignal | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 903 du fichier decNumber.c.

Références COMPSIG, decCompareOp(), decStatus(), et uInt.

00904                                                                           {
00905   uInt status=0;                        // accumulator
00906   decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
00907   if (status!=0) decStatus(res, status, set);
00908   return res;
00909   } // decNumberCompareSignal

decNumber* decNumberCompareTotal | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 924 du fichier decNumber.c.

Références COMPTOTAL, decCompareOp(), decStatus(), et uInt.

00925                                                                          {
00926   uInt status=0;                        // accumulator
00927   decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
00928   if (status!=0) decStatus(res, status, set);
00929   return res;
00930   } // decNumberCompareTotal

decNumber* decNumberCompareTotalMag | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 945 du fichier decNumber.c.

Références decNumber::bits, COMPTOTAL, D2N, D2U, DEC_Insufficient_storage, DECBUFFER, decCompareOp(), DECNEG, decNumberCopy(), decNumberIsNegative, decStatus(), decNumber::digits, et uInt.

00946                                                                             {
00947   uInt status=0;                   // accumulator
00948   uInt needbytes;                  // for space calculations
00949   decNumber bufa[D2N(DECBUFFER+1)];// +1 in case DECBUFFER=0
00950   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
00951   decNumber bufb[D2N(DECBUFFER+1)];
00952   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
00953   decNumber *a, *b;                // temporary pointers
00954
00955   #if DECCHECK
00956   if (decCheckOperands(res, lhs, rhs, set)) return res;
00957   #endif
00958
00959   do {                                  // protect allocated storage
00960     // if either is negative, take a copy and absolute
00961     if (decNumberIsNegative(lhs)) {     // lhs<0
00962       a=bufa;
00963       needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit);
00964       if (needbytes>sizeof(bufa)) {     // need malloc space
00965         allocbufa=(decNumber *)malloc(needbytes);
00966         if (allocbufa==NULL) {          // hopeless -- abandon
00967           status|=DEC_Insufficient_storage;
00968           break;}
00969         a=allocbufa;                    // use the allocated space
00970         }
00971       decNumberCopy(a, lhs);            // copy content
00972       a->bits&=~DECNEG;                 // .. and clear the sign
00973       lhs=a;                            // use copy from here on
00974       }
00975     if (decNumberIsNegative(rhs)) {     // rhs<0
00976       b=bufb;
00977       needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
00978       if (needbytes>sizeof(bufb)) {     // need malloc space
00979         allocbufb=(decNumber *)malloc(needbytes);
00980         if (allocbufb==NULL) {          // hopeless -- abandon
00981           status|=DEC_Insufficient_storage;
00982           break;}
00983         b=allocbufb;                    // use the allocated space
00984         }
00985       decNumberCopy(b, rhs);            // copy content
00986       b->bits&=~DECNEG;                 // .. and clear the sign
00987       rhs=b;                            // use copy from here on
00988       }
00989     decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
00990     } while(0);                         // end protected
00991
00992   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
00993   if (allocbufb!=NULL) free(allocbufb); // ..
00994   if (status!=0) decStatus(res, status, set);
00995   return res;
00996   } // decNumberCompareTotalMag

decNumber* decNumberCopy | ( | decNumber * | dest,
 |  | const decNumber * | src
 | ) |  |

Définition à la ligne 3365 du fichier decNumber.c.

Références decNumber::bits, D2U, DECDPUN, decNumberZero(), decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decDivideOp(), decExpOp(), decLnOp(), decNaNs(), decNumberCompareTotalMag(), decNumberCopyAbs(), decNumberCopyNegate(), decNumberCopySign(), decNumberLog10(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToIntegralExact(), decQuantizeOp(), et DecFloat_::operator=().

03365                                                                  {
03366
03367   #if DECCHECK
03368   if (src==NULL) return decNumberZero(dest);
03369   #endif
03370
03371   if (dest==src) return dest;                // no copy required
03372
03373   // Use explicit assignments here as structure assignment could copy
03374   // more than just the lsu (for small DECDPUN).  This would not affect
03375   // the value of the results, but could disturb test harness spill
03376   // checking.
03377   dest->bits=src->bits;
03378   dest->exponent=src->exponent;
03379   dest->digits=src->digits;
03380   dest->lsu[0]=src->lsu[0];
03381   if (src->digits>DECDPUN) {                 // more Units to come
03382     const Unit *smsup, *s;                   // work
03383     Unit  *d;                                // ..
03384     // memcpy for the remaining Units would be safe as they cannot
03385     // overlap.  However, this explicit loop is faster in short cases.
03386     d=dest->lsu+1;                           // -> first destination
03387     smsup=src->lsu+D2U(src->digits);         // -> source msu+1
03388     for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
03389     }
03390   return dest;
03391   } // decNumberCopy

decNumber* decNumberCopyAbs | ( | decNumber * | res,
 |  | const decNumber * | rhs
 | ) |  |

Définition à la ligne 3405 du fichier decNumber.c.

Références decNumber::bits, DECNEG, et decNumberCopy().

Référencé par decNumberLogB().

03405                                                                    {
03406   #if DECCHECK
03407   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03408   #endif
03409   decNumberCopy(res, rhs);
03410   res->bits&=~DECNEG;                   // turn off sign
03411   return res;
03412   } // decNumberCopyAbs

decNumber* decNumberCopyNegate | ( | decNumber * | res,
 |  | const decNumber * | rhs
 | ) |  |

Définition à la ligne 3426 du fichier decNumber.c.

Références decNumber::bits, DECNEG, et decNumberCopy().

03426                                                                       {
03427   #if DECCHECK
03428   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03429   #endif
03430   decNumberCopy(res, rhs);
03431   res->bits^=DECNEG;                    // invert the sign
03432   return res;
03433   } // decNumberCopyNegate

decNumber* decNumberCopySign | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs
 | ) |  |

Définition à la ligne 3447 du fichier decNumber.c.

Références decNumber::bits, DECNEG, decNumberCopy(), et uByte.

Référencé par decNumberNextToward().

03448                                                     {
03449   uByte sign;                           // rhs sign
03450   #if DECCHECK
03451   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03452   #endif
03453   sign=rhs->bits & DECNEG;              // save sign bit
03454   decNumberCopy(res, lhs);
03455   res->bits&=~DECNEG;                   // clear the sign
03456   res->bits|=sign;                      // set from rhs
03457   return res;
03458   } // decNumberCopySign

decNumber* decNumberDivide | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1010 du fichier decNumber.c.

Références decDivideOp(), decStatus(), DIVIDE, et uInt.

Référencé par DecFloat_::operator/=().

01011                                                                    {
01012   uInt status=0;                        // accumulator
01013   decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
01014   if (status!=0) decStatus(res, status, set);
01015   #if DECCHECK
01016   decCheckInexact(res, set);
01017   #endif
01018   return res;
01019   } // decNumberDivide

decNumber* decNumberDivideInteger | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1033 du fichier decNumber.c.

Références decDivideOp(), decStatus(), DIVIDEINT, et uInt.

Référencé par DivideInteger().

01034                                                                           {
01035   uInt status=0;                        // accumulator
01036   decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
01037   if (status!=0) decStatus(res, status, set);
01038   return res;
01039   } // decNumberDivideInteger

decNumber* decNumberExp | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1066 du fichier decNumber.c.

Références decCheckMath(), decExpOp(), decStatus(), decNumber::digits, decContext::digits, et uInt.

01067                                           {
01068   uInt status=0;                        // accumulator
01069   #if DECSUBSET
01070   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01071   #endif
01072
01073   #if DECCHECK
01074   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01075   #endif
01076
01077   // Check restrictions; these restrictions ensure that if h=8 (see
01078   // decExpOp) then the result will either overflow or underflow to 0.
01079   // Other math functions restrict the input range, too, for inverses.
01080   // If not violated then carry out the operation.
01081   if (!decCheckMath(rhs, set, &status)) do { // protect allocation
01082     #if DECSUBSET
01083     if (!set->extended) {
01084       // reduce operand and set lostDigits status, as needed
01085       if (rhs->digits>set->digits) {
01086         allocrhs=decRoundOperand(rhs, set, &status);
01087         if (allocrhs==NULL) break;
01088         rhs=allocrhs;
01089         }
01090       }
01091     #endif
01092     decExpOp(res, rhs, set, &status);
01093     } while(0);                         // end protected
01094
01095   #if DECSUBSET
01096   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
01097   #endif
01098   // apply significant status
01099   if (status!=0) decStatus(res, status, set);
01100   #if DECCHECK
01101   decCheckInexact(res, set);
01102   #endif
01103   return res;
01104   } // decNumberExp

decNumber* decNumberFMA | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | const decNumber * | fhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1122 du fichier decNumber.c.

Références D2N, D2U, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_EMAX, DEC_MIN_EMIN, DEC_sNaN, decAddOp(), DECBUFFER, decCheckMath(), decMultiplyOp(), DECNAN, decNumberIsSpecial, decNumberZero(), decStatus(), decContext::digits, decNumber::digits, decContext::emax, decContext::emin, et uInt.

01124                                           {
01125   uInt status=0;                   // accumulator
01126   decContext dcmul;                // context for the multiplication
01127   uInt needbytes;                  // for space calculations
01128   decNumber bufa[D2N(DECBUFFER*2+1)];
01129   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
01130   decNumber *acc;                  // accumulator pointer
01131   decNumber dzero;                 // work
01132
01133   #if DECCHECK
01134   if (decCheckOperands(res, lhs, rhs, set)) return res;
01135   if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;
01136   #endif
01137
01138   do {                                  // protect allocated storage
01139     #if DECSUBSET
01140     if (!set->extended) {               // [undefined if subset]
01141       status|=DEC_Invalid_operation;
01142       break;}
01143     #endif
01144     // Check math restrictions [these ensure no overflow or underflow]
01145     if ((!decNumberIsSpecial(lhs) && decCheckMath(lhs, set, &status))
01146      || (!decNumberIsSpecial(rhs) && decCheckMath(rhs, set, &status))
01147      || (!decNumberIsSpecial(fhs) && decCheckMath(fhs, set, &status))) break;
01148     // set up context for multiply
01149     dcmul=*set;
01150     dcmul.digits=lhs->digits+rhs->digits; // just enough
01151     // [The above may be an over-estimate for subset arithmetic, but that's OK]
01152     dcmul.emax=DEC_MAX_EMAX;            // effectively unbounded ..
01153     dcmul.emin=DEC_MIN_EMIN;            // [thanks to Math restrictions]
01154     // set up decNumber space to receive the result of the multiply
01155     acc=bufa;                           // may fit
01156     needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit);
01157     if (needbytes>sizeof(bufa)) {       // need malloc space
01158       allocbufa=(decNumber *)malloc(needbytes);
01159       if (allocbufa==NULL) {            // hopeless -- abandon
01160         status|=DEC_Insufficient_storage;
01161         break;}
01162       acc=allocbufa;                    // use the allocated space
01163       }
01164     // multiply with extended range and necessary precision
01165     //printf("emin=%ld\n", dcmul.emin);
01166     decMultiplyOp(acc, lhs, rhs, &dcmul, &status);
01167     // Only Invalid operation (from sNaN or Inf * 0) is possible in
01168     // status; if either is seen than ignore fhs (in case it is
01169     // another sNaN) and set acc to NaN unless we had an sNaN
01170     // [decMultiplyOp leaves that to caller]
01171     // Note sNaN has to go through addOp to shorten payload if
01172     // necessary
01173     if ((status&DEC_Invalid_operation)!=0) {
01174       if (!(status&DEC_sNaN)) {         // but be true invalid
01175         decNumberZero(res);             // acc not yet set
01176         res->bits=DECNAN;
01177         break;
01178         }
01179       decNumberZero(&dzero);            // make 0 (any non-NaN would do)
01180       fhs=&dzero;                       // use that
01181       }
01182     #if DECCHECK
01183      else { // multiply was OK
01184       if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
01185       }
01186     #endif
01187     // add the third operand and result -> res, and all is done
01188     decAddOp(res, acc, fhs, set, 0, &status);
01189     } while(0);                         // end protected
01190
01191   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
01192   if (status!=0) decStatus(res, status, set);
01193   #if DECCHECK
01194   decCheckInexact(res, set);
01195   #endif
01196   return res;
01197   } // decNumberFMA

decNumber* decNumberFromInt32 | ( | decNumber * | dn,
 |  | Int | in
 | ) |  |

Définition à la ligne 336 du fichier decNumber.c.

Références BADINT, decNumber::bits, DECNEG, decNumberFromUInt32(), et uInt.

Référencé par decLnOp(), decNumberLog10(), et decNumberLogB().

00336                                                       {
00337   uInt unsig;
00338   if (in>=0) unsig=in;
00339    else {                               // negative (possibly BADINT)
00340     if (in==BADINT) unsig=(uInt)1073741824*2; // special case
00341      else unsig=-in;                    // invert
00342     }
00343   // in is now positive
00344   decNumberFromUInt32(dn, unsig);
00345   if (in<0) dn->bits=DECNEG;            // sign needed
00346   return dn;
00347   } // decNumberFromInt32

decNumber* decNumberFromString | ( | decNumber * | dn,
 |  | const char | chars[],
 |  | decContext * | set
 | ) |  |

Définition à la ligne 480 du fichier decNumber.c.

Références _EnFr_, decContext::clamp, DEC_Conversion_syntax, DEC_English, DEC_French, decBiStr(), DECBUFFER, DECINF, DECNAN, DECNEG, decNumberZero(), DECNUMMAXE, DECSNAN, decContext::digits, Flag, Int, SD2U, uByte, uInt, Unit, et X10.

Référencé par DecFloat_::DecFloat_(), decLnOp(), DecFloat_::operator=(), operator>>(), et DecFloat_::ToChar().

00481                                                  {
00482   Int   exponent=0;                // working exponent [assume 0]
00483   uByte bits=0;                    // working flags [assume +ve]
00484   Unit  *res;                      // where result will be built
00485   Unit  resbuff[SD2U(DECBUFFER+9)];// local buffer in case need temporary
00486                                    // [+9 allows for ln() constants]
00487   Unit  *allocres=NULL;            // -> allocated result, iff allocated
00488   Int   d=0;                       // count of digits found in decimal part
00489   const char *dotchar=NULL;        // where dot was found
00490   const char *cfirst=chars;        // -> first character of decimal part
00491   const char *last=NULL;           // -> last digit of decimal part
00492   const char *c;                   // work
00493   Unit  *up;                       // ..
00494   #if DECDPUN>1
00495   Int   cut, out;                  // ..
00496   #endif
00497   Int   residue;                   // rounding residue
00498   uInt  status=0;                  // error code
00499
00500   #if DECCHECK
00501   if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
00502     return decNumberZero(dn);
00503   #endif
00504
00505   do {                             // status & malloc protection
00506     for (c=chars;; c++) {          // -> input character
00507       if (*c>='0' && *c<='9') {    // test for Arabic digit
00508         last=c;
00509         d++;                       // count of real digits
00510         continue;                  // still in decimal part
00511         }
00512  // JPL french ------------------------------------------------------------
00513
00514  switch (_EnFr_){
00515
00516  case  DEC_English :    if (*c=='.' && dotchar==NULL) { // first '.'
00517         dotchar=c;                 // record offset into decimal part
00518         if (c==cfirst) cfirst++;   // first digit must follow
00519         continue;} break ;
00520  case   DEC_French :    if (*c==',' && dotchar==NULL) { // first ','
00521         dotchar=c;                 // record offset into decimal part
00522         if (c==cfirst) cfirst++;   // first digit must follow
00523         continue;} break ;
00524 // JPL french ------------------------------------------------------------
00525  }
00526
00527       if (c==chars) {              // first in string...
00528         if (*c=='-') {             // valid - sign
00529           cfirst++;
00530           bits=DECNEG;
00531           continue;}
00532         if (*c=='+') {             // valid + sign
00533           cfirst++;
00534           continue;}
00535         }
00536       // *c is not a digit, or a valid +, -, or '.'
00537       break;
00538       } // c
00539
00540     if (last==NULL) {              // no digits yet
00541       status=DEC_Conversion_syntax;// assume the worst
00542       if (*c=='\0') break;         // and no more to come...
00543       #if DECSUBSET
00544       // if subset then infinities and NaNs are not allowed
00545       if (!set->extended) break;   // hopeless
00546       #endif
00547       // Infinities and NaNs are possible, here
00548       if (dotchar!=NULL) break;    // .. unless had a dot
00549       decNumberZero(dn);           // be optimistic
00550       if (decBiStr(c, "infinity", "INFINITY")
00551        || decBiStr(c, "inf", "INF")) {
00552         dn->bits=bits | DECINF;
00553         status=0;                  // is OK
00554         break; // all done
00555         }
00556       // a NaN expected
00557       // 2003.09.10 NaNs are now permitted to have a sign
00558       dn->bits=bits | DECNAN;      // assume simple NaN
00559       if (*c=='s' || *c=='S') {    // looks like an sNaN
00560         c++;
00561         dn->bits=bits | DECSNAN;
00562         }
00563       if (*c!='n' && *c!='N') break;    // check caseless "NaN"
00564       c++;
00565       if (*c!='a' && *c!='A') break;    // ..
00566       c++;
00567       if (*c!='n' && *c!='N') break;    // ..
00568       c++;
00569       // now either nothing, or nnnn payload, expected
00570       // -> start of integer and skip leading 0s [including plain 0]
00571       for (cfirst=c; *cfirst=='0';) cfirst++;
00572       if (*cfirst=='\0') {         // "NaN" or "sNaN", maybe with all 0s
00573         status=0;                  // it's good
00574         break;                     // ..
00575         }
00576       // something other than 0s; setup last and d as usual [no dots]
00577       for (c=cfirst;; c++, d++) {
00578         if (*c<'0' || *c>'9') break; // test for Arabic digit
00579         last=c;
00580         }
00581       if (*c!='\0') break;         // not all digits
00582       if (d>set->digits-1) {
00583         // [NB: payload in a decNumber can be full length unless
00584         // clamped, in which case can only be digits-1]
00585         if (set->clamp) break;
00586         if (d>set->digits) break;
00587         } // too many digits?
00588       // good; drop through to convert the integer to coefficient
00589       status=0;                    // syntax is OK
00590       bits=dn->bits;               // for copy-back
00591       } // last==NULL
00592
00593      else if (*c!='\0') {          // more to process...
00594       // had some digits; exponent is only valid sequence now
00595       Flag nege;                   // 1=negative exponent
00596       const char *firstexp;        // -> first significant exponent digit
00597       status=DEC_Conversion_syntax;// assume the worst
00598       if (*c!='e' && *c!='E') break;
00599       /* Found 'e' or 'E' -- now process explicit exponent */
00600       // 1998.07.11: sign no longer required
00601       nege=0;
00602       c++;                         // to (possible) sign
00603
00604       if (*c=='-') {nege=1; c++;}
00605           else if (*c=='+') c++;
00606       if (*c=='\0') break;
00607
00608
00609       for (; *c=='0' && *(c+1)!='\0';) c++;  // strip insignificant zeros
00610       firstexp=c;                            // save exponent digit place
00611       for (; ;c++) {
00612         if (*c<'0' || *c>'9') break;         // not a digit
00613         exponent=X10(exponent)+(Int)*c-(Int)'0';
00614         } // c
00615       // if not now on a '\0', *c must not be a digit
00616       if (*c!='\0') break;
00617
00618       // (this next test must be after the syntax checks)
00619       // if it was too long the exponent may have wrapped, so check
00620       // carefully and set it to a certain overflow if wrap possible
00621       if (c>=firstexp+9+1) {
00622         if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2;
00623         // [up to 1999999999 is OK, for example 1E-1000000998]
00624         }
00625       if (nege) exponent=-exponent;     // was negative
00626       status=0;                         // is OK
00627       } // stuff after digits
00628
00629     // Here when whole string has been inspected; syntax is good
00630     // cfirst->first digit (never dot), last->last digit (ditto)
00631
00632     // strip leading zeros/dot [leave final 0 if all 0's]
00633     if (*cfirst=='0') {                 // [cfirst has stepped over .]
00634       for (c=cfirst; c<last; c++, cfirst++) {
00635 // JPL-------------------------------------------------------------------
00636         if (*c=='.' && _EnFr_ == DEC_English) continue;          // ignore dots
00637         if (*c==',' && _EnFr_ == DEC_French) continue;          // ignore dots
00638 // JPL-------------------------------------------------------------------
00639         if (*c!='0') break;             // non-zero found
00640         d--;                            // 0 stripped
00641         } // c
00642       #if DECSUBSET
00643       // make a rapid exit for easy zeros if !extended
00644       if (*cfirst=='0' && !set->extended) {
00645         decNumberZero(dn);              // clean result
00646         break;                          // [could be return]
00647         }
00648       #endif
00649       } // at least one leading 0
00650
00651     // Handle decimal point...
00652     if (dotchar!=NULL && dotchar<last)  // non-trailing '.' found?
00653       exponent-=(last-dotchar);         // adjust exponent
00654     // [we can now ignore the .]
00655
00656     // OK, the digits string is good.  Assemble in the decNumber, or in
00657     // a temporary units array if rounding is needed
00658     if (d<=set->digits) res=dn->lsu;    // fits into supplied decNumber
00659      else {                             // rounding needed
00660       Int needbytes=D2U(d)*sizeof(Unit);// bytes needed
00661       res=resbuff;                      // assume use local buffer
00662       if (needbytes>(Int)sizeof(resbuff)) { // too big for local
00663         allocres=(Unit *)malloc(needbytes);
00664         if (allocres==NULL) {status|=DEC_Insufficient_storage; break;}
00665         res=allocres;
00666         }
00667       }
00668     // res now -> number lsu, buffer, or allocated storage for Unit array
00669
00670     // Place the coefficient into the selected Unit array
00671     // [this is often 70% of the cost of this function when DECDPUN>1]
00672     #if DECDPUN>1
00673     out=0;                         // accumulator
00674     up=res+D2U(d)-1;               // -> msu
00675     cut=d-(up-res)*DECDPUN;        // digits in top unit
00676     for (c=cfirst;; c++) {         // along the digits
00677 // JPL ----------------------------------------------------------------------------
00678       if (*c=='.' && _EnFr_ ==DEC_English ) continue;       // ignore '.' [don't decrement cut]
00679       if (*c==',' && _EnFr_ ==DEC_French ) continue;       // ignore ',' [don't decrement cut]
00680 // JPL ----------------------------------------------------------------------------
00681       out=X10(out)+(Int)*c-(Int)'0';
00682       if (c==last) break;          // done [never get to trailing '.']
00683       cut--;
00684       if (cut>0) continue;         // more for this unit
00685       *up=(Unit)out;               // write unit
00686       up--;                        // prepare for unit below..
00687       cut=DECDPUN;                 // ..
00688       out=0;                       // ..
00689       } // c
00690     *up=(Unit)out;                 // write lsu
00691
00692     #else
00693     // DECDPUN==1
00694     up=res;                        // -> lsu
00695     for (c=last; c>=cfirst; c--) { // over each character, from least
00696   switch (_EnFr_){
00697
00698  case  DEC_English :
00699       if (*c=='.') continue; break;      // ignore . [don't step up]
00700
00701 // JPL french ------------------------------------------------------------
00702  case  DEC_French :
00703            if (*c==',') continue;  break     // ignore . [don't step up]
00704 // JPL french ------------------------------------------------------------
00705   }
00706       *up=(Unit)((Int)*c-(Int)'0');
00707       up++;
00708       } // c
00709     #endif
00710
00711     dn->bits=bits;
00712     dn->exponent=exponent;
00713     dn->digits=d;
00714
00715     // if not in number (too long) shorten into the number
00716     if (d>set->digits) {
00717       residue=0;
00718       decSetCoeff(dn, set, res, d, &residue, &status);
00719       // always check for overflow or subnormal and round as needed
00720       decFinalize(dn, set, &residue, &status);
00721       }
00722      else { // no rounding, but may still have overflow or subnormal
00723       // [these tests are just for performance; finalize repeats them]
00724       if ((dn->exponent-1<set->emin-dn->digits)
00725        || (dn->exponent-1>set->emax-set->digits)) {
00726         residue=0;
00727         decFinalize(dn, set, &residue, &status);
00728         }
00729       }
00730     // decNumberShow(dn);
00731     } while(0);                         // [for break]
00732
00733   if (allocres!=NULL) free(allocres);   // drop any storage used
00734   if (status!=0) decStatus(dn, status, set);
00735   return dn;
00736   } /* decNumberFromString */

decNumber* decNumberFromUInt32 | ( | decNumber * | dn,
 |  | uInt | uin
 | ) |  |

Définition à la ligne 349 du fichier decNumber.c.

Références decGetDigits(), decNumberZero(), decNumber::digits, decNumber::lsu, et Unit.

Référencé par decNumberFromInt32().

00349                                                          {
00350   Unit *up;                             // work pointer
00351   decNumberZero(dn);                    // clean
00352   if (uin==0) return dn;                // [or decGetDigits bad call]
00353   for (up=dn->lsu; uin>0; up++) {
00354     *up=(Unit)(uin%(DECDPUNMAX+1));
00355     uin=uin/(DECDPUNMAX+1);
00356     }
00357   dn->digits=decGetDigits(dn->lsu, up-dn->lsu);
00358   return dn;
00359   } // decNumberFromUInt32

uByte* decNumberGetBCD | ( | const decNumber * | dn,
 |  | uByte * | bcd
 | ) |  |

Définition à la ligne 3470 du fichier decNumber.c.

Références DECDPUN, decNumber::digits, decNumber::lsu, uByte, et uInt.

03470                                                          {
03471   uByte *ub=bcd+dn->digits-1;      // -> lsd
03472   const Unit *up=dn->lsu;          // Unit pointer, -> lsu
03473
03474   #if DECDPUN==1                   // trivial simple copy
03475     for (; ub>=bcd; ub--, up++) *ub=*up;
03476   #else                            // chopping needed
03477     uInt u=*up;                    // work
03478     uInt cut=DECDPUN;              // downcounter through unit
03479     for (; ub>=bcd; ub--) {
03480       *ub=(uByte)(u%10);           // [*6554 trick inhibits, here]
03481       u=u/10;
03482       cut--;
03483       if (cut>0) continue;         // more in this unit
03484       up++;
03485       u=*up;
03486       cut=DECDPUN;
03487       }
03488   #endif
03489   return bcd;
03490   } // decNumberGetBCD

decNumber* decNumberInvert | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1213 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

01214                                              {
01215   const Unit *ua, *msua;                // -> operand and its msu
01216   Unit  *uc, *msuc;                     // -> result and its msu
01217   Int   msudigs;                        // digits in res msu
01218   #if DECCHECK
01219   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01220   #endif
01221
01222   if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
01223     decStatus(res, DEC_Invalid_operation, set);
01224     return res;
01225     }
01226   // operand is valid
01227   ua=rhs->lsu;                          // bottom-up
01228   uc=res->lsu;                          // ..
01229   msua=ua+D2U(rhs->digits)-1;           // -> msu of rhs
01230   msuc=uc+D2U(set->digits)-1;           // -> msu of result
01231   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
01232   for (; uc<=msuc; ua++, uc++) {        // Unit loop
01233     Unit a;                             // extract unit
01234     Int  i, j;                          // work
01235     if (ua>msua) a=0;
01236      else a=*ua;
01237     *uc=0;                              // can now write back
01238     // always need to examine all bits in rhs
01239     // This loop could be unrolled and/or use BIN2BCD tables
01240     for (i=0; i<DECDPUN; i++) {
01241       if ((~a)&1) *uc=*uc+(Unit)powers[i];   // effect INVERT
01242       j=a%10;
01243       a=a/10;
01244       if (j>1) {
01245         decStatus(res, DEC_Invalid_operation, set);
01246         return res;
01247         }
01248       if (uc==msuc && i==msudigs-1) break;   // just did final digit
01249       } // each digit
01250     } // each unit
01251   // [here uc-1 is the msu of the result]
01252   res->digits=decGetDigits(res->lsu, uc-res->lsu);
01253   res->exponent=0;                      // integer
01254   res->bits=0;                          // sign=0
01255   return res;  // [no status to set]
01256   } // decNumberInvert

Int decNumberIsNormal | ( | const decNumber * | dn,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 3529 du fichier decNumber.c.

Références decNumberIsSpecial, decNumberIsZero, decNumber::digits, decNumber::exponent, et Int.

Référencé par decNumberClass(), et decNumberNextToward().

03529                                                             {
03530   Int ae;                               // adjusted exponent
03531   #if DECCHECK
03532   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
03533   #endif
03534
03535   if (decNumberIsSpecial(dn)) return 0; // not finite
03536   if (decNumberIsZero(dn)) return 0;    // not non-zero
03537
03538   ae=dn->exponent+dn->digits-1;         // adjusted exponent
03539   if (ae<set->emin) return 0;           // is subnormal
03540   return 1;
03541   } // decNumberIsNormal

Int decNumberIsSubnormal | ( | const decNumber * | dn,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 3549 du fichier decNumber.c.

Références decNumberIsSpecial, decNumberIsZero, decNumber::digits, decNumber::exponent, et Int.

03549                                                                {
03550   Int ae;                               // adjusted exponent
03551   #if DECCHECK
03552   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
03553   #endif
03554
03555   if (decNumberIsSpecial(dn)) return 0; // not finite
03556   if (decNumberIsZero(dn)) return 0;    // not non-zero
03557
03558   ae=dn->exponent+dn->digits-1;         // adjusted exponent
03559   if (ae<set->emin) return 1;           // is subnormal
03560   return 0;
03561   } // decNumberIsSubnormal

decNumber* decNumberLn | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1286 du fichier decNumber.c.

Références DEC_Invalid_operation, decCheckMath(), decLnOp(), decStatus(), decNumber::digits, decContext::digits, ISZERO, et uInt.

01287                                          {
01288   uInt status=0;                   // accumulator
01289   #if DECSUBSET
01290   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01291   #endif
01292
01293   #if DECCHECK
01294   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01295   #endif
01296
01297   // Check restrictions; this is a math function; if not violated
01298   // then carry out the operation.
01299   if (!decCheckMath(rhs, set, &status)) do { // protect allocation
01300     #if DECSUBSET
01301     if (!set->extended) {
01302       // reduce operand and set lostDigits status, as needed
01303       if (rhs->digits>set->digits) {
01304         allocrhs=decRoundOperand(rhs, set, &status);
01305         if (allocrhs==NULL) break;
01306         rhs=allocrhs;
01307         }
01308       // special check in subset for rhs=0
01309       if (ISZERO(rhs)) {                // +/- zeros -> error
01310         status|=DEC_Invalid_operation;
01311         break;}
01312       } // extended=0
01313     #endif
01314     decLnOp(res, rhs, set, &status);
01315     } while(0);                         // end protected
01316
01317   #if DECSUBSET
01318   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
01319   #endif
01320   // apply significant status
01321   if (status!=0) decStatus(res, status, set);
01322   #if DECCHECK
01323   decCheckInexact(res, set);
01324   #endif
01325   return res;
01326   } // decNumberLn

decNumber* decNumberLog10 | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1408 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_MATH, DEC_NaNs, DEC_sNaN, DECBUFFER, decCheckMath(), decContextDefault(), decCopyFit(), decDivideOp(), decFinish, decLnOp(), DECNEG, decNumberCopy(), decNumberFromInt32(), decNumberZero(), DECSPECIAL, decStatus(), decNumber::digits, decContext::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, et uInt.

01409                                            {
01410   uInt status=0, ignore=0;         // status accumulators
01411   uInt needbytes;                  // for space calculations
01412   Int p;                           // working precision
01413   Int t;                           // digits in exponent of A
01414
01415   // buffers for a and b working decimals
01416   // (adjustment calculator, same size)
01417   decNumber bufa[D2N(DECBUFFER+2)];
01418   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
01419   decNumber *a=bufa;               // temporary a
01420   decNumber bufb[D2N(DECBUFFER+2)];
01421   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
01422   decNumber *b=bufb;               // temporary b
01423   decNumber bufw[D2N(10)];         // working 2-10 digit number
01424   decNumber *w=bufw;               // ..
01425   #if DECSUBSET
01426   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01427   #endif
01428
01429   decContext aset;                 // working context
01430
01431   #if DECCHECK
01432   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01433   #endif
01434
01435   // Check restrictions; this is a math function; if not violated
01436   // then carry out the operation.
01437   if (!decCheckMath(rhs, set, &status)) do { // protect malloc
01438     #if DECSUBSET
01439     if (!set->extended) {
01440       // reduce operand and set lostDigits status, as needed
01441       if (rhs->digits>set->digits) {
01442         allocrhs=decRoundOperand(rhs, set, &status);
01443         if (allocrhs==NULL) break;
01444         rhs=allocrhs;
01445         }
01446       // special check in subset for rhs=0
01447       if (ISZERO(rhs)) {                // +/- zeros -> error
01448         status|=DEC_Invalid_operation;
01449         break;}
01450       } // extended=0
01451     #endif
01452
01453     decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
01454
01455     // handle exact powers of 10; only check if +ve finite
01456     if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {
01457       Int residue=0;               // (no residue)
01458       uInt copystat=0;             // clean status
01459
01460       // round to a single digit...
01461       aset.digits=1;
01462       decCopyFit(w, rhs, &aset, &residue, &copystat); // copy & shorten
01463       // if exact and the digit is 1, rhs is a power of 10
01464       if (!(copystat&DEC_Inexact) && w->lsu[0]==1) {
01465         // the exponent, conveniently, is the power of 10; making
01466         // this the result needs a little care as it might not fit,
01467         // so first convert it into the working number, and then move
01468         // to res
01469         decNumberFromInt32(w, w->exponent);
01470         residue=0;
01471         decCopyFit(res, w, set, &residue, &status); // copy & round
01472         decFinish(res, set, &residue, &status);     // cleanup/set flags
01473         break;
01474         } // not a power of 10
01475       } // not a candidate for exact
01476
01477     // simplify the information-content calculation to use 'total
01478     // number of digits in a, including exponent' as compared to the
01479     // requested digits, as increasing this will only rarely cost an
01480     // iteration in ln(a) anyway
01481     t=6;                                // it can never be >6
01482
01483     // allocate space when needed...
01484     p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
01485     needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
01486     if (needbytes>sizeof(bufa)) {       // need malloc space
01487       allocbufa=(decNumber *)malloc(needbytes);
01488       if (allocbufa==NULL) {            // hopeless -- abandon
01489         status|=DEC_Insufficient_storage;
01490         break;}
01491       a=allocbufa;                      // use the allocated space
01492       }
01493     aset.digits=p;                      // as calculated
01494     aset.emax=DEC_MAX_MATH;             // usual bounds
01495     aset.emin=-DEC_MAX_MATH;            // ..
01496     aset.clamp=0;                       // and no concrete format
01497     decLnOp(a, rhs, &aset, &status);    // a=ln(rhs)
01498
01499     // skip the division if the result so far is infinite, NaN, or
01500     // zero, or there was an error; note NaN from sNaN needs copy
01501     if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
01502     if (a->bits&DECSPECIAL || ISZERO(a)) {
01503       decNumberCopy(res, a);            // [will fit]
01504       break;}
01505
01506     // for ln(10) an extra 3 digits of precision are needed
01507     p=set->digits+3;
01508     needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
01509     if (needbytes>sizeof(bufb)) {       // need malloc space
01510       allocbufb=(decNumber *)malloc(needbytes);
01511       if (allocbufb==NULL) {            // hopeless -- abandon
01512         status|=DEC_Insufficient_storage;
01513         break;}
01514       b=allocbufb;                      // use the allocated space
01515       }
01516     decNumberZero(w);                   // set up 10...
01517     #if DECDPUN==1
01518     w->lsu[1]=1; w->lsu[0]=0;           // ..
01519     #else
01520     w->lsu[0]=10;                       // ..
01521     #endif
01522     w->digits=2;                        // ..
01523
01524     aset.digits=p;
01525     decLnOp(b, w, &aset, &ignore);      // b=ln(10)
01526
01527     aset.digits=set->digits;            // for final divide
01528     decDivideOp(res, a, b, &aset, DIVIDE, &status); // into result
01529     } while(0);                         // [for break]
01530
01531   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
01532   if (allocbufb!=NULL) free(allocbufb); // ..
01533   #if DECSUBSET
01534   if (allocrhs !=NULL) free(allocrhs);  // ..
01535   #endif
01536   // apply significant status
01537   if (status!=0) decStatus(res, status, set);
01538   #if DECCHECK
01539   decCheckInexact(res, set);
01540   #endif
01541   return res;
01542   } // decNumberLog10

decNumber* decNumberLogB | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1352 du fichier decNumber.c.

Références DEC_Division_by_zero, DECINF, decNaNs(), DECNEG, decNumberCopyAbs(), decNumberFromInt32(), decNumberIsInfinite, decNumberIsNaN, decNumberIsZero, decNumberZero(), decStatus(), decNumber::digits, decNumber::exponent, Int, et uInt.

01353                                            {
01354   uInt status=0;                   // accumulator
01355
01356   #if DECCHECK
01357   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01358   #endif
01359
01360   // NaNs as usual; Infinities return +Infinity; 0->oops
01361   if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);
01362    else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs);
01363    else if (decNumberIsZero(rhs)) {
01364     decNumberZero(res);                 // prepare for Infinity
01365     res->bits=DECNEG|DECINF;            // -Infinity
01366     status|=DEC_Division_by_zero;       // as per 754
01367     }
01368    else { // finite non-zero
01369     Int ae=rhs->exponent+rhs->digits-1; // adjusted exponent
01370     decNumberFromInt32(res, ae);        // lay it out
01371     }
01372
01373   if (status!=0) decStatus(res, status, set);
01374   return res;
01375   } // decNumberLogB

decNumber* decNumberMax | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1556 du fichier decNumber.c.

Références COMPMAX, decCompareOp(), decStatus(), et uInt.

Référencé par max().

01557                                                                 {
01558   uInt status=0;                        // accumulator
01559   decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
01560   if (status!=0) decStatus(res, status, set);
01561   #if DECCHECK
01562   decCheckInexact(res, set);
01563   #endif
01564   return res;
01565   } // decNumberMax

decNumber* decNumberMaxMag | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1579 du fichier decNumber.c.

Références COMPMAXMAG, decCompareOp(), decStatus(), et uInt.

01580                                                                 {
01581   uInt status=0;                        // accumulator
01582   decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
01583   if (status!=0) decStatus(res, status, set);
01584   #if DECCHECK
01585   decCheckInexact(res, set);
01586   #endif
01587   return res;
01588   } // decNumberMaxMag

decNumber* decNumberMin | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1602 du fichier decNumber.c.

Références COMPMIN, decCompareOp(), decStatus(), et uInt.

Référencé par min().

01603                                                                 {
01604   uInt status=0;                        // accumulator
01605   decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
01606   if (status!=0) decStatus(res, status, set);
01607   #if DECCHECK
01608   decCheckInexact(res, set);
01609   #endif
01610   return res;
01611   } // decNumberMin

decNumber* decNumberMinMag | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1625 du fichier decNumber.c.

Références COMPMINMAG, decCompareOp(), decStatus(), et uInt.

01626                                                                 {
01627   uInt status=0;                        // accumulator
01628   decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
01629   if (status!=0) decStatus(res, status, set);
01630   #if DECCHECK
01631   decCheckInexact(res, set);
01632   #endif
01633   return res;
01634   } // decNumberMinMag

decNumber* decNumberMinus | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1650 du fichier decNumber.c.

Références decAddOp(), DECNEG, decNumberZero(), decStatus(), decNumber::exponent, et uInt.

Référencé par DecFloat_::operator-().

01651                                             {
01652   decNumber dzero;
01653   uInt status=0;                        // accumulator
01654
01655   #if DECCHECK
01656   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01657   #endif
01658
01659   decNumberZero(&dzero);                // make 0
01660   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
01661   decAddOp(res, &dzero, rhs, set, DECNEG, &status);
01662   if (status!=0) decStatus(res, status, set);
01663   #if DECCHECK
01664   decCheckInexact(res, set);
01665   #endif
01666   return res;
01667   } // decNumberMinus

decNumber* decNumberMultiply | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1924 du fichier decNumber.c.

Références decMultiplyOp(), decStatus(), et uInt.

Référencé par DecFloat_::operator *=().

01925                                                                      {
01926   uInt status=0;                   // accumulator
01927   decMultiplyOp(res, lhs, rhs, set, &status);
01928   if (status!=0) decStatus(res, status, set);
01929   #if DECCHECK
01930   decCheckInexact(res, set);
01931   #endif
01932   return res;
01933   } // decNumberMultiply

decNumber* decNumberNextMinus | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1680 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, DEC_MIN_EMIN, DEC_ROUND_FLOOR, DEC_sNaN, decAddOp(), DECINF, DECNEG, decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, decNumber::lsu, decContext::round, et uInt.

01681                                                 {
01682   decNumber dtiny;                           // constant
01683   decContext workset=*set;                   // work
01684   uInt status=0;                             // accumulator
01685   #if DECCHECK
01686   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01687   #endif
01688
01689   // +Infinity is the special case
01690   if ((rhs->bits&(DECINF|DECNEG))==DECINF) {
01691     decSetMaxValue(res, set);                // is +ve
01692     // there is no status to set
01693     return res;
01694     }
01695   decNumberZero(&dtiny);                     // start with 0
01696   dtiny.lsu[0]=1;                            // make number that is ..
01697   dtiny.exponent=DEC_MIN_EMIN-1;             // .. smaller than tiniest
01698   workset.round=DEC_ROUND_FLOOR;
01699   decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
01700   status&=DEC_Invalid_operation|DEC_sNaN;    // only sNaN Invalid please
01701   if (status!=0) decStatus(res, status, set);
01702   return res;
01703   } // decNumberNextMinus

decNumber* decNumberNextPlus | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1716 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, DEC_MIN_EMIN, DEC_ROUND_CEILING, DEC_sNaN, decAddOp(), DECINF, DECNEG, decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, decNumber::lsu, decContext::round, et uInt.

01717                                                {
01718   decNumber dtiny;                           // constant
01719   decContext workset=*set;                   // work
01720   uInt status=0;                             // accumulator
01721   #if DECCHECK
01722   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01723   #endif
01724
01725   // -Infinity is the special case
01726   if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
01727     decSetMaxValue(res, set);
01728     res->bits=DECNEG;                        // negative
01729     // there is no status to set
01730     return res;
01731     }
01732   decNumberZero(&dtiny);                     // start with 0
01733   dtiny.lsu[0]=1;                            // make number that is ..
01734   dtiny.exponent=DEC_MIN_EMIN-1;             // .. smaller than tiniest
01735   workset.round=DEC_ROUND_CEILING;
01736   decAddOp(res, rhs, &dtiny, &workset, 0, &status);
01737   status&=DEC_Invalid_operation|DEC_sNaN;    // only sNaN Invalid please
01738   if (status!=0) decStatus(res, status, set);
01739   return res;
01740   } // decNumberNextPlus

decNumber* decNumberNextToward | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1756 du fichier decNumber.c.

Références BADINT, decNumber::bits, DEC_Insufficient_storage, DEC_MIN_EMIN, DEC_ROUND_CEILING, DEC_ROUND_FLOOR, decAddOp(), decCompare(), DECINF, decNaNs(), DECNEG, decNumberCopySign(), decNumberIsNaN, decNumberIsNormal(), decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, Int, decNumber::lsu, decContext::round, uByte, et uInt.

01757                                                                        {
01758   decNumber dtiny;                           // constant
01759   decContext workset=*set;                   // work
01760   Int result;                                // ..
01761   uInt status=0;                             // accumulator
01762   #if DECCHECK
01763   if (decCheckOperands(res, lhs, rhs, set)) return res;
01764   #endif
01765
01766   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
01767     decNaNs(res, lhs, rhs, set, &status);
01768     }
01769    else { // Is numeric, so no chance of sNaN Invalid, etc.
01770     result=decCompare(lhs, rhs, 0);     // sign matters
01771     if (result==BADINT) status|=DEC_Insufficient_storage; // rare
01772      else { // valid compare
01773       if (result==0) decNumberCopySign(res, lhs, rhs); // easy
01774        else { // differ: need NextPlus or NextMinus
01775         uByte sub;                      // add or subtract
01776         if (result<0) {                 // lhs<rhs, do nextplus
01777           // -Infinity is the special case
01778           if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
01779             decSetMaxValue(res, set);
01780             res->bits=DECNEG;           // negative
01781             return res;                 // there is no status to set
01782             }
01783           workset.round=DEC_ROUND_CEILING;
01784           sub=0;                        // add, please
01785           } // plus
01786          else {                         // lhs>rhs, do nextminus
01787           // +Infinity is the special case
01788           if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
01789             decSetMaxValue(res, set);
01790             return res;                 // there is no status to set
01791             }
01792           workset.round=DEC_ROUND_FLOOR;
01793           sub=DECNEG;                   // subtract, please
01794           } // minus
01795         decNumberZero(&dtiny);          // start with 0
01796         dtiny.lsu[0]=1;                 // make number that is ..
01797         dtiny.exponent=DEC_MIN_EMIN-1;  // .. smaller than tiniest
01798         decAddOp(res, lhs, &dtiny, &workset, sub, &status); // + or -
01799         // turn off exceptions if the result is a normal number
01800         // (including Nmin), otherwise let all status through
01801         if (decNumberIsNormal(res, set)) status=0;
01802         } // unequal
01803       } // compare OK
01804     } // numeric
01805   if (status!=0) decStatus(res, status, set);
01806   return res;
01807   } // decNumberNextToward

decNumber* decNumberNormalize | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2326 du fichier decNumber.c.

Références decNumberReduce().

Référencé par DecFloat_::Normalize().

02327                                                 {
02328   return decNumberReduce(res, rhs, set);
02329   } // decNumberNormalize

decNumber* decNumberOr | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1824 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

01825                                                                {
01826   const Unit *ua, *ub;                  // -> operands
01827   const Unit *msua, *msub;              // -> operand msus
01828   Unit  *uc, *msuc;                     // -> result and its msu
01829   Int   msudigs;                        // digits in res msu
01830   #if DECCHECK
01831   if (decCheckOperands(res, lhs, rhs, set)) return res;
01832   #endif
01833
01834   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
01835    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
01836     decStatus(res, DEC_Invalid_operation, set);
01837     return res;
01838     }
01839   // operands are valid
01840   ua=lhs->lsu;                          // bottom-up
01841   ub=rhs->lsu;                          // ..
01842   uc=res->lsu;                          // ..
01843   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
01844   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
01845   msuc=uc+D2U(set->digits)-1;           // -> msu of result
01846   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
01847   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
01848     Unit a, b;                          // extract units
01849     if (ua>msua) a=0;
01850      else a=*ua;
01851     if (ub>msub) b=0;
01852      else b=*ub;
01853     *uc=0;                              // can now write back
01854     if (a|b) {                          // maybe 1 bits to examine
01855       Int i, j;
01856       // This loop could be unrolled and/or use BIN2BCD tables
01857       for (i=0; i<DECDPUN; i++) {
01858         if ((a|b)&1) *uc=*uc+(Unit)powers[i];     // effect OR
01859         j=a%10;
01860         a=a/10;
01861         j|=b%10;
01862         b=b/10;
01863         if (j>1) {
01864           decStatus(res, DEC_Invalid_operation, set);
01865           return res;
01866           }
01867         if (uc==msuc && i==msudigs-1) break;      // just did final digit
01868         } // each digit
01869       } // non-zero
01870     } // each unit
01871   // [here uc-1 is the msu of the result]
01872   res->digits=decGetDigits(res->lsu, uc-res->lsu);
01873   res->exponent=0;                      // integer
01874   res->bits=0;                          // sign=0
01875   return res;  // [no status to set]
01876   } // decNumberOr

decNumber* decNumberPlus | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1894 du fichier decNumber.c.

Références decAddOp(), decNumberZero(), decStatus(), decNumber::exponent, et uInt.

Référencé par DecFloat_::operator+().

01895                                            {
01896   decNumber dzero;
01897   uInt status=0;                        // accumulator
01898   #if DECCHECK
01899   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01900   #endif
01901
01902   decNumberZero(&dzero);                // make 0
01903   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
01904   decAddOp(res, &dzero, rhs, set, 0, &status);
01905   if (status!=0) decStatus(res, status, set);
01906   #if DECCHECK
01907   decCheckInexact(res, set);
01908   #endif
01909   return res;
01910   } // decNumberPlus

decNumber* decNumberPower | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 1961 du fichier decNumber.c.

Références BADINT, BIGEVEN, BIGODD, decNumber::bits, decContext::clamp, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_MATH, DEC_Overflow, DEC_ROUND_HALF_EVEN, DEC_Rounded, DEC_Subnormal, DEC_Underflow, DECBUFFER, decCheckMath(), decContextDefault(), decCopyFit(), decDivideOp(), decExpOp(), decFinalize(), decFinish, decGetInt(), DECINF, decLnOp(), decMultiplyOp(), decNaNs(), DECNEG, decNumberCompare(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decNumberIsNegative, decNumberIsZero, decNumberZero(), DECNUMMAXP, decShiftToMost(), decStatus(), decTrim(), decContext::digits, decNumber::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, MAXI, decContext::round, SPECIALARGS, uByte, et uInt.

Référencé par pow().

01962                                                                   {
01963   #if DECSUBSET
01964   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
01965   decNumber *allocrhs=NULL;        // .., rhs
01966   #endif
01967   decNumber *allocdac=NULL;        // -> allocated acc buffer, iff used
01968   decNumber *allocinv=NULL;        // -> allocated 1/x buffer, iff used
01969   Int   reqdigits=set->digits;     // requested DIGITS
01970   Int   n;                         // rhs in binary
01971   Flag  rhsint=0;                  // 1 if rhs is an integer
01972   Flag  useint=0;                  // 1 if can use integer calculation
01973   Flag  isoddint=0;                // 1 if rhs is an integer and odd
01974   Int   i;                         // work
01975   #if DECSUBSET
01976   Int   dropped;                   // ..
01977   #endif
01978   uInt  needbytes;                 // buffer size needed
01979   Flag  seenbit;                   // seen a bit while powering
01980   Int   residue=0;                 // rounding residue
01981   uInt  status=0;                  // accumulators
01982   uByte bits=0;                    // result sign if errors
01983   decContext aset;                 // working context
01984   decNumber dnOne;                 // work value 1...
01985   // local accumulator buffer [a decNumber, with digits+elength+1 digits]
01986   decNumber dacbuff[D2N(DECBUFFER+9)];
01987   decNumber *dac=dacbuff;          // -> result accumulator
01988   // same again for possible 1/lhs calculation
01989   decNumber invbuff[D2N(DECBUFFER+9)];
01990
01991   #if DECCHECK
01992   if (decCheckOperands(res, lhs, rhs, set)) return res;
01993   #endif
01994
01995   do {                             // protect allocated storage
01996     #if DECSUBSET
01997     if (!set->extended) { // reduce operands and set status, as needed
01998       if (lhs->digits>reqdigits) {
01999         alloclhs=decRoundOperand(lhs, set, &status);
02000         if (alloclhs==NULL) break;
02001         lhs=alloclhs;
02002         }
02003       if (rhs->digits>reqdigits) {
02004         allocrhs=decRoundOperand(rhs, set, &status);
02005         if (allocrhs==NULL) break;
02006         rhs=allocrhs;
02007         }
02008       }
02009     #endif
02010     // [following code does not require input rounding]
02011
02012     // handle NaNs and rhs Infinity (lhs infinity is harder)
02013     if (SPECIALARGS) {
02014       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { // NaNs
02015         decNaNs(res, lhs, rhs, set, &status);
02016         break;}
02017       if (decNumberIsInfinite(rhs)) {   // rhs Infinity
02018         Flag rhsneg=rhs->bits&DECNEG;   // save rhs sign
02019         if (decNumberIsNegative(lhs)    // lhs<0
02020          && !decNumberIsZero(lhs))      // ..
02021           status|=DEC_Invalid_operation;
02022          else {                         // lhs >=0
02023           decNumberZero(&dnOne);        // set up 1
02024           dnOne.lsu[0]=1;
02025           decNumberCompare(dac, lhs, &dnOne, set); // lhs ? 1
02026           decNumberZero(res);           // prepare for 0/1/Infinity
02027           if (decNumberIsNegative(dac)) {    // lhs<1
02028             if (rhsneg) res->bits|=DECINF;   // +Infinity [else is +0]
02029             }
02030            else if (dac->lsu[0]==0) {        // lhs=1
02031             // 1**Infinity is inexact, so return fully-padded 1.0000
02032             Int shift=set->digits-1;
02033             *res->lsu=1;                     // was 0, make int 1
02034             res->digits=decShiftToMost(res->lsu, 1, shift);
02035             res->exponent=-shift;            // make 1.0000...
02036             status|=DEC_Inexact|DEC_Rounded; // deemed inexact
02037             }
02038            else {                            // lhs>1
02039             if (!rhsneg) res->bits|=DECINF;  // +Infinity [else is +0]
02040             }
02041           } // lhs>=0
02042         break;}
02043       // [lhs infinity drops through]
02044       } // specials
02045
02046     // Original rhs may be an integer that fits and is in range
02047     n=decGetInt(rhs);
02048     if (n!=BADINT) {                    // it is an integer
02049       rhsint=1;                         // record the fact for 1**n
02050       isoddint=(Flag)n&1;               // [works even if big]
02051       if (n!=BIGEVEN && n!=BIGODD)      // can use integer path?
02052         useint=1;                       // looks good
02053       }
02054
02055     if (decNumberIsNegative(lhs)        // -x ..
02056       && isoddint) bits=DECNEG;         // .. to an odd power
02057
02058     // handle LHS infinity
02059     if (decNumberIsInfinite(lhs)) {     // [NaNs already handled]
02060       uByte rbits=rhs->bits;            // save
02061       decNumberZero(res);               // prepare
02062       if (n==0) *res->lsu=1;            // [-]Inf**0 => 1
02063        else {
02064         // -Inf**nonint -> error
02065         if (!rhsint && decNumberIsNegative(lhs)) {
02066           status|=DEC_Invalid_operation;     // -Inf**nonint is error
02067           break;}
02068         if (!(rbits & DECNEG)) bits|=DECINF; // was not a **-n
02069         // [otherwise will be 0 or -0]
02070         res->bits=bits;
02071         }
02072       break;}
02073
02074     // similarly handle LHS zero
02075     if (decNumberIsZero(lhs)) {
02076       if (n==0) {                            // 0**0 => Error
02077         #if DECSUBSET
02078         if (!set->extended) {                // [unless subset]
02079           decNumberZero(res);
02080           *res->lsu=1;                       // return 1
02081           break;}
02082         #endif
02083         status|=DEC_Invalid_operation;
02084         }
02085        else {                                // 0**x
02086         uByte rbits=rhs->bits;               // save
02087         if (rbits & DECNEG) {                // was a 0**(-n)
02088           #if DECSUBSET
02089           if (!set->extended) {              // [bad if subset]
02090             status|=DEC_Invalid_operation;
02091             break;}
02092           #endif
02093           bits|=DECINF;
02094           }
02095         decNumberZero(res);                  // prepare
02096         // [otherwise will be 0 or -0]
02097         res->bits=bits;
02098         }
02099       break;}
02100
02101     // here both lhs and rhs are finite; rhs==0 is handled in the
02102     // integer path.  Next handle the non-integer cases
02103     if (!useint) {                      // non-integral rhs
02104       // any -ve lhs is bad, as is either operand or context out of
02105       // bounds
02106       if (decNumberIsNegative(lhs)) {
02107         status|=DEC_Invalid_operation;
02108         break;}
02109       if (decCheckMath(lhs, set, &status)
02110        || decCheckMath(rhs, set, &status)) break; // variable status
02111
02112       decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
02113       aset.emax=DEC_MAX_MATH;           // usual bounds
02114       aset.emin=-DEC_MAX_MATH;          // ..
02115       aset.clamp=0;                     // and no concrete format
02116
02117       // calculate the result using exp(ln(lhs)*rhs), which can
02118       // all be done into the accumulator, dac.  The precision needed
02119       // is enough to contain the full information in the lhs (which
02120       // is the total digits, including exponent), or the requested
02121       // precision, if larger, + 4; 6 is used for the exponent
02122       // maximum length, and this is also used when it is shorter
02123       // than the requested digits as it greatly reduces the >0.5 ulp
02124       // cases at little cost (because Ln doubles digits each
02125       // iteration so a few extra digits rarely causes an extra
02126       // iteration)
02127       aset.digits=MAXI(lhs->digits, set->digits)+6+4;
02128       } // non-integer rhs
02129
02130      else { // rhs is in-range integer
02131       if (n==0) {                       // x**0 = 1
02132         // (0**0 was handled above)
02133         decNumberZero(res);             // result=1
02134         *res->lsu=1;                    // ..
02135         break;}
02136       // rhs is a non-zero integer
02137       if (n<0) n=-n;                    // use abs(n)
02138
02139       aset=*set;                        // clone the context
02140       aset.round=DEC_ROUND_HALF_EVEN;   // internally use balanced
02141       // calculate the working DIGITS
02142       aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
02143       #if DECSUBSET
02144       if (!set->extended) aset.digits--;     // use classic precision
02145       #endif
02146       // it's an error if this is more than can be handled
02147       if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}
02148       } // integer path
02149
02150     // aset.digits is the count of digits for the accumulator needed
02151     // if accumulator is too long for local storage, then allocate
02152     needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);
02153     // [needbytes also used below if 1/lhs needed]
02154     if (needbytes>sizeof(dacbuff)) {
02155       allocdac=(decNumber *)malloc(needbytes);
02156       if (allocdac==NULL) {   // hopeless -- abandon
02157         status|=DEC_Insufficient_storage;
02158         break;}
02159       dac=allocdac;           // use the allocated space
02160       }
02161     // here, aset is set up and accumulator is ready for use
02162
02163     if (!useint) {                           // non-integral rhs
02164       // x ** y; special-case x=1 here as it will otherwise always
02165       // reduce to integer 1; decLnOp has a fastpath which detects
02166       // the case of x=1
02167       decLnOp(dac, lhs, &aset, &status);     // dac=ln(lhs)
02168       // [no error possible, as lhs 0 already handled]
02169       if (ISZERO(dac)) {                     // x==1, 1.0, etc.
02170         // need to return fully-padded 1.0000 etc., but rhsint->1
02171         *dac->lsu=1;                         // was 0, make int 1
02172         if (!rhsint) {                       // add padding
02173           Int shift=set->digits-1;
02174           dac->digits=decShiftToMost(dac->lsu, 1, shift);
02175           dac->exponent=-shift;              // make 1.0000...
02176           status|=DEC_Inexact|DEC_Rounded;   // deemed inexact
02177           }
02178         }
02179        else {
02180         decMultiplyOp(dac, dac, rhs, &aset, &status);  // dac=dac*rhs
02181         decExpOp(dac, dac, &aset, &status);            // dac=exp(dac)
02182         }
02183       // and drop through for final rounding
02184       } // non-integer rhs
02185
02186      else {                             // carry on with integer
02187       decNumberZero(dac);               // acc=1
02188       *dac->lsu=1;                      // ..
02189
02190       // if a negative power the constant 1 is needed, and if not subset
02191       // invert the lhs now rather than inverting the result later
02192       if (decNumberIsNegative(rhs)) {   // was a **-n [hence digits>0]
02193         decNumber *inv=invbuff;         // asssume use fixed buffer
02194         decNumberCopy(&dnOne, dac);     // dnOne=1;  [needed now or later]
02195         #if DECSUBSET
02196         if (set->extended) {            // need to calculate 1/lhs
02197         #endif
02198           // divide lhs into 1, putting result in dac [dac=1/dac]
02199           decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);
02200           // now locate or allocate space for the inverted lhs
02201           if (needbytes>sizeof(invbuff)) {
02202             allocinv=(decNumber *)malloc(needbytes);
02203             if (allocinv==NULL) {       // hopeless -- abandon
02204               status|=DEC_Insufficient_storage;
02205               break;}
02206             inv=allocinv;               // use the allocated space
02207             }
02208           // [inv now points to big-enough buffer or allocated storage]
02209           decNumberCopy(inv, dac);      // copy the 1/lhs
02210           decNumberCopy(dac, &dnOne);   // restore acc=1
02211           lhs=inv;                      // .. and go forward with new lhs
02212         #if DECSUBSET
02213           }
02214         #endif
02215         }
02216
02217       // Raise-to-the-power loop...
02218       seenbit=0;                   // set once a 1-bit is encountered
02219       for (i=1;;i++){              // for each bit [top bit ignored]
02220         // abandon if had overflow or terminal underflow
02221         if (status & (DEC_Overflow|DEC_Underflow)) { // interesting?
02222           if (status&DEC_Overflow || ISZERO(dac)) break;
02223           }
02224         // [the following two lines revealed an optimizer bug in a C++
02225         // compiler, with symptom: 5**3 -> 25, when n=n+n was used]
02226         n=n<<1;                    // move next bit to testable position
02227         if (n<0) {                 // top bit is set
02228           seenbit=1;               // OK, significant bit seen
02229           decMultiplyOp(dac, dac, lhs, &aset, &status); // dac=dac*x
02230           }
02231         if (i==31) break;          // that was the last bit
02232         if (!seenbit) continue;    // no need to square 1
02233         decMultiplyOp(dac, dac, dac, &aset, &status); // dac=dac*dac [square]
02234         } /*i*/ // 32 bits
02235
02236       // complete internal overflow or underflow processing
02237       if (status & (DEC_Overflow|DEC_Underflow)) {
02238         #if DECSUBSET
02239         // If subset, and power was negative, reverse the kind of -erflow
02240         // [1/x not yet done]
02241         if (!set->extended && decNumberIsNegative(rhs)) {
02242           if (status & DEC_Overflow)
02243             status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;
02244            else { // trickier -- Underflow may or may not be set
02245             status&=~(DEC_Underflow | DEC_Subnormal); // [one or both]
02246             status|=DEC_Overflow;
02247             }
02248           }
02249         #endif
02250         dac->bits=(dac->bits & ~DECNEG) | bits; // force correct sign
02251         // round subnormals [to set.digits rather than aset.digits]
02252         // or set overflow result similarly as required
02253         decFinalize(dac, set, &residue, &status);
02254         decNumberCopy(res, dac);   // copy to result (is now OK length)
02255         break;
02256         }
02257
02258       #if DECSUBSET
02259       if (!set->extended &&                  // subset math
02260           decNumberIsNegative(rhs)) {        // was a **-n [hence digits>0]
02261         // so divide result into 1 [dac=1/dac]
02262         decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);
02263         }
02264       #endif
02265       } // rhs integer path
02266
02267     // reduce result to the requested length and copy to result
02268     decCopyFit(res, dac, set, &residue, &status);
02269     decFinish(res, set, &residue, &status);  // final cleanup
02270     #if DECSUBSET
02271     if (!set->extended) decTrim(res, set, 0, 1, &dropped); // trailing zeros
02272     #endif
02273     } while(0);                         // end protected
02274
02275   if (allocdac!=NULL) free(allocdac);   // drop any storage used
02276   if (allocinv!=NULL) free(allocinv);   // ..
02277   #if DECSUBSET
02278   if (alloclhs!=NULL) free(alloclhs);   // ..
02279   if (allocrhs!=NULL) free(allocrhs);   // ..
02280   #endif
02281   if (status!=0) decStatus(res, status, set);
02282   #if DECCHECK
02283   decCheckInexact(res, set);
02284   #endif
02285   return res;
02286   } // decNumberPower

decNumber* decNumberQuantize | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2306 du fichier decNumber.c.

Références decQuantizeOp(), decStatus(), et uInt.

Référencé par decNumberToIntegralExact(), et DecFloat_::Quantize().

02307                                                                      {
02308   uInt status=0;                        // accumulator
02309   decQuantizeOp(res, lhs, rhs, set, 1, &status);
02310   if (status!=0) decStatus(res, status, set);
02311   return res;
02312   } // decNumberQuantize

decNumber* decNumberReduce | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2331 du fichier decNumber.c.

Références decCopyFit(), decFinish, decNaNs(), decNumberIsNaN, decStatus(), decTrim(), decNumber::digits, decContext::digits, Int, et uInt.

Référencé par decNumberNormalize().

02332                                              {
02333   #if DECSUBSET
02334   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
02335   #endif
02336   uInt status=0;                   // as usual
02337   Int  residue=0;                  // as usual
02338   Int  dropped;                    // work
02339
02340   #if DECCHECK
02341   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
02342   #endif
02343
02344   do {                             // protect allocated storage
02345     #if DECSUBSET
02346     if (!set->extended) {
02347       // reduce operand and set lostDigits status, as needed
02348       if (rhs->digits>set->digits) {
02349         allocrhs=decRoundOperand(rhs, set, &status);
02350         if (allocrhs==NULL) break;
02351         rhs=allocrhs;
02352         }
02353       }
02354     #endif
02355     // [following code does not require input rounding]
02356
02357     // Infinities copy through; NaNs need usual treatment
02358     if (decNumberIsNaN(rhs)) {
02359       decNaNs(res, rhs, NULL, set, &status);
02360       break;
02361       }
02362
02363     // reduce result to the requested length and copy to result
02364     decCopyFit(res, rhs, set, &residue, &status); // copy & round
02365     decFinish(res, set, &residue, &status);       // cleanup/set flags
02366     decTrim(res, set, 1, 0, &dropped);            // normalize in place
02367                                                   // [may clamp]
02368     } while(0);                              // end protected
02369
02370   #if DECSUBSET
02371   if (allocrhs !=NULL) free(allocrhs);       // ..
02372   #endif
02373   if (status!=0) decStatus(res, status, set);// then report status
02374   return res;
02375   } // decNumberReduce

decNumber* decNumberRemainder | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2415 du fichier decNumber.c.

Références decDivideOp(), decStatus(), REMAINDER, et uInt.

Référencé par DecFloat_::operator%=().

02416                                                                       {
02417   uInt status=0;                        // accumulator
02418   decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
02419   if (status!=0) decStatus(res, status, set);
02420   #if DECCHECK
02421   decCheckInexact(res, set);
02422   #endif
02423   return res;
02424   } // decNumberRemainder

decNumber* decNumberRemainderNear | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2438 du fichier decNumber.c.

Références decDivideOp(), decStatus(), REMNEAR, et uInt.

Référencé par RemainderNear().

02439                                                                           {
02440   uInt status=0;                        // accumulator
02441   decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
02442   if (status!=0) decStatus(res, status, set);
02443   #if DECCHECK
02444   decCheckInexact(res, set);
02445   #endif
02446   return res;
02447   } // decNumberRemainderNear

decNumber* decNumberRescale | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2395 du fichier decNumber.c.

Références decQuantizeOp(), decStatus(), et uInt.

Référencé par DecFloat_::Rescale(), et DecFloat_::ToChar().

02396                                                                     {
02397   uInt status=0;                        // accumulator
02398   decQuantizeOp(res, lhs, rhs, set, 0, &status);
02399   if (status!=0) decStatus(res, status, set);
02400   return res;
02401   } // decNumberRescale

decNumber* decNumberRotate | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2474 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decReverse(), decShiftToLeast(), decStatus(), decContext::digits, decNumber::exponent, Int, MSUDIGITS, powers, et uInt.

02475                                                                   {
02476   uInt status=0;              // accumulator
02477   Int  rotate;                // rhs as an Int
02478
02479   #if DECCHECK
02480   if (decCheckOperands(res, lhs, rhs, set)) return res;
02481   #endif
02482
02483   // NaNs propagate as normal
02484   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02485     decNaNs(res, lhs, rhs, set, &status);
02486    // rhs must be an integer
02487    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02488     status=DEC_Invalid_operation;
02489    else { // both numeric, rhs is an integer
02490     rotate=decGetInt(rhs);                   // [cannot fail]
02491     if (rotate==BADINT                       // something bad ..
02492      || rotate==BIGODD || rotate==BIGEVEN    // .. very big ..
02493      || abs(rotate)>set->digits)             // .. or out of range
02494       status=DEC_Invalid_operation;
02495      else {                                  // rhs is OK
02496       decNumberCopy(res, lhs);
02497       // convert -ve rotate to equivalent positive rotation
02498       if (rotate<0) rotate=set->digits+rotate;
02499       if (rotate!=0 && rotate!=set->digits   // zero or full rotation
02500        && !decNumberIsInfinite(res)) {       // lhs was infinite
02501         // left-rotate to do; 0 < rotate < set->digits
02502         uInt units, shift;                   // work
02503         uInt msudigits;                      // digits in result msu
02504         Unit *msu=res->lsu+D2U(res->digits)-1;    // current msu
02505         Unit *msumax=res->lsu+D2U(set->digits)-1; // rotation msu
02506         for (msu++; msu<=msumax; msu++) *msu=0;   // ensure high units=0
02507         res->digits=set->digits;                  // now full-length
02508         msudigits=MSUDIGITS(res->digits);         // actual digits in msu
02509
02510         // rotation here is done in-place, in three steps
02511         // 1. shift all to least up to one unit to unit-align final
02512         //    lsd [any digits shifted out are rotated to the left,
02513         //    abutted to the original msd (which may require split)]
02514         //
02515         //    [if there are no whole units left to rotate, the
02516         //    rotation is now complete]
02517         //
02518         // 2. shift to least, from below the split point only, so that
02519         //    the final msd is in the right place in its Unit [any
02520         //    digits shifted out will fit exactly in the current msu,
02521         //    left aligned, no split required]
02522         //
02523         // 3. rotate all the units by reversing left part, right
02524         //    part, and then whole
02525         //
02526         // example: rotate right 8 digits (2 units + 2), DECDPUN=3.
02527         //
02528         //   start: 00a bcd efg hij klm npq
02529         //
02530         //      1a  000 0ab cde fgh|ijk lmn [pq saved]
02531         //      1b  00p qab cde fgh|ijk lmn
02532         //
02533         //      2a  00p qab cde fgh|00i jkl [mn saved]
02534         //      2b  mnp qab cde fgh|00i jkl
02535         //
02536         //      3a  fgh cde qab mnp|00i jkl
02537         //      3b  fgh cde qab mnp|jkl 00i
02538         //      3c  00i jkl mnp qab cde fgh
02539
02540         // Step 1: amount to shift is the partial right-rotate count
02541         rotate=set->digits-rotate;      // make it right-rotate
02542         units=rotate/DECDPUN;           // whole units to rotate
02543         shift=rotate%DECDPUN;           // left-over digits count
02544         if (shift>0) {                  // not an exact number of units
02545           uInt save=res->lsu[0]%powers[shift];    // save low digit(s)
02546           decShiftToLeast(res->lsu, D2U(res->digits), shift);
02547           if (shift>msudigits) {        // msumax-1 needs >0 digits
02548             uInt rem=save%powers[shift-msudigits];// split save
02549             *msumax=(Unit)(save/powers[shift-msudigits]); // and insert
02550             *(msumax-1)=*(msumax-1)
02551                        +(Unit)(rem*powers[DECDPUN-(shift-msudigits)]); // ..
02552             }
02553            else { // all fits in msumax
02554             *msumax=*msumax+(Unit)(save*powers[msudigits-shift]); // [maybe *1]
02555             }
02556           } // digits shift needed
02557
02558         // If whole units to rotate...
02559         if (units>0) {                  // some to do
02560           // Step 2: the units to touch are the whole ones in rotate,
02561           //   if any, and the shift is DECDPUN-msudigits (which may be
02562           //   0, again)
02563           shift=DECDPUN-msudigits;
02564           if (shift>0) {                // not an exact number of units
02565             uInt save=res->lsu[0]%powers[shift];  // save low digit(s)
02566             decShiftToLeast(res->lsu, units, shift);
02567             *msumax=*msumax+(Unit)(save*powers[msudigits]);
02568             } // partial shift needed
02569
02570           // Step 3: rotate the units array using triple reverse
02571           // (reversing is easy and fast)
02572           decReverse(res->lsu+units, msumax);     // left part
02573           decReverse(res->lsu, res->lsu+units-1); // right part
02574           decReverse(res->lsu, msumax);           // whole
02575           } // whole units to rotate
02576         // the rotation may have left an undetermined number of zeros
02577         // on the left, so true length needs to be calculated
02578         res->digits=decGetDigits(res->lsu, msumax-res->lsu+1);
02579         } // rotate needed
02580       } // rhs OK
02581     } // numerics
02582   if (status!=0) decStatus(res, status, set);
02583   return res;
02584   } // decNumberRotate

decNumber* decNumberSameQuantum | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs
 | ) |  |

Définition à la ligne 2595 du fichier decNumber.c.

Références decNumberIsInfinite, decNumberIsNaN, decNumberZero(), decNumber::exponent, decNumber::lsu, et SPECIALARGS.

Référencé par DecFloat_::SameQuantum().

02596                                                        {
02597   Unit ret=0;                      // return value
02598
02599   #if DECCHECK
02600   if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;
02601   #endif
02602
02603   if (SPECIALARGS) {
02604     if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1;
02605      else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1;
02606      // [anything else with a special gives 0]
02607     }
02608    else if (lhs->exponent==rhs->exponent) ret=1;
02609
02610   decNumberZero(res);              // OK to overwrite an operand now
02611   *res->lsu=ret;
02612   return res;
02613   } // decNumberSameQuantum

decNumber* decNumberScaleB | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2630 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, DEC_Invalid_operation, decFinalize(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decStatus(), decContext::digits, decContext::emax, decNumber::exponent, Int, et uInt.

02631                                                                    {
02632   Int  reqexp;                // requested exponent change [B]
02633   uInt status=0;              // accumulator
02634   Int  residue;               // work
02635
02636   #if DECCHECK
02637   if (decCheckOperands(res, lhs, rhs, set)) return res;
02638   #endif
02639
02640   // Handle special values except lhs infinite
02641   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02642     decNaNs(res, lhs, rhs, set, &status);
02643     // rhs must be an integer
02644    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02645     status=DEC_Invalid_operation;
02646    else {
02647     // lhs is a number; rhs is a finite with q==0
02648     reqexp=decGetInt(rhs);                   // [cannot fail]
02649     if (reqexp==BADINT                       // something bad ..
02650      || reqexp==BIGODD || reqexp==BIGEVEN    // .. very big ..
02651      || abs(reqexp)>(2*(set->digits+set->emax))) // .. or out of range
02652       status=DEC_Invalid_operation;
02653      else {                                  // rhs is OK
02654       decNumberCopy(res, lhs);               // all done if infinite lhs
02655       if (!decNumberIsInfinite(res)) {       // prepare to scale
02656         res->exponent+=reqexp;               // adjust the exponent
02657         residue=0;
02658         decFinalize(res, set, &residue, &status); // .. and check
02659         } // finite LHS
02660       } // rhs OK
02661     } // rhs finite
02662   if (status!=0) decStatus(res, status, set);
02663   return res;
02664   } // decNumberScaleB

decNumber* decNumberSetBCD | ( | decNumber * | dn,
 |  | const uByte * | bcd,
 |  | uInt | n
 | ) |  |

Définition à la ligne 3504 du fichier decNumber.c.

Références D2U, DECDPUN, decNumber::digits, Int, decNumber::lsu, MSUDIGITS, uByte, et X10.

03504                                                                      {
03505   Unit *up=dn->lsu+D2U(dn->digits)-1;   // -> msu [target pointer]
03506   const uByte *ub=bcd;                  // -> source msd
03507
03508   #if DECDPUN==1                        // trivial simple copy
03509     for (; ub<bcd+n; ub++, up--) *up=*ub;
03510   #else                                 // some assembly needed
03511     // calculate how many digits in msu, and hence first cut
03512     Int cut=MSUDIGITS(n);               // [faster than remainder]
03513     for (;up>=dn->lsu; up--) {          // each Unit from msu
03514       *up=0;                            // will take <=DECDPUN digits
03515       for (; cut>0; ub++, cut--) *up=X10(*up)+*ub;
03516       cut=DECDPUN;                      // next Unit has all digits
03517       }
03518   #endif
03519   dn->digits=n;                         // set digit count
03520   return dn;
03521   } // decNumberSetBCD

decNumber* decNumberShift | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2687 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, D2U, DEC_Invalid_operation, decDecap(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decShiftToLeast(), decShiftToMost(), decStatus(), decContext::digits, decNumber::exponent, Int, et uInt.

02688                                                                   {
02689   uInt status=0;              // accumulator
02690   Int  shift;                 // rhs as an Int
02691
02692   #if DECCHECK
02693   if (decCheckOperands(res, lhs, rhs, set)) return res;
02694   #endif
02695
02696   // NaNs propagate as normal
02697   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02698     decNaNs(res, lhs, rhs, set, &status);
02699    // rhs must be an integer
02700    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02701     status=DEC_Invalid_operation;
02702    else { // both numeric, rhs is an integer
02703     shift=decGetInt(rhs);                    // [cannot fail]
02704     if (shift==BADINT                        // something bad ..
02705      || shift==BIGODD || shift==BIGEVEN      // .. very big ..
02706      || abs(shift)>set->digits)              // .. or out of range
02707       status=DEC_Invalid_operation;
02708      else {                                  // rhs is OK
02709       decNumberCopy(res, lhs);
02710       if (shift!=0 && !decNumberIsInfinite(res)) { // something to do
02711         if (shift>0) {                       // to left
02712           if (shift==set->digits) {          // removing all
02713             *res->lsu=0;                     // so place 0
02714             res->digits=1;                   // ..
02715             }
02716            else {                            //
02717             // first remove leading digits if necessary
02718             if (res->digits+shift>set->digits) {
02719               decDecap(res, res->digits+shift-set->digits);
02720               // that updated res->digits; may have gone to 1 (for a
02721               // single digit or for zero
02722               }
02723             if (res->digits>1 || *res->lsu)  // if non-zero..
02724               res->digits=decShiftToMost(res->lsu, res->digits, shift);
02725             } // partial left
02726           } // left
02727          else { // to right
02728           if (-shift>=res->digits) {         // discarding all
02729             *res->lsu=0;                     // so place 0
02730             res->digits=1;                   // ..
02731             }
02732            else {
02733             decShiftToLeast(res->lsu, D2U(res->digits), -shift);
02734             res->digits-=(-shift);
02735             }
02736           } // to right
02737         } // non-0 non-Inf shift
02738       } // rhs OK
02739     } // numerics
02740   if (status!=0) decStatus(res, status, set);
02741   return res;
02742   } // decNumberShift

decNumber* decNumberSquareRoot | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 2816 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, COMPARE, D2N, D2U, DEC_Clamped, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_EMAX, DEC_MIN_EMIN, DEC_Overflow, DEC_ROUND_DOWN, DEC_ROUND_HALF_EVEN, DEC_ROUND_UP, DEC_Rounded, DEC_Subnormal, DEC_Underflow, decAddOp(), DECBUFFER, decCompareOp(), decContextDefault(), decCopyFit(), decDivideOp(), decFinish, decMultiplyOp(), decNaNs(), DECNEG, decNumberCopy(), decNumberIsInfinite, decNumberIsNegative, decNumberZero(), decShiftToLeast(), decStatus(), decTrim(), decNumber::digits, decContext::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, MAXI, MINI, decContext::round, SPECIALARG, et uInt.

Référencé par sqrt().

02817                                                  {
02818   decContext workset, approxset;   // work contexts
02819   decNumber dzero;                 // used for constant zero
02820   Int  maxp;                       // largest working precision
02821   Int  workp;                      // working precision
02822   Int  residue=0;                  // rounding residue
02823   uInt status=0, ignore=0;         // status accumulators
02824   uInt rstatus;                    // ..
02825   Int  exp;                        // working exponent
02826   Int  ideal;                      // ideal (preferred) exponent
02827   Int  needbytes;                  // work
02828   Int  dropped;                    // ..
02829
02830   #if DECSUBSET
02831   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
02832   #endif
02833   // buffer for f [needs +1 in case DECBUFFER 0]
02834   decNumber buff[D2N(DECBUFFER+1)];
02835   // buffer for a [needs +2 to match likely maxp]
02836   decNumber bufa[D2N(DECBUFFER+2)];
02837   // buffer for temporary, b [must be same size as a]
02838   decNumber bufb[D2N(DECBUFFER+2)];
02839   decNumber *allocbuff=NULL;       // -> allocated buff, iff allocated
02840   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
02841   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
02842   decNumber *f=buff;               // reduced fraction
02843   decNumber *a=bufa;               // approximation to result
02844   decNumber *b=bufb;               // intermediate result
02845   // buffer for temporary variable, up to 3 digits
02846   decNumber buft[D2N(3)];
02847   decNumber *t=buft;               // up-to-3-digit constant or work
02848
02849   #if DECCHECK
02850   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
02851   #endif
02852
02853   do {                             // protect allocated storage
02854     #if DECSUBSET
02855     if (!set->extended) {
02856       // reduce operand and set lostDigits status, as needed
02857       if (rhs->digits>set->digits) {
02858         allocrhs=decRoundOperand(rhs, set, &status);
02859         if (allocrhs==NULL) break;
02860         // [Note: 'f' allocation below could reuse this buffer if
02861         // used, but as this is rare they are kept separate for clarity.]
02862         rhs=allocrhs;
02863         }
02864       }
02865     #endif
02866     // [following code does not require input rounding]
02867
02868     // handle infinities and NaNs
02869     if (SPECIALARG) {
02870       if (decNumberIsInfinite(rhs)) {         // an infinity
02871         if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
02872          else decNumberCopy(res, rhs);        // +Infinity
02873         }
02874        else decNaNs(res, rhs, NULL, set, &status); // a NaN
02875       break;
02876       }
02877
02878     // calculate the ideal (preferred) exponent [floor(exp/2)]
02879     // [It would be nicer to write: ideal=rhs->exponent>>1, but this
02880     // generates a compiler warning.  Generated code is the same.]
02881     ideal=(rhs->exponent&~1)/2;         // target
02882
02883     // handle zeros
02884     if (ISZERO(rhs)) {
02885       decNumberCopy(res, rhs);          // could be 0 or -0
02886       res->exponent=ideal;              // use the ideal [safe]
02887       // use decFinish to clamp any out-of-range exponent, etc.
02888       decFinish(res, set, &residue, &status);
02889       break;
02890       }
02891
02892     // any other -x is an oops
02893     if (decNumberIsNegative(rhs)) {
02894       status|=DEC_Invalid_operation;
02895       break;
02896       }
02897
02898     // space is needed for three working variables
02899     //   f -- the same precision as the RHS, reduced to 0.01->0.99...
02900     //   a -- Hull's approximation -- precision, when assigned, is
02901     //        currentprecision+1 or the input argument precision,
02902     //        whichever is larger (+2 for use as temporary)
02903     //   b -- intermediate temporary result (same size as a)
02904     // if any is too long for local storage, then allocate
02905     workp=MAXI(set->digits+1, rhs->digits);  // actual rounding precision
02906     workp=MAXI(workp, 7);                    // at least 7 for low cases
02907     maxp=workp+2;                            // largest working precision
02908
02909     needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
02910     if (needbytes>(Int)sizeof(buff)) {
02911       allocbuff=(decNumber *)malloc(needbytes);
02912       if (allocbuff==NULL) {  // hopeless -- abandon
02913         status|=DEC_Insufficient_storage;
02914         break;}
02915       f=allocbuff;            // use the allocated space
02916       }
02917     // a and b both need to be able to hold a maxp-length number
02918     needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
02919     if (needbytes>(Int)sizeof(bufa)) {            // [same applies to b]
02920       allocbufa=(decNumber *)malloc(needbytes);
02921       allocbufb=(decNumber *)malloc(needbytes);
02922       if (allocbufa==NULL || allocbufb==NULL) {   // hopeless
02923         status|=DEC_Insufficient_storage;
02924         break;}
02925       a=allocbufa;            // use the allocated spaces
02926       b=allocbufb;            // ..
02927       }
02928
02929     // copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1
02930     decNumberCopy(f, rhs);
02931     exp=f->exponent+f->digits;               // adjusted to Hull rules
02932     f->exponent=-(f->digits);                // to range
02933
02934     // set up working context
02935     decContextDefault(&workset, DEC_INIT_DECIMAL64);
02936     workset.emax=DEC_MAX_EMAX;
02937     workset.emin=DEC_MIN_EMIN;
02938
02939     // [Until further notice, no error is possible and status bits
02940     // (Rounded, etc.) should be ignored, not accumulated.]
02941
02942     // Calculate initial approximation, and allow for odd exponent
02943     workset.digits=workp;                    // p for initial calculation
02944     t->bits=0; t->digits=3;
02945     a->bits=0; a->digits=3;
02946     if ((exp & 1)==0) {                      // even exponent
02947       // Set t=0.259, a=0.819
02948       t->exponent=-3;
02949       a->exponent=-3;
02950       #if DECDPUN>=3
02951         t->lsu[0]=259;
02952         a->lsu[0]=819;
02953       #elif DECDPUN==2
02954         t->lsu[0]=59; t->lsu[1]=2;
02955         a->lsu[0]=19; a->lsu[1]=8;
02956       #else
02957         t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
02958         a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
02959       #endif
02960       }
02961      else {                                  // odd exponent
02962       // Set t=0.0819, a=2.59
02963       f->exponent--;                         // f=f/10
02964       exp++;                                 // e=e+1
02965       t->exponent=-4;
02966       a->exponent=-2;
02967       #if DECDPUN>=3
02968         t->lsu[0]=819;
02969         a->lsu[0]=259;
02970       #elif DECDPUN==2
02971         t->lsu[0]=19; t->lsu[1]=8;
02972         a->lsu[0]=59; a->lsu[1]=2;
02973       #else
02974         t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
02975         a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
02976       #endif
02977       }
02978
02979     decMultiplyOp(a, a, f, &workset, &ignore);    // a=a*f
02980     decAddOp(a, a, t, &workset, 0, &ignore);      // ..+t
02981     // [a is now the initial approximation for sqrt(f), calculated with
02982     // currentprecision, which is also a's precision.]
02983
02984     // the main calculation loop
02985     decNumberZero(&dzero);                   // make 0
02986     decNumberZero(t);                        // set t = 0.5
02987     t->lsu[0]=5;                             // ..
02988     t->exponent=-1;                          // ..
02989     workset.digits=3;                        // initial p
02990     for (; workset.digits<maxp;) {
02991       // set p to min(2*p - 2, maxp)  [hence 3; or: 4, 6, 10, ... , maxp]
02992       workset.digits=MINI(workset.digits*2-2, maxp);
02993       // a = 0.5 * (a + f/a)
02994       // [calculated at p then rounded to currentprecision]
02995       decDivideOp(b, f, a, &workset, DIVIDE, &ignore); // b=f/a
02996       decAddOp(b, b, a, &workset, 0, &ignore);         // b=b+a
02997       decMultiplyOp(a, b, t, &workset, &ignore);       // a=b*0.5
02998       } // loop
02999
03000     // Here, 0.1 <= a < 1 [Hull], and a has maxp digits
03001     // now reduce to length, etc.; this needs to be done with a
03002     // having the correct exponent so as to handle subnormals
03003     // correctly
03004     approxset=*set;                          // get emin, emax, etc.
03005     approxset.round=DEC_ROUND_HALF_EVEN;
03006     a->exponent+=exp/2;                      // set correct exponent
03007     rstatus=0;                               // clear status
03008     residue=0;                               // .. and accumulator
03009     decCopyFit(a, a, &approxset, &residue, &rstatus);  // reduce (if needed)
03010     decFinish(a, &approxset, &residue, &rstatus);      // clean and finalize
03011
03012     // Overflow was possible if the input exponent was out-of-range,
03013     // in which case quit
03014     if (rstatus&DEC_Overflow) {
03015       status=rstatus;                        // use the status as-is
03016       decNumberCopy(res, a);                 // copy to result
03017       break;
03018       }
03019
03020     // Preserve status except Inexact/Rounded
03021     status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));
03022
03023     // Carry out the Hull correction
03024     a->exponent-=exp/2;                      // back to 0.1->1
03025
03026     // a is now at final precision and within 1 ulp of the properly
03027     // rounded square root of f; to ensure proper rounding, compare
03028     // squares of (a - l/2 ulp) and (a + l/2 ulp) with f.
03029     // Here workset.digits=maxp and t=0.5, and a->digits determines
03030     // the ulp
03031     workset.digits--;                             // maxp-1 is OK now
03032     t->exponent=-a->digits-1;                     // make 0.5 ulp
03033     decAddOp(b, a, t, &workset, DECNEG, &ignore); // b = a - 0.5 ulp
03034     workset.round=DEC_ROUND_UP;
03035     decMultiplyOp(b, b, b, &workset, &ignore);    // b = mulru(b, b)
03036     decCompareOp(b, f, b, &workset, COMPARE, &ignore); // b ? f, reversed
03037     if (decNumberIsNegative(b)) {                 // f < b [i.e., b > f]
03038       // this is the more common adjustment, though both are rare
03039       t->exponent++;                              // make 1.0 ulp
03040       t->lsu[0]=1;                                // ..
03041       decAddOp(a, a, t, &workset, DECNEG, &ignore); // a = a - 1 ulp
03042       // assign to approx [round to length]
03043       approxset.emin-=exp/2;                      // adjust to match a
03044       approxset.emax-=exp/2;
03045       decAddOp(a, &dzero, a, &approxset, 0, &ignore);
03046       }
03047      else {
03048       decAddOp(b, a, t, &workset, 0, &ignore);    // b = a + 0.5 ulp
03049       workset.round=DEC_ROUND_DOWN;
03050       decMultiplyOp(b, b, b, &workset, &ignore);  // b = mulrd(b, b)
03051       decCompareOp(b, b, f, &workset, COMPARE, &ignore);   // b ? f
03052       if (decNumberIsNegative(b)) {               // b < f
03053         t->exponent++;                            // make 1.0 ulp
03054         t->lsu[0]=1;                              // ..
03055         decAddOp(a, a, t, &workset, 0, &ignore);  // a = a + 1 ulp
03056         // assign to approx [round to length]
03057         approxset.emin-=exp/2;                    // adjust to match a
03058         approxset.emax-=exp/2;
03059         decAddOp(a, &dzero, a, &approxset, 0, &ignore);
03060         }
03061       }
03062     // [no errors are possible in the above, and rounding/inexact during
03063     // estimation are irrelevant, so status was not accumulated]
03064
03065     // Here, 0.1 <= a < 1  (still), so adjust back
03066     a->exponent+=exp/2;                      // set correct exponent
03067
03068     // count droppable zeros [after any subnormal rounding] by
03069     // trimming a copy
03070     decNumberCopy(b, a);
03071     decTrim(b, set, 1, 1, &dropped);         // [drops trailing zeros]
03072
03073     // Set Inexact and Rounded.  The answer can only be exact if
03074     // it is short enough so that squaring it could fit in workp
03075     // digits, so this is the only (relatively rare) condition that
03076     // a careful check is needed
03077     if (b->digits*2-1 > workp) {             // cannot fit
03078       status|=DEC_Inexact|DEC_Rounded;
03079       }
03080      else {                                  // could be exact/unrounded
03081       uInt mstatus=0;                        // local status
03082       decMultiplyOp(b, b, b, &workset, &mstatus); // try the multiply
03083       if (mstatus&DEC_Overflow) {            // result just won't fit
03084         status|=DEC_Inexact|DEC_Rounded;
03085         }
03086        else {                                // plausible
03087         decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); // b ? rhs
03088         if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; // not equal
03089          else {                              // is Exact
03090           // here, dropped is the count of trailing zeros in 'a'
03091           // use closest exponent to ideal...
03092           Int todrop=ideal-a->exponent;      // most that can be dropped
03093           if (todrop<0) status|=DEC_Rounded; // ideally would add 0s
03094            else {                            // unrounded
03095             // there are some to drop, but emax may not allow all
03096             Int maxexp=set->emax-set->digits+1;
03097             Int maxdrop=maxexp-a->exponent;
03098             if (todrop>maxdrop && set->clamp) { // apply clamping
03099               todrop=maxdrop;
03100               status|=DEC_Clamped;
03101               }
03102             if (dropped<todrop) {            // clamp to those available
03103               todrop=dropped;
03104               status|=DEC_Clamped;
03105               }
03106             if (todrop>0) {                  // have some to drop
03107               decShiftToLeast(a->lsu, D2U(a->digits), todrop);
03108               a->exponent+=todrop;           // maintain numerical value
03109               a->digits-=todrop;             // new length
03110               }
03111             }
03112           }
03113         }
03114       }
03115
03116     // double-check Underflow, as perhaps the result could not have
03117     // been subnormal (initial argument too big), or it is now Exact
03118     if (status&DEC_Underflow) {
03119       Int ae=rhs->exponent+rhs->digits-1;    // adjusted exponent
03120       // check if truly subnormal
03121       #if DECEXTFLAG                         // DEC_Subnormal too
03122         if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow);
03123       #else
03124         if (ae>=set->emin*2) status&=~DEC_Underflow;
03125       #endif
03126       // check if truly inexact
03127       if (!(status&DEC_Inexact)) status&=~DEC_Underflow;
03128       }
03129
03130     decNumberCopy(res, a);                   // a is now the result
03131     } while(0);                              // end protected
03132
03133   if (allocbuff!=NULL) free(allocbuff);      // drop any storage used
03134   if (allocbufa!=NULL) free(allocbufa);      // ..
03135   if (allocbufb!=NULL) free(allocbufb);      // ..
03136   #if DECSUBSET
03137   if (allocrhs !=NULL) free(allocrhs);       // ..
03138   #endif
03139   if (status!=0) decStatus(res, status, set);// then report status
03140   #if DECCHECK
03141   decCheckInexact(res, set);
03142   #endif
03143   return res;
03144   } // decNumberSquareRoot

decNumber* decNumberSubtract | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 3158 du fichier decNumber.c.

Références decAddOp(), DECNEG, decStatus(), et uInt.

Référencé par DecFloat_::operator-=().

03159                                                                      {
03160   uInt status=0;                        // accumulator
03161
03162   decAddOp(res, lhs, rhs, set, DECNEG, &status);
03163   if (status!=0) decStatus(res, status, set);
03164   #if DECCHECK
03165   decCheckInexact(res, set);
03166   #endif
03167   return res;
03168   } // decNumberSubtract

char* decNumberToEngString | ( | const decNumber * | dn,
 |  | char * | string
 | ) |  |

Définition à la ligne 455 du fichier decNumber.c.

Références decToString().

Référencé par DecFloat_::ToChar(), et DecFloat_::ToStr().

00455                                                               {
00456   decToString(dn, string, 1);
00457   return string;
00458   } // DecNumberToEngString

Int decNumberToInt32 | ( | const decNumber * | dn,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 371 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, decContextSetStatus(), DECDPUN, DECNEG, DECSPECIAL, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, powers, uInt, Unit, et X10.

00371                                                            {
00372   #if DECCHECK
00373   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
00374   #endif
00375
00376   // special or too many digits, or bad exponent
00377   if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; // bad
00378    else { // is a finite integer with 10 or fewer digits
00379     Int d;                         // work
00380     const Unit *up;                // ..
00381     uInt hi=0, lo;                 // ..
00382     up=dn->lsu;                    // -> lsu
00383     lo=*up;                        // get 1 to 9 digits
00384     #if DECDPUN>1                  // split to higher
00385       hi=lo/10;
00386       lo=lo%10;
00387     #endif
00388     up++;
00389     // collect remaining Units, if any, into hi
00390     for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
00391     // now low has the lsd, hi the remainder
00392     if (hi>214748364 || (hi==214748364 && lo>7)) { // out of range?
00393       // most-negative is a reprieve
00394       if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000;
00395       // bad -- drop through
00396       }
00397      else { // in-range always
00398       Int i=X10(hi)+lo;
00399       if (dn->bits&DECNEG) return -i;
00400       return i;
00401       }
00402     } // integer
00403   decContextSetStatus(set, DEC_Invalid_operation); // [may not return]
00404   return 0;
00405   } // decNumberToInt32

decNumber* decNumberToIntegralExact | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 3191 du fichier decNumber.c.

Références decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberQuantize(), decNumberZero(), decStatus(), decContext::digits, decNumber::digits, decNumber::exponent, SPECIALARG, decContext::status, decContext::traps, et uInt.

Référencé par decNumberToIntegralValue().

03192                                                       {
03193   decNumber dn;
03194   decContext workset;              // working context
03195   uInt status=0;                   // accumulator
03196
03197   #if DECCHECK
03198   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
03199   #endif
03200
03201   // handle infinities and NaNs
03202   if (SPECIALARG) {
03203     if (decNumberIsInfinite(rhs)) decNumberCopy(res, rhs); // an Infinity
03204      else decNaNs(res, rhs, NULL, set, &status); // a NaN
03205     }
03206    else { // finite
03207     // have a finite number; no error possible (res must be big enough)
03208     if (rhs->exponent>=0) return decNumberCopy(res, rhs);
03209     // that was easy, but if negative exponent there is work to do...
03210     workset=*set;                  // clone rounding, etc.
03211     workset.digits=rhs->digits;    // no length rounding
03212     workset.traps=0;               // no traps
03213     decNumberZero(&dn);            // make a number with exponent 0
03214     decNumberQuantize(res, rhs, &dn, &workset);
03215     status|=workset.status;
03216     }
03217   if (status!=0) decStatus(res, status, set);
03218   return res;
03219   } // decNumberToIntegralExact

decNumber* decNumberToIntegralValue | ( | decNumber * | res,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 3221 du fichier decNumber.c.

Références DEC_Invalid_operation, decNumberToIntegralExact(), decContext::status, et decContext::traps.

Référencé par DecFloat_::ToIntegralValue().

03222                                                       {
03223   decContext workset=*set;         // working context
03224   workset.traps=0;                 // no traps
03225   decNumberToIntegralExact(res, rhs, &workset);
03226   // this never affects set, except for sNaNs; NaN will have been set
03227   // or propagated already, so no need to call decStatus
03228   set->status|=workset.status&DEC_Invalid_operation;
03229   return res;
03230   } // decNumberToIntegralValue

char* decNumberToString | ( | const decNumber * | dn,
 |  | char * | string
 | ) |  |

Définition à la ligne 450 du fichier decNumber.c.

Références decToString().

00450                                                            {
00451   decToString(dn, string, 0);
00452   return string;
00453   } // DecNumberToString

uInt decNumberToUInt32 | ( | const decNumber * | dn,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 407 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, decContextSetStatus(), DECDPUN, DECNEG, DECSPECIAL, decNumber::digits, decNumber::exponent, Int, ISZERO, decNumber::lsu, powers, uInt, Unit, et X10.

00407                                                              {
00408   #if DECCHECK
00409   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
00410   #endif
00411   // special or too many digits, or bad exponent, or negative (<0)
00412   if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0
00413     || (dn->bits&DECNEG && !ISZERO(dn)));                   // bad
00414    else { // is a finite integer with 10 or fewer digits
00415     Int d;                         // work
00416     const Unit *up;                // ..
00417     uInt hi=0, lo;                 // ..
00418     up=dn->lsu;                    // -> lsu
00419     lo=*up;                        // get 1 to 9 digits
00420     #if DECDPUN>1                  // split to higher
00421       hi=lo/10;
00422       lo=lo%10;
00423     #endif
00424     up++;
00425     // collect remaining Units, if any, into hi
00426     for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
00427
00428     // now low has the lsd, hi the remainder
00429     if (hi>429496729 || (hi==429496729 && lo>5)) ; // no reprieve possible
00430      else return X10(hi)+lo;
00431     } // integer
00432   decContextSetStatus(set, DEC_Invalid_operation); // [may not return]
00433   return 0;
00434   } // decNumberToUInt32

decNumber* decNumberTrim ( decNumber * dn )

Définition à la ligne 3573 du fichier decNumber.c.

Références DEC_INIT_BASE, decContextDefault(), decTrim(), et Int.

Référencé par DecFloat_::Trim().

03573                                          {
03574   Int  dropped;                    // work
03575   decContext set;                  // ..
03576   #if DECCHECK
03577   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
03578   #endif
03579   decContextDefault(&set, DEC_INIT_BASE);    // clamp=0
03580   return decTrim(dn, &set, 0, 1, &dropped);
03581   } // decNumberTrim

const char* decNumberVersion ( void )

Définition à la ligne 3588 du fichier decNumber.c.

Références DECVERSION.

03588                                     {
03589   return DECVERSION;
03590   } // decNumberVersion

decNumber* decNumberXor | ( | decNumber * | res,
 |  | const decNumber * | lhs,
 |  | const decNumber * | rhs,
 |  | decContext * | set
 | ) |  |

Définition à la ligne 3247 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

03248                                                                 {
03249   const Unit *ua, *ub;                  // -> operands
03250   const Unit *msua, *msub;              // -> operand msus
03251   Unit  *uc, *msuc;                     // -> result and its msu
03252   Int   msudigs;                        // digits in res msu
03253   #if DECCHECK
03254   if (decCheckOperands(res, lhs, rhs, set)) return res;
03255   #endif
03256
03257   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
03258    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
03259     decStatus(res, DEC_Invalid_operation, set);
03260     return res;
03261     }
03262   // operands are valid
03263   ua=lhs->lsu;                          // bottom-up
03264   ub=rhs->lsu;                          // ..
03265   uc=res->lsu;                          // ..
03266   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
03267   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
03268   msuc=uc+D2U(set->digits)-1;           // -> msu of result
03269   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
03270   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
03271     Unit a, b;                          // extract units
03272     if (ua>msua) a=0;
03273      else a=*ua;
03274     if (ub>msub) b=0;
03275      else b=*ub;
03276     *uc=0;                              // can now write back
03277     if (a|b) {                          // maybe 1 bits to examine
03278       Int i, j;
03279       // This loop could be unrolled and/or use BIN2BCD tables
03280       for (i=0; i<DECDPUN; i++) {
03281         if ((a^b)&1) *uc=*uc+(Unit)powers[i];     // effect XOR
03282         j=a%10;
03283         a=a/10;
03284         j|=b%10;
03285         b=b/10;
03286         if (j>1) {
03287           decStatus(res, DEC_Invalid_operation, set);
03288           return res;
03289           }
03290         if (uc==msuc && i==msudigs-1) break;      // just did final digit
03291         } // each digit
03292       } // non-zero
03293     } // each unit
03294   // [here uc-1 is the msu of the result]
03295   res->digits=decGetDigits(res->lsu, uc-res->lsu);
03296   res->exponent=0;                      // integer
03297   res->bits=0;                          // sign=0
03298   return res;  // [no status to set]
03299   } // decNumberXor

decNumber* decNumberZero ( decNumber * dn )

Définition à la ligne 3601 du fichier decNumber.c.

Références decNumber::bits, decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decFinalize(), DecFloat_::DecFloat_(), decLnOp(), decMultiplyOp(), decNumberAbs(), decNumberCopy(), decNumberFMA(), decNumberFromString(), decNumberFromUInt32(), decNumberLog10(), decNumberLogB(), decNumberMinus(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPlus(), decNumberPower(), decNumberSameQuantum(), decNumberSquareRoot(), decNumberToIntegralExact(), decSetOverflow(), decSetSubnormal(), et decStatus().

03601                                          {
03602
03603   #if DECCHECK
03604   if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
03605   #endif
03606
03607   dn->bits=0;
03608   dn->exponent=0;
03609   dn->digits=1;
03610   dn->lsu[0]=0;
03611   return dn;
03612   } // decNumberZero

static decNumber * decQuantizeOp | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * | ,
 |  | Flag | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 5844 du fichier decNumber.c.

Références BADINT, BIGEVEN, BIGODD, decNumber::bits, DEC_Inexact, DEC_Invalid_operation, DEC_Rounded, DEC_Underflow, decApplyRound(), decCopyFit(), decFinalize(), decGetInt(), DECINF, DECNAN, decNaNs(), decNumberCopy(), decShiftToMost(), DECSNAN, decNumber::digits, decContext::digits, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, et SPECIALARGS.

Référencé par decNumberQuantize(), et decNumberRescale().

05846                                                            {
05847   #if DECSUBSET
05848   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
05849   decNumber *allocrhs=NULL;        // .., rhs
05850   #endif
05851   const decNumber *inrhs=rhs;      // save original rhs
05852   Int   reqdigits=set->digits;     // requested DIGITS
05853   Int   reqexp;                    // requested exponent [-scale]
05854   Int   residue=0;                 // rounding residue
05855   Int   etiny=set->emin-(reqdigits-1);
05856
05857   #if DECCHECK
05858   if (decCheckOperands(res, lhs, rhs, set)) return res;
05859   #endif
05860
05861   do {                             // protect allocated storage
05862     #if DECSUBSET
05863     if (!set->extended) {
05864       // reduce operands and set lostDigits status, as needed
05865       if (lhs->digits>reqdigits) {
05866         alloclhs=decRoundOperand(lhs, set, status);
05867         if (alloclhs==NULL) break;
05868         lhs=alloclhs;
05869         }
05870       if (rhs->digits>reqdigits) { // [this only checks lostDigits]
05871         allocrhs=decRoundOperand(rhs, set, status);
05872         if (allocrhs==NULL) break;
05873         rhs=allocrhs;
05874         }
05875       }
05876     #endif
05877     // [following code does not require input rounding]
05878
05879     // Handle special values
05880     if (SPECIALARGS) {
05881       // NaNs get usual processing
05882       if (SPECIALARGS & (DECSNAN | DECNAN))
05883         decNaNs(res, lhs, rhs, set, status);
05884       // one infinity but not both is bad
05885       else if ((lhs->bits ^ rhs->bits) & DECINF)
05886         *status|=DEC_Invalid_operation;
05887       // both infinity: return lhs
05888       else decNumberCopy(res, lhs);          // [nop if in place]
05889       break;
05890       }
05891
05892     // set requested exponent
05893     if (quant) reqexp=inrhs->exponent;  // quantize -- match exponents
05894      else {                             // rescale -- use value of rhs
05895       // Original rhs must be an integer that fits and is in range,
05896       // which could be from -1999999997 to +999999999, thanks to
05897       // subnormals
05898       reqexp=decGetInt(inrhs);               // [cannot fail]
05899       }
05900
05901     #if DECSUBSET
05902     if (!set->extended) etiny=set->emin;     // no subnormals
05903     #endif
05904
05905     if (reqexp==BADINT                       // bad (rescale only) or ..
05906      || reqexp==BIGODD || reqexp==BIGEVEN    // very big (ditto) or ..
05907      || (reqexp<etiny)                       // < lowest
05908      || (reqexp>set->emax)) {                // > emax
05909       *status|=DEC_Invalid_operation;
05910       break;}
05911
05912     // the RHS has been processed, so it can be overwritten now if necessary
05913     if (ISZERO(lhs)) {                       // zero coefficient unchanged
05914       decNumberCopy(res, lhs);               // [nop if in place]
05915       res->exponent=reqexp;                  // .. just set exponent
05916       #if DECSUBSET
05917       if (!set->extended) res->bits=0;       // subset specification; no -0
05918       #endif
05919       }
05920      else {                                  // non-zero lhs
05921       Int adjust=reqexp-lhs->exponent;       // digit adjustment needed
05922       // if adjusted coefficient will definitely not fit, give up now
05923       if ((lhs->digits-adjust)>reqdigits) {
05924         *status|=DEC_Invalid_operation;
05925         break;
05926         }
05927
05928       if (adjust>0) {                        // increasing exponent
05929         // this will decrease the length of the coefficient by adjust
05930         // digits, and must round as it does so
05931         decContext workset;                  // work
05932         workset=*set;                        // clone rounding, etc.
05933         workset.digits=lhs->digits-adjust;   // set requested length
05934         // [note that the latter can be <1, here]
05935         decCopyFit(res, lhs, &workset, &residue, status); // fit to result
05936         decApplyRound(res, &workset, residue, status);    // .. and round
05937         residue=0;                                        // [used]
05938         // If just rounded a 999s case, exponent will be off by one;
05939         // adjust back (after checking space), if so.
05940         if (res->exponent>reqexp) {
05941           // re-check needed, e.g., for quantize(0.9999, 0.001) under
05942           // set->digits==3
05943           if (res->digits==reqdigits) {      // cannot shift by 1
05944             *status&=~(DEC_Inexact | DEC_Rounded); // [clean these]
05945             *status|=DEC_Invalid_operation;
05946             break;
05947             }
05948           res->digits=decShiftToMost(res->lsu, res->digits, 1); // shift
05949           res->exponent--;                   // (re)adjust the exponent.
05950           }
05951         #if DECSUBSET
05952         if (ISZERO(res) && !set->extended) res->bits=0; // subset; no -0
05953         #endif
05954         } // increase
05955        else /* adjust<=0 */ {                // decreasing or = exponent
05956         // this will increase the length of the coefficient by -adjust
05957         // digits, by adding zero or more trailing zeros; this is
05958         // already checked for fit, above
05959         decNumberCopy(res, lhs);             // [it will fit]
05960         // if padding needed (adjust<0), add it now...
05961         if (adjust<0) {
05962           res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
05963           res->exponent+=adjust;             // adjust the exponent
05964           }
05965         } // decrease
05966       } // non-zero
05967
05968     // Check for overflow [do not use Finalize in this case, as an
05969     // overflow here is a "don't fit" situation]
05970     if (res->exponent>set->emax-res->digits+1) {  // too big
05971       *status|=DEC_Invalid_operation;
05972       break;
05973       }
05974      else {
05975       decFinalize(res, set, &residue, status);    // set subnormal flags
05976       *status&=~DEC_Underflow;          // suppress Underflow [as per 754]
05977       }
05978     } while(0);                         // end protected
05979
05980   #if DECSUBSET
05981   if (allocrhs!=NULL) free(allocrhs);   // drop any storage used
05982   if (alloclhs!=NULL) free(alloclhs);   // ..
05983   #endif
05984   return res;
05985   } // decQuantizeOp

static void decReverse | ( | Unit * | ,
 |  | Unit * |  |
 | ) |  |  | [static]

Définition à la ligne 6675 du fichier decNumber.c.

Référencé par decNumberRotate().

06675                                              {
06676   Unit temp;
06677   for (; ulo<uhi; ulo++, uhi--) {
06678     temp=*ulo;
06679     *ulo=*uhi;
06680     *uhi=temp;
06681     }
06682   return;
06683   } // decReverse

static void decSetCoeff | ( | decNumber * | ,
 |  | decContext * | ,
 |  | const Unit * | ,
 |  | Int | ,
 |  | Int * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 6902 du fichier decNumber.c.

Références DEC_Inexact, DEC_Rounded, DECDPUN, decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, powers, et uInt.

Référencé par decAddOp(), decCopyFit(), decDivideOp(), decMultiplyOp(), et decSetSubnormal().

06903                                                              {
06904   Int   discard;              // number of digits to discard
06905   uInt  cut;                  // cut point in Unit
06906   const Unit *up;             // work
06907   Unit  *target;              // ..
06908   Int   count;                // ..
06909   #if DECDPUN<=4
06910   uInt  temp;                 // ..
06911   #endif
06912
06913   discard=len-set->digits;    // digits to discard
06914   if (discard<=0) {           // no digits are being discarded
06915     if (dn->lsu!=lsu) {       // copy needed
06916       // copy the coefficient array to the result number; no shift needed
06917       count=len;              // avoids D2U
06918       up=lsu;
06919       for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
06920         *target=*up;
06921       dn->digits=len;         // set the new length
06922       }
06923     // dn->exponent and residue are unchanged, record any inexactitude
06924     if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded);
06925     return;
06926     }
06927
06928   // some digits must be discarded ...
06929   dn->exponent+=discard;      // maintain numerical value
06930   *status|=DEC_Rounded;       // accumulate Rounded status
06931   if (*residue>1) *residue=1; // previous residue now to right, so reduce
06932
06933   if (discard>len) {          // everything, +1, is being discarded
06934     // guard digit is 0
06935     // residue is all the number [NB could be all 0s]
06936     if (*residue<=0) {        // not already positive
06937       count=len;              // avoids D2U
06938       for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { // found non-0
06939         *residue=1;
06940         break;                // no need to check any others
06941         }
06942       }
06943     if (*residue!=0) *status|=DEC_Inexact; // record inexactitude
06944     *dn->lsu=0;               // coefficient will now be 0
06945     dn->digits=1;             // ..
06946     return;
06947     } // total discard
06948
06949   // partial discard [most common case]
06950   // here, at least the first (most significant) discarded digit exists
06951
06952   // spin up the number, noting residue during the spin, until get to
06953   // the Unit with the first discarded digit.  When reach it, extract
06954   // it and remember its position
06955   count=0;
06956   for (up=lsu;; up++) {
06957     count+=DECDPUN;
06958     if (count>=discard) break; // full ones all checked
06959     if (*up!=0) *residue=1;
06960     } // up
06961
06962   // here up -> Unit with first discarded digit
06963   cut=discard-(count-DECDPUN)-1;
06964   if (cut==DECDPUN-1) {       // unit-boundary case (fast)
06965     Unit half=(Unit)powers[DECDPUN]>>1;
06966     // set residue directly
06967     if (*up>=half) {
06968       if (*up>half) *residue=7;
06969       else *residue+=5;       // add sticky bit
06970       }
06971      else { // <half
06972       if (*up!=0) *residue=3; // [else is 0, leave as sticky bit]
06973       }
06974     if (set->digits<=0) {     // special for Quantize/Subnormal :-(
06975       *dn->lsu=0;             // .. result is 0
06976       dn->digits=1;           // ..
06977       }
06978      else {                   // shift to least
06979       count=set->digits;      // now digits to end up with
06980       dn->digits=count;       // set the new length
06981       up++;                   // move to next
06982       // on unit boundary, so shift-down copy loop is simple
06983       for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
06984         *target=*up;
06985       }
06986     } // unit-boundary case
06987
06988    else { // discard digit is in low digit(s), and not top digit
06989     uInt  discard1;                // first discarded digit
06990     uInt  quot, rem;               // for divisions
06991     if (cut==0) quot=*up;          // is at bottom of unit
06992      else /* cut>0 */ {            // it's not at bottom of unit
06993       #if DECDPUN<=4
06994         quot=QUOT10(*up, cut);
06995         rem=*up-quot*powers[cut];
06996       #else
06997         rem=*up%powers[cut];
06998         quot=*up/powers[cut];
06999       #endif
07000       if (rem!=0) *residue=1;
07001       }
07002     // discard digit is now at bottom of quot
07003     #if DECDPUN<=4
07004       temp=(quot*6554)>>16;        // fast /10
07005       // Vowels algorithm here not a win (9 instructions)
07006       discard1=quot-X10(temp);
07007       quot=temp;
07008     #else
07009       discard1=quot%10;
07010       quot=quot/10;
07011     #endif
07012     // here, discard1 is the guard digit, and residue is everything
07013     // else [use mapping array to accumulate residue safely]
07014     *residue+=resmap[discard1];
07015     cut++;                         // update cut
07016     // here: up -> Unit of the array with bottom digit
07017     //       cut is the division point for each Unit
07018     //       quot holds the uncut high-order digits for the current unit
07019     if (set->digits<=0) {          // special for Quantize/Subnormal :-(
07020       *dn->lsu=0;                  // .. result is 0
07021       dn->digits=1;                // ..
07022       }
07023      else {                        // shift to least needed
07024       count=set->digits;           // now digits to end up with
07025       dn->digits=count;            // set the new length
07026       // shift-copy the coefficient array to the result number
07027       for (target=dn->lsu; ; target++) {
07028         *target=(Unit)quot;
07029         count-=(DECDPUN-cut);
07030         if (count<=0) break;
07031         up++;
07032         quot=*up;
07033         #if DECDPUN<=4
07034           quot=QUOT10(quot, cut);
07035           rem=*up-quot*powers[cut];
07036         #else
07037           rem=quot%powers[cut];
07038           quot=quot/powers[cut];
07039         #endif
07040         *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
07041         count-=cut;
07042         if (count<=0) break;
07043         } // shift-copy loop
07044       } // shift to least
07045     } // not unit boundary
07046
07047   if (*residue!=0) *status|=DEC_Inexact; // record inexactitude
07048   return;
07049   } // decSetCoeff

static void decSetMaxValue | ( | decNumber * | ,
 |  | decContext * |  |
 | ) |  |  | [static]

Définition à la ligne 7407 du fichier decNumber.c.

Références decNumber::bits, DECDPUN, decNumber::digits, decContext::digits, decContext::emax, decNumber::exponent, Int, et decNumber::lsu.

Référencé par decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), et decSetOverflow().

07407                                                            {
07408   Unit *up;                        // work
07409   Int count=set->digits;           // nines to add
07410   dn->digits=count;
07411   // fill in all nines to set maximum value
07412   for (up=dn->lsu; ; up++) {
07413     if (count>DECDPUN) *up=DECDPUNMAX;  // unit full o'nines
07414      else {                             // this is the msu
07415       *up=(Unit)(powers[count]-1);
07416       break;
07417       }
07418     count-=DECDPUN;                // filled those digits
07419     } // up
07420   dn->bits=0;                      // + sign
07421   dn->exponent=set->emax-set->digits+1;
07422   } // decSetMaxValue

static void decSetOverflow | ( | decNumber * | ,
 |  | decContext * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 7361 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, DEC_Clamped, DEC_Inexact, DEC_Overflow, DEC_ROUND_05UP, DEC_ROUND_CEILING, DEC_ROUND_DOWN, DEC_ROUND_FLOOR, DEC_Rounded, DECINF, DECNEG, decNumberZero(), decSetMaxValue(), decContext::digits, decContext::emax, decNumber::exponent, Flag, Int, ISZERO, decContext::round, et uByte.

Référencé par decApplyRound(), et decFinalize().

07361                                                                          {
07362   Flag needmax=0;                  // result is maximum finite value
07363   uByte sign=dn->bits&DECNEG;      // clean and save sign bit
07364
07365   if (ISZERO(dn)) {                // zero does not overflow magnitude
07366     Int emax=set->emax;                      // limit value
07367     if (set->clamp) emax-=set->digits-1;     // lower if clamping
07368     if (dn->exponent>emax) {                 // clamp required
07369       dn->exponent=emax;
07370       *status|=DEC_Clamped;
07371       }
07372     return;
07373     }
07374
07375   decNumberZero(dn);
07376   switch (set->round) {
07377     case DEC_ROUND_DOWN: {
07378       needmax=1;                   // never Infinity
07379       break;} // r-d
07380     case DEC_ROUND_05UP: {
07381       needmax=1;                   // never Infinity
07382       break;} // r-05
07383     case DEC_ROUND_CEILING: {
07384       if (sign) needmax=1;         // Infinity if non-negative
07385       break;} // r-c
07386     case DEC_ROUND_FLOOR: {
07387       if (!sign) needmax=1;        // Infinity if negative
07388       break;} // r-f
07389     default: break;                // Infinity in all other cases
07390     }
07391   if (needmax) {
07392     decSetMaxValue(dn, set);
07393     dn->bits=sign;                 // set sign
07394     }
07395    else dn->bits=sign|DECINF;      // Value is +/-Infinity
07396   *status|=DEC_Overflow | DEC_Inexact | DEC_Rounded;
07397   } // decSetOverflow

static void decSetSubnormal | ( | decNumber * | ,
 |  | decContext * | ,
 |  | Int * | ,
 |  | uInt * |  |
 | ) |  |  | [static]

Définition à la ligne 7441 du fichier decNumber.c.

Références DEC_Clamped, DEC_Inexact, DEC_Invalid_operation, DEC_Rounded, DEC_Subnormal, DEC_Underflow, decApplyRound(), decNumberZero(), decSetCoeff(), decShiftToMost(), decNumber::digits, decContext::digits, decContext::emin, decNumber::exponent, Int, ISZERO, et decNumber::lsu.

Référencé par decFinalize().

07442                                           {
07443   decContext workset;         // work
07444   Int        etiny, adjust;   // ..
07445
07446   #if DECSUBSET
07447   // simple set to zero and 'hard underflow' for subset
07448   if (!set->extended) {
07449     decNumberZero(dn);
07450     // always full overflow
07451     *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
07452     return;
07453     }
07454   #endif
07455
07456   // Full arithmetic -- allow subnormals, rounded to minimum exponent
07457   // (Etiny) if needed
07458   etiny=set->emin-(set->digits-1);      // smallest allowed exponent
07459
07460   if ISZERO(dn) {                       // value is zero
07461     // residue can never be non-zero here
07462     #if DECCHECK
07463       if (*residue!=0) {
07464         printf("++ Subnormal 0 residue %ld\n", (LI)*residue);
07465         *status|=DEC_Invalid_operation;
07466         }
07467     #endif
07468     if (dn->exponent<etiny) {           // clamp required
07469       dn->exponent=etiny;
07470       *status|=DEC_Clamped;
07471       }
07472     return;
07473     }
07474
07475   *status|=DEC_Subnormal;               // have a non-zero subnormal
07476   adjust=etiny-dn->exponent;            // calculate digits to remove
07477   if (adjust<=0) {                      // not out of range; unrounded
07478     // residue can never be non-zero here, except in the Nmin-residue
07479     // case (which is a subnormal result), so can take fast-path here
07480     // it may already be inexact (from setting the coefficient)
07481     if (*status&DEC_Inexact) *status|=DEC_Underflow;
07482     return;
07483     }
07484
07485   // adjust>0, so need to rescale the result so exponent becomes Etiny
07486   // [this code is similar to that in rescale]
07487   workset=*set;                         // clone rounding, etc.
07488   workset.digits=dn->digits-adjust;     // set requested length
07489   workset.emin-=adjust;                 // and adjust emin to match
07490   // [note that the latter can be <1, here, similar to Rescale case]
07491   decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
07492   decApplyRound(dn, &workset, *residue, status);
07493
07494   // Use 754 default rule: Underflow is set iff Inexact
07495   // [independent of whether trapped]
07496   if (*status&DEC_Inexact) *status|=DEC_Underflow;
07497
07498   // if rounded up a 999s case, exponent will be off by one; adjust
07499   // back if so [it will fit, because it was shortened earlier]
07500   if (dn->exponent>etiny) {
07501     dn->digits=decShiftToMost(dn->lsu, dn->digits, 1);
07502     dn->exponent--;                     // (re)adjust the exponent.
07503     }
07504
07505   // if rounded to zero, it is by definition clamped...
07506   if (ISZERO(dn)) *status|=DEC_Clamped;
07507   } // decSetSubnormal

static Int decShiftToLeast | ( | Unit * | ,
 |  | Int | ,
 |  | Int |  |
 | ) |  |  | [static]

Définition à la ligne 6754 du fichier decNumber.c.

Références D2U, DECDPUN, Int, MSUDIGITS, powers, et QUOT10.

Référencé par decDivideOp(), decNumberRotate(), decNumberShift(), et decNumberSquareRoot().

06754                                                             {
06755   Unit  *target, *up;              // work
06756   Int   cut, count;                // work
06757   Int   quot, rem;                 // for division
06758
06759   if (shift==0) return units;      // [fastpath] nothing to do
06760   if (shift==units*DECDPUN) {      // [fastpath] little to do
06761     *uar=0;                        // all digits cleared gives zero
06762     return 1;                      // leaves just the one
06763     }
06764
06765   target=uar;                      // both paths
06766   cut=MSUDIGITS(shift);
06767   if (cut==DECDPUN) {              // unit-boundary case; easy
06768     up=uar+D2U(shift);
06769     for (; up<uar+units; target++, up++) *target=*up;
06770     return target-uar;
06771     }
06772
06773   // messier
06774   up=uar+D2U(shift-cut);           // source; correct to whole Units
06775   count=units*DECDPUN-shift;       // the maximum new length
06776   #if DECDPUN<=4
06777     quot=QUOT10(*up, cut);
06778   #else
06779     quot=*up/powers[cut];
06780   #endif
06781   for (; ; target++) {
06782     *target=(Unit)quot;
06783     count-=(DECDPUN-cut);
06784     if (count<=0) break;
06785     up++;
06786     quot=*up;
06787     #if DECDPUN<=4
06788       quot=QUOT10(quot, cut);
06789       rem=*up-quot*powers[cut];
06790     #else
06791       rem=quot%powers[cut];
06792       quot=quot/powers[cut];
06793     #endif
06794     *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
06795     count-=cut;
06796     if (count<=0) break;
06797     }
06798   return target-uar+1;
06799   } // decShiftToLeast

static Int decShiftToMost | ( | Unit * | ,
 |  | Int | ,
 |  | Int |  |
 | ) |  |  | [static]

Définition à la ligne 6698 du fichier decNumber.c.

Références D2U, DECDPUN, Int, MSUDIGITS, powers, QUOT10, et uInt.

Référencé par decAddOp(), decExpOp(), decFinalize(), decNumberPower(), decNumberShift(), decQuantizeOp(), et decSetSubnormal().

06698                                                             {
06699   Unit  *target, *source, *first;  // work
06700   Int   cut;                       // odd 0's to add
06701   uInt  next;                      // work
06702
06703   if (shift==0) return digits;     // [fastpath] nothing to do
06704   if ((digits+shift)<=DECDPUN) {   // [fastpath] single-unit case
06705     *uar=(Unit)(*uar*powers[shift]);
06706     return digits+shift;
06707     }
06708
06709   next=0;                          // all paths
06710   source=uar+D2U(digits)-1;        // where msu comes from
06711   target=source+D2U(shift);        // where upper part of first cut goes
06712   cut=DECDPUN-MSUDIGITS(shift);    // where to slice
06713   if (cut==0) {                    // unit-boundary case
06714     for (; source>=uar; source--, target--) *target=*source;
06715     }
06716    else {
06717     first=uar+D2U(digits+shift)-1; // where msu of source will end up
06718     for (; source>=uar; source--, target--) {
06719       // split the source Unit and accumulate remainder for next
06720       #if DECDPUN<=4
06721         uInt quot=QUOT10(*source, cut);
06722         uInt rem=*source-quot*powers[cut];
06723         next+=quot;
06724       #else
06725         uInt rem=*source%powers[cut];
06726         next+=*source/powers[cut];
06727       #endif
06728       if (target<=first) *target=(Unit)next;   // write to target iff valid
06729       next=rem*powers[DECDPUN-cut];            // save remainder for next Unit
06730       }
06731     } // shift-move
06732
06733   // propagate any partial unit to one below and clear the rest
06734   for (; target>=uar; target--) {
06735     *target=(Unit)next;
06736     next=0;
06737     }
06738   return digits+shift;
06739   } // decShiftToMost

static void decStatus | ( | decNumber * | ,
 |  | uInt | ,
 |  | decContext * |  |
 | ) |  |  | [static]

Définition à la ligne 7754 du fichier decNumber.c.

Références decNumber::bits, DEC_NaNs, DEC_sNaN, decContextSetStatus(), DECNAN, et decNumberZero().

Référencé par decNumberAbs(), decNumberAdd(), decNumberAnd(), decNumberCompare(), decNumberCompareSignal(), decNumberCompareTotal(), decNumberCompareTotalMag(), decNumberDivide(), decNumberDivideInteger(), decNumberExp(), decNumberFMA(), decNumberInvert(), decNumberLn(), decNumberLog10(), decNumberLogB(), decNumberMax(), decNumberMaxMag(), decNumberMin(), decNumberMinMag(), decNumberMinus(), decNumberMultiply(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberOr(), decNumberPlus(), decNumberPower(), decNumberQuantize(), decNumberReduce(), decNumberRemainder(), decNumberRemainderNear(), decNumberRescale(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberSubtract(), decNumberToIntegralExact(), et decNumberXor().

07754                                                                    {
07755   if (status & DEC_NaNs) {              // error status -> NaN
07756     // if cause was an sNaN, clear and propagate [NaN is already set up]
07757     if (status & DEC_sNaN) status&=~DEC_sNaN;
07758      else {
07759       decNumberZero(dn);                // other error: clean throughout
07760       dn->bits=DECNAN;                  // and make a quiet NaN
07761       }
07762     }
07763   decContextSetStatus(set, status);     // [may not return]
07764   return;
07765   } // decStatus

static void decToString | ( | const decNumber * | dn,
 |  | char * | string,
 |  | Flag | eng |
 | ) |  |  | [static]

Définition à la ligne 3634 du fichier decNumber.c.

Références decNumber::bits, D2U, DECDPUN, decNumberIsInfinite, decNumberIsNegative, DECSNAN, DECSPECIAL, decNumber::digits, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, MSUDIGITS, pow(), TODIGIT, et uInt.

03634                                                                      {
03635   Int exp=dn->exponent;       // local copy
03636   Int e;                      // E-part value
03637   Int pre;                    // digits before the '.'
03638   Int cut;                    // for counting digits in a Unit
03639   char *c=string;             // work [output pointer]
03640   const Unit *up=dn->lsu+D2U(dn->digits)-1; // -> msu [input pointer]
03641   uInt u, pow;                // work
03642
03643   #if DECCHECK
03644   if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
03645     strcpy(string, "?");
03646     return;}
03647   #endif
03648
03649   if (decNumberIsNegative(dn)) {   // Negatives get a minus
03650     *c='-';
03651     c++;
03652     }
03653   if (dn->bits&DECSPECIAL) {       // Is a special value
03654     if (decNumberIsInfinite(dn)) {
03655       strcpy(c,   "Inf");
03656       strcpy(c+3, "inity");
03657       return;}
03658     // a NaN
03659     if (dn->bits&DECSNAN) {        // signalling NaN
03660       *c='s';
03661       c++;
03662       }
03663     strcpy(c, "NaN");
03664     c+=3;                          // step past
03665     // if not a clean non-zero coefficient, that's all there is in a
03666     // NaN string
03667     if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;
03668     // [drop through to add integer]
03669     }
03670
03671   // calculate how many digits in msu, and hence first cut
03672   cut=MSUDIGITS(dn->digits);       // [faster than remainder]
03673   cut--;                           // power of ten for digit
03674
03675   if (exp==0) {                    // simple integer [common fastpath]
03676     for (;up>=dn->lsu; up--) {     // each Unit from msu
03677       u=*up;                       // contains DECDPUN digits to lay out
03678       for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);
03679       cut=DECDPUN-1;               // next Unit has all digits
03680       }
03681     *c='\0';                       // terminate the string
03682     return;}
03683
03684   /* non-0 exponent -- assume plain form */
03685   pre=dn->digits+exp;              // digits before '.'
03686   e=0;                             // no E
03687   if ((exp>0) || (pre<-5)) {       // need exponential form
03688     e=exp+dn->digits-1;            // calculate E value
03689     pre=1;                         // assume one digit before '.'
03690     if (eng && (e!=0)) {           // engineering: may need to adjust
03691       Int adj;                     // adjustment
03692       // The C remainder operator is undefined for negative numbers, so
03693       // a positive remainder calculation must be used here
03694       if (e<0) {
03695         adj=(-e)%3;
03696         if (adj!=0) adj=3-adj;
03697         }
03698        else { // e>0
03699         adj=e%3;
03700         }
03701       e=e-adj;
03702       // if dealing with zero still produce an exponent which is a
03703       // multiple of three, as expected, but there will only be the
03704       // one zero before the E, still.  Otherwise note the padding.
03705       if (!ISZERO(dn)) pre+=adj;
03706        else {  // is zero
03707         if (adj!=0) {              // 0.00Esnn needed
03708           e=e+3;
03709           pre=-(2-adj);
03710           }
03711         } // zero
03712       } // eng
03713     } // need exponent
03714
03715   /* lay out the digits of the coefficient, adding 0s and . as needed */
03716   u=*up;
03717   if (pre>0) {                     // xxx.xxx or xx00 (engineering) form
03718     Int n=pre;
03719     for (; pre>0; pre--, c++, cut--) {
03720       if (cut<0) {                 // need new Unit
03721         if (up==dn->lsu) break;    // out of input digits (pre>digits)
03722         up--;
03723         cut=DECDPUN-1;
03724         u=*up;
03725         }
03726       TODIGIT(u, cut, c, pow);
03727       }
03728     if (n<dn->digits) {            // more to come, after '.'
03729       *c='.'; c++;
03730       for (;; c++, cut--) {
03731         if (cut<0) {               // need new Unit
03732           if (up==dn->lsu) break;  // out of input digits
03733           up--;
03734           cut=DECDPUN-1;
03735           u=*up;
03736           }
03737         TODIGIT(u, cut, c, pow);
03738         }
03739       }
03740      else for (; pre>0; pre--, c++) *c='0'; // 0 padding (for engineering) needed
03741     }
03742    else {                          // 0.xxx or 0.000xxx form
03743     *c='0'; c++;
03744     *c='.'; c++;
03745     for (; pre<0; pre++, c++) *c='0';   // add any 0's after '.'
03746     for (; ; c++, cut--) {
03747       if (cut<0) {                 // need new Unit
03748         if (up==dn->lsu) break;    // out of input digits
03749         up--;
03750         cut=DECDPUN-1;
03751         u=*up;
03752         }
03753       TODIGIT(u, cut, c, pow);
03754       }
03755     }
03756
03757   /* Finally add the E-part, if needed.  It will never be 0, has a
03758      base maximum and minimum of +999999999 through -999999999, but
03759      could range down to -1999999998 for anormal numbers */
03760   if (e!=0) {
03761     Flag had=0;               // 1=had non-zero
03762     *c='E'; c++;
03763     *c='+'; c++;              // assume positive
03764     u=e;                      // ..
03765     if (e<0) {
03766       *(c-1)='-';             // oops, need -
03767       u=-e;                   // uInt, please
03768       }
03769     // lay out the exponent [_itoa or equivalent is not ANSI C]
03770     for (cut=9; cut>=0; cut--) {
03771       TODIGIT(u, cut, c, pow);
03772       if (*c=='0' && !had) continue;    // skip leading zeros
03773       had=1;                            // had non-0
03774       c++;                              // step for next
03775       } // cut
03776     }
03777   *c='\0';          // terminate the string (all paths)
03778   return;
03779   } // decToString

static void decToString | ( | const decNumber * | ,
 |  | char | [],
 |  | Flag |  |
 | ) |  |  | [static]

Référencé par decNumberToEngString(), et decNumberToString().

static decNumber * decTrim | ( | decNumber * | ,
 |  | decContext * | ,
 |  | Flag | ,
 |  | Flag | ,
 |  | Int * |  |
 | ) |  |  | [static]

Définition à la ligne 6604 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, DECDPUN, DECSPECIAL, decContext::digits, decNumber::digits, decContext::emax, decNumber::exponent, Int, ISZERO, decNumber::lsu, powers, QUOT10, et uInt.

Référencé par decDivideOp(), decNumberPower(), decNumberReduce(), decNumberSquareRoot(), et decNumberTrim().

06605                                                        {
06606   Int   d, exp;                    // work
06607   uInt  cut;                       // ..
06608   Unit  *up;                       // -> current Unit
06609
06610   #if DECCHECK
06611   if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
06612   #endif
06613
06614   *dropped=0;                           // assume no zeros dropped
06615   if ((dn->bits & DECSPECIAL)           // fast exit if special ..
06616     || (*dn->lsu & 0x01)) return dn;    // .. or odd
06617   if (ISZERO(dn)) {                     // .. or 0
06618     dn->exponent=0;                     // (sign is preserved)
06619     return dn;
06620     }
06621
06622   // have a finite number which is even
06623   exp=dn->exponent;
06624   cut=1;                           // digit (1-DECDPUN) in Unit
06625   up=dn->lsu;                      // -> current Unit
06626   for (d=0; d<dn->digits-1; d++) { // [don't strip the final digit]
06627     // slice by powers
06628     #if DECDPUN<=4
06629       uInt quot=QUOT10(*up, cut);
06630       if ((*up-quot*powers[cut])!=0) break;  // found non-0 digit
06631     #else
06632       if (*up%powers[cut]!=0) break;         // found non-0 digit
06633     #endif
06634     // have a trailing 0
06635     if (!all) {                    // trimming
06636       // [if exp>0 then all trailing 0s are significant for trim]
06637       if (exp<=0) {                // if digit might be significant
06638         if (exp==0) break;         // then quit
06639         exp++;                     // next digit might be significant
06640         }
06641       }
06642     cut++;                         // next power
06643     if (cut>DECDPUN) {             // need new Unit
06644       up++;
06645       cut=1;
06646       }
06647     } // d
06648   if (d==0) return dn;             // none to drop
06649
06650   // may need to limit drop if clamping
06651   if (set->clamp && !noclamp) {
06652     Int maxd=set->emax-set->digits+1-dn->exponent;
06653     if (maxd<=0) return dn;        // nothing possible
06654     if (d>maxd) d=maxd;
06655     }
06656
06657   // effect the drop
06658   decShiftToLeast(dn->lsu, D2U(dn->digits), d);
06659   dn->exponent+=d;                 // maintain numerical value
06660   dn->digits-=d;                   // new length
06661   *dropped=d;                      // report the count
06662   return dn;
06663   } // decTrim

static Int decUnitAddSub | ( | const Unit * | ,
 |  | Int | ,
 |  | const Unit * | ,
 |  | Int | ,
 |  | Int | ,
 |  | Unit * | ,
 |  | Int |  |
 | ) |  |  | [static]

Définition à la ligne 6350 du fichier decNumber.c.

Références DECDPUN, eInt, Int, QUOT10, et ueInt.

Référencé par decAddOp(), decDivideOp(), decMultiplyOp(), et decUnitCompare().

06352                                          {
06353   const Unit *alsu=a;              // A lsu [need to remember it]
06354   Unit *clsu=c;                    // C ditto
06355   Unit *minC;                      // low water mark for C
06356   Unit *maxC;                      // high water mark for C
06357   eInt carry=0;                    // carry integer (could be Long)
06358   Int  add;                        // work
06359   #if DECDPUN<=4                   // myriadal, millenary, etc.
06360   Int  est;                        // estimated quotient
06361   #endif
06362
06363   #if DECTRACE
06364   if (alength<1 || blength<1)
06365     printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m);
06366   #endif
06367
06368   maxC=c+alength;                  // A is usually the longer
06369   minC=c+blength;                  // .. and B the shorter
06370   if (bshift!=0) {                 // B is shifted; low As copy across
06371     minC+=bshift;
06372     // if in place [common], skip copy unless there's a gap [rare]
06373     if (a==c && bshift<=alength) {
06374       c+=bshift;
06375       a+=bshift;
06376       }
06377      else for (; c<clsu+bshift; a++, c++) {  // copy needed
06378       if (a<alsu+alength) *c=*a;
06379        else *c=0;
06380       }
06381     }
06382   if (minC>maxC) { // swap
06383     Unit *hold=minC;
06384     minC=maxC;
06385     maxC=hold;
06386     }
06387
06388   // For speed, do the addition as two loops; the first where both A
06389   // and B contribute, and the second (if necessary) where only one or
06390   // other of the numbers contribute.
06391   // Carry handling is the same (i.e., duplicated) in each case.
06392   for (; c<minC; c++) {
06393     carry+=*a;
06394     a++;
06395     carry+=((eInt)*b)*m;                // [special-casing m=1/-1
06396     b++;                                // here is not a win]
06397     // here carry is new Unit of digits; it could be +ve or -ve
06398     if ((ueInt)carry<=DECDPUNMAX) {     // fastpath 0-DECDPUNMAX
06399       *c=(Unit)carry;
06400       carry=0;
06401       continue;
06402       }
06403     #if DECDPUN==4                           // use divide-by-multiply
06404       if (carry>=0) {
06405         est=(((ueInt)carry>>11)*53687)>>18;
06406         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06407         carry=est;                           // likely quotient [89%]
06408         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06409         carry++;
06410         *c-=DECDPUNMAX+1;
06411         continue;
06412         }
06413       // negative case
06414       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06415       est=(((ueInt)carry>>11)*53687)>>18;
06416       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06417       carry=est-(DECDPUNMAX+1);              // correctly negative
06418       if (*c<DECDPUNMAX+1) continue;         // was OK
06419       carry++;
06420       *c-=DECDPUNMAX+1;
06421     #elif DECDPUN==3
06422       if (carry>=0) {
06423         est=(((ueInt)carry>>3)*16777)>>21;
06424         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06425         carry=est;                           // likely quotient [99%]
06426         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06427         carry++;
06428         *c-=DECDPUNMAX+1;
06429         continue;
06430         }
06431       // negative case
06432       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06433       est=(((ueInt)carry>>3)*16777)>>21;
06434       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06435       carry=est-(DECDPUNMAX+1);              // correctly negative
06436       if (*c<DECDPUNMAX+1) continue;         // was OK
06437       carry++;
06438       *c-=DECDPUNMAX+1;
06439     #elif DECDPUN<=2
06440       // Can use QUOT10 as carry <= 4 digits
06441       if (carry>=0) {
06442         est=QUOT10(carry, DECDPUN);
06443         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06444         carry=est;                           // quotient
06445         continue;
06446         }
06447       // negative case
06448       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06449       est=QUOT10(carry, DECDPUN);
06450       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06451       carry=est-(DECDPUNMAX+1);              // correctly negative
06452     #else
06453       // remainder operator is undefined if negative, so must test
06454       if ((ueInt)carry<(DECDPUNMAX+1)*2) {   // fastpath carry +1
06455         *c=(Unit)(carry-(DECDPUNMAX+1));     // [helps additions]
06456         carry=1;
06457         continue;
06458         }
06459       if (carry>=0) {
06460         *c=(Unit)(carry%(DECDPUNMAX+1));
06461         carry=carry/(DECDPUNMAX+1);
06462         continue;
06463         }
06464       // negative case
06465       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06466       *c=(Unit)(carry%(DECDPUNMAX+1));
06467       carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
06468     #endif
06469     } // c
06470
06471   // now may have one or other to complete
06472   // [pretest to avoid loop setup/shutdown]
06473   if (c<maxC) for (; c<maxC; c++) {
06474     if (a<alsu+alength) {               // still in A
06475       carry+=*a;
06476       a++;
06477       }
06478      else {                             // inside B
06479       carry+=((eInt)*b)*m;
06480       b++;
06481       }
06482     // here carry is new Unit of digits; it could be +ve or -ve and
06483     // magnitude up to DECDPUNMAX squared
06484     if ((ueInt)carry<=DECDPUNMAX) {     // fastpath 0-DECDPUNMAX
06485       *c=(Unit)carry;
06486       carry=0;
06487       continue;
06488       }
06489     // result for this unit is negative or >DECDPUNMAX
06490     #if DECDPUN==4                           // use divide-by-multiply
06491       if (carry>=0) {
06492         est=(((ueInt)carry>>11)*53687)>>18;
06493         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06494         carry=est;                           // likely quotient [79.7%]
06495         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06496         carry++;
06497         *c-=DECDPUNMAX+1;
06498         continue;
06499         }
06500       // negative case
06501       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06502       est=(((ueInt)carry>>11)*53687)>>18;
06503       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06504       carry=est-(DECDPUNMAX+1);              // correctly negative
06505       if (*c<DECDPUNMAX+1) continue;         // was OK
06506       carry++;
06507       *c-=DECDPUNMAX+1;
06508     #elif DECDPUN==3
06509       if (carry>=0) {
06510         est=(((ueInt)carry>>3)*16777)>>21;
06511         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06512         carry=est;                           // likely quotient [99%]
06513         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06514         carry++;
06515         *c-=DECDPUNMAX+1;
06516         continue;
06517         }
06518       // negative case
06519       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06520       est=(((ueInt)carry>>3)*16777)>>21;
06521       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06522       carry=est-(DECDPUNMAX+1);              // correctly negative
06523       if (*c<DECDPUNMAX+1) continue;         // was OK
06524       carry++;
06525       *c-=DECDPUNMAX+1;
06526     #elif DECDPUN<=2
06527       if (carry>=0) {
06528         est=QUOT10(carry, DECDPUN);
06529         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06530         carry=est;                           // quotient
06531         continue;
06532         }
06533       // negative case
06534       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06535       est=QUOT10(carry, DECDPUN);
06536       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06537       carry=est-(DECDPUNMAX+1);              // correctly negative
06538     #else
06539       if ((ueInt)carry<(DECDPUNMAX+1)*2){    // fastpath carry 1
06540         *c=(Unit)(carry-(DECDPUNMAX+1));
06541         carry=1;
06542         continue;
06543         }
06544       // remainder operator is undefined if negative, so must test
06545       if (carry>=0) {
06546         *c=(Unit)(carry%(DECDPUNMAX+1));
06547         carry=carry/(DECDPUNMAX+1);
06548         continue;
06549         }
06550       // negative case
06551       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06552       *c=(Unit)(carry%(DECDPUNMAX+1));
06553       carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
06554     #endif
06555     } // c
06556
06557   // OK, all A and B processed; might still have carry or borrow
06558   // return number of Units in the result, negated if a borrow
06559   if (carry==0) return c-clsu;     // no carry, so no more to do
06560   if (carry>0) {                   // positive carry
06561     *c=(Unit)carry;                // place as new unit
06562     c++;                           // ..
06563     return c-clsu;
06564     }
06565   // -ve carry: it's a borrow; complement needed
06566   add=1;                           // temporary carry...
06567   for (c=clsu; c<maxC; c++) {
06568     add=DECDPUNMAX+add-*c;
06569     if (add<=DECDPUNMAX) {
06570       *c=(Unit)add;
06571       add=0;
06572       }
06573      else {
06574       *c=0;
06575       add=1;
06576       }
06577     }
06578   // add an extra unit iff it would be non-zero
06579   #if DECTRACE
06580     printf("UAS borrow: add %ld, carry %ld\n", add, carry);
06581   #endif
06582   if ((add-carry-1)!=0) {
06583     *c=(Unit)(add-carry-1);
06584     c++;                      // interesting, include it
06585     }
06586   return clsu-c;              // -ve result indicates borrowed
06587   } // decUnitAddSub

static Int decUnitCompare | ( | const Unit * | ,
 |  | Int | ,
 |  | const Unit * | ,
 |  | Int | ,
 |  | Int |  |
 | ) |  |  | [static]

Définition à la ligne 6246 du fichier decNumber.c.

Références BADINT, D2U, DECBUFFER, DECDPUN, decUnitAddSub(), Int, powers, et SD2U.

Référencé par decCompare(), decCompareOp(), et decDivideOp().

06247                                                                {
06248   Unit  *acc;                      // accumulator for result
06249   Unit  accbuff[SD2U(DECBUFFER*2+1)]; // local buffer
06250   Unit  *allocacc=NULL;            // -> allocated acc buffer, iff allocated
06251   Int   accunits, need;            // units in use or needed for acc
06252   const Unit *l, *r, *u;           // work
06253   Int   expunits, exprem, result;  // ..
06254
06255   if (exp==0) {                    // aligned; fastpath
06256     if (alength>blength) return 1;
06257     if (alength<blength) return -1;
06258     // same number of units in both -- need unit-by-unit compare
06259     l=a+alength-1;
06260     r=b+alength-1;
06261     for (;l>=a; l--, r--) {
06262       if (*l>*r) return 1;
06263       if (*l<*r) return -1;
06264       }
06265     return 0;                      // all units match
06266     } // aligned
06267
06268   // Unaligned.  If one is >1 unit longer than the other, padded
06269   // approximately, then can return easily
06270   if (alength>blength+(Int)D2U(exp)) return 1;
06271   if (alength+1<blength+(Int)D2U(exp)) return -1;
06272
06273   // Need to do a real subtract.  For this, a result buffer is needed
06274   // even though only the sign is of interest.  Its length needs
06275   // to be the larger of alength and padded blength, +2
06276   need=blength+D2U(exp);                // maximum real length of B
06277   if (need<alength) need=alength;
06278   need+=2;
06279   acc=accbuff;                          // assume use local buffer
06280   if (need*sizeof(Unit)>sizeof(accbuff)) {
06281     allocacc=(Unit *)malloc(need*sizeof(Unit));
06282     if (allocacc==NULL) return BADINT;  // hopeless -- abandon
06283     acc=allocacc;
06284     }
06285   // Calculate units and remainder from exponent.
06286   expunits=exp/DECDPUN;
06287   exprem=exp%DECDPUN;
06288   // subtract [A+B*(-m)]
06289   accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,
06290                          -(Int)powers[exprem]);
06291   // [UnitAddSub result may have leading zeros, even on zero]
06292   if (accunits<0) result=-1;            // negative result
06293    else {                               // non-negative result
06294     // check units of the result before freeing any storage
06295     for (u=acc; u<acc+accunits-1 && *u==0;) u++;
06296     result=(*u==0 ? 0 : +1);
06297     }
06298   // clean up and return the result
06299   if (allocacc!=NULL) free(allocacc);   // drop any storage used
06300   return result;
06301   } // decUnitCompare

Documentation des variables

const uByte d2utable[DECMAXD2U+1] = D2UTABLE

Définition à la ligne 176 du fichier decNumber.c.

const uShort LNnn[90]

Valeur initiale :

{9016,  8652,  8316,  8008,  7724,  7456,  7208,
  6972,  6748,  6540,  6340,  6148,  5968,  5792,  5628,  5464,  5312,
  5164,  5020,  4884,  4748,  4620,  4496,  4376,  4256,  4144,  4032,
 39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
 29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
 22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
 15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
 10197,  9685,  9177,  8677,  8185,  7697,  7213,  6737,  6269,  5801,
  5341,  4889,  4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
 10130,  6046, 20055}

Définition à la ligne 5528 du fichier decNumber.c.

const uInt multies[] = {131073, 26215, 5243, 1049, 210} [static]

Définition à la ligne 210 du fichier decNumber.c.

const uByte resmap[10] = {0, 3, 3, 3, 3, 5, 7, 7, 7, 7} [static]

Définition à la ligne 6901 du fichier decNumber.c.

Unit uarrone[1] = {1} [static]

Définition à la ligne 201 du fichier decNumber.c.

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


Decimal: Fichier source de P:/wx_LIB/Dcml/decNumber.c

P:/wx_LIB/Dcml/decNumber.c

Aller à la documentation de ce fichier.
00001 /* ------------------------------------------------------------------ */
00002 /* Decimal Number arithmetic module                                   */
00003 /* ------------------------------------------------------------------ */
00004 /* Copyright (c) IBM Corporation, 2000, 2008.  All rights reserved.   */
00005 /*                                                                    */
00006 /* This software is made available under the terms of the IBM         */
00007 /* alphaWorks License Agreement (distributed with this software as    */
00008 /* alphaWorks-License.txt).  Your use of this software indicates      */
00009 /* your acceptance of the terms and conditions of that Agreement.     */
00010 /*                                                                    */
00011 /* The description and User's Guide ("The decNumber C Library") for   */
00012 /* this software is called decNumber.pdf.  This document is           */
00013 /* available, together with arithmetic and format specifications,     */
00014 /* testcases, and Web links, on the General Decimal Arithmetic page.  */
00015 /*                                                                    */
00016 /* Please send comments, suggestions, and corrections to the author:  */
00017 /*   mfc@uk.ibm.com                                                   */
00018 /*   Mike Cowlishaw, IBM Fellow                                       */
00019 /*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
00020 /* ------------------------------------------------------------------ */
00021 /* This module comprises the routines for arbitrary-precision General */
00022 /* Decimal Arithmetic as defined in the specification which may be    */
00023 /* found on the General Decimal Arithmetic pages.  It implements both */
00024 /* the full ('extended') arithmetic and the simpler ('subset')        */
00025 /* arithmetic.                                                        */
00026 /*                                                                    */
00027 /* Usage notes:                                                       */
00028 /*                                                                    */
00029 /* 1. This code is ANSI C89 except:                                   */
00030 /*                                                                    */
00031 /*    a) C99 line comments (double forward slash) are used.  (Most C  */
00032 /*       compilers accept these.  If yours does not, a simple script  */
00033 /*       can be used to convert them to ANSI C comments.)             */
00034 /*                                                                    */
00035 /*    b) Types from C99 stdint.h are used.  If you do not have this   */
00036 /*       header file, see the User's Guide section of the decNumber   */
00037 /*       documentation; this lists the necessary definitions.         */
00038 /*                                                                    */
00039 /*    c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and       */
00040 /*       uint64_t types may be used.  To avoid these, set DECUSE64=0  */
00041 /*       and DECDPUN<=4 (see documentation).                          */
00042 /*                                                                    */
00043 /*    The code also conforms to C99 restrictions; in particular,      */
00044 /*    strict aliasing rules are observed.                             */
00045 /*                                                                    */
00046 /* 2. The decNumber format which this library uses is optimized for   */
00047 /*    efficient processing of relatively short numbers; in particular */
00048 /*    it allows the use of fixed sized structures and minimizes copy  */
00049 /*    and move operations.  It does, however, support arbitrary       */
00050 /*    precision (up to 999,999,999 digits) and arbitrary exponent     */
00051 /*    range (Emax in the range 0 through 999,999,999 and Emin in the  */
00052 /*    range -999,999,999 through 0).  Mathematical functions (for     */
00053 /*    example decNumberExp) as identified below are restricted more   */
00054 /*    tightly: digits, emax, and -emin in the context must be <=      */
00055 /*    DEC_MAX_MATH (999999), and their operand(s) must be within      */
00056 /*    these bounds.                                                   */
00057 /*                                                                    */
00058 /* 3. Logical functions are further restricted; their operands must   */
00059 /*    be finite, positive, have an exponent of zero, and all digits   */
00060 /*    must be either 0 or 1.  The result will only contain digits     */
00061 /*    which are 0 or 1 (and will have exponent=0 and a sign of 0).    */
00062 /*                                                                    */
00063 /* 4. Operands to operator functions are never modified unless they   */
00064 /*    are also specified to be the result number (which is always     */
00065 /*    permitted).  Other than that case, operands must not overlap.   */
00066 /*                                                                    */
00067 /* 5. Error handling: the type of the error is ORed into the status   */
00068 /*    flags in the current context (decContext structure).  The       */
00069 /*    SIGFPE signal is then raised if the corresponding trap-enabler  */
00070 /*    flag in the decContext is set (is 1).                           */
00071 /*                                                                    */
00072 /*    It is the responsibility of the caller to clear the status      */
00073 /*    flags as required.                                              */
00074 /*                                                                    */
00075 /*    The result of any routine which returns a number will always    */
00076 /*    be a valid number (which may be a special value, such as an     */
00077 /*    Infinity or NaN).                                               */
00078 /*                                                                    */
00079 /* 6. The decNumber format is not an exchangeable concrete            */
00080 /*    representation as it comprises fields which may be machine-     */
00081 /*    dependent (packed or unpacked, or special length, for example). */
00082 /*    Canonical conversions to and from strings are provided; other   */
00083 /*    conversions are available in separate modules.                  */
00084 /*                                                                    */
00085 /* 7. Normally, input operands are assumed to be valid.  Set DECCHECK */
00086 /*    to 1 for extended operand checking (including NULL operands).   */
00087 /*    Results are undefined if a badly-formed structure (or a NULL    */
00088 /*    pointer to a structure) is provided, though with DECCHECK       */
00089 /*    enabled the operator routines are protected against exceptions. */
00090 /*    (Except if the result pointer is NULL, which is unrecoverable.) */
00091 /*                                                                    */
00092 /*    However, the routines will never cause exceptions if they are   */
00093 /*    given well-formed operands, even if the value of the operands   */
00094 /*    is inappropriate for the operation and DECCHECK is not set.     */
00095 /*    (Except for SIGFPE, as and where documented.)                   */
00096 /*                                                                    */
00097 /* 8. Subset arithmetic is available only if DECSUBSET is set to 1.   */
00098 /* ------------------------------------------------------------------ */
00099 /* Implementation notes for maintenance of this module:               */
00100 /*                                                                    */
00101 /* 1. Storage leak protection:  Routines which use malloc are not     */
00102 /*    permitted to use return for fastpath or error exits (i.e.,      */
00103 /*    they follow strict structured programming conventions).         */
00104 /*    Instead they have a do{}while(0); construct surrounding the     */
00105 /*    code which is protected -- break may be used to exit this.      */
00106 /*    Other routines can safely use the return statement inline.      */
00107 /*                                                                    */
00108 /*    Storage leak accounting can be enabled using DECALLOC.          */
00109 /*                                                                    */
00110 /* 2. All loops use the for(;;) construct.  Any do construct does     */
00111 /*    not loop; it is for allocation protection as just described.    */
00112 /*                                                                    */
00113 /* 3. Setting status in the context must always be the very last      */
00114 /*    action in a routine, as non-0 status may raise a trap and hence */
00115 /*    the call to set status may not return (if the handler uses long */
00116 /*    jump).  Therefore all cleanup must be done first.  In general,  */
00117 /*    to achieve this status is accumulated and is only applied just  */
00118 /*    before return by calling decContextSetStatus (via decStatus).   */
00119 /*                                                                    */
00120 /*    Routines which allocate storage cannot, in general, use the     */
00121 /*    'top level' routines which could cause a non-returning          */
00122 /*    transfer of control.  The decXxxxOp routines are safe (do not   */
00123 /*    call decStatus even if traps are set in the context) and should */
00124 /*    be used instead (they are also a little faster).                */
00125 /*                                                                    */
00126 /* 4. Exponent checking is minimized by allowing the exponent to      */
00127 /*    grow outside its limits during calculations, provided that      */
00128 /*    the decFinalize function is called later.  Multiplication and   */
00129 /*    division, and intermediate calculations in exponentiation,      */
00130 /*    require more careful checks because of the risk of 31-bit       */
00131 /*    overflow (the most negative valid exponent is -1999999997, for  */
00132 /*    a 999999999-digit number with adjusted exponent of -999999999). */
00133 /*                                                                    */
00134 /* 5. Rounding is deferred until finalization of results, with any    */
00135 /*    'off to the right' data being represented as a single digit     */
00136 /*    residue (in the range -1 through 9).  This avoids any double-   */
00137 /*    rounding when more than one shortening takes place (for         */
00138 /*    example, when a result is subnormal).                           */
00139 /*                                                                    */
00140 /* 6. The digits count is allowed to rise to a multiple of DECDPUN    */
00141 /*    during many operations, so whole Units are handled and exact    */
00142 /*    accounting of digits is not needed.  The correct digits value   */
00143 /*    is found by decGetDigits, which accounts for leading zeros.     */
00144 /*    This must be called before any rounding if the number of digits */
00145 /*    is not known exactly.                                           */
00146 /*                                                                    */
00147 /* 7. The multiply-by-reciprocal 'trick' is used for partitioning     */
00148 /*    numbers up to four digits, using appropriate constants.  This   */
00149 /*    is not useful for longer numbers because overflow of 32 bits    */
00150 /*    would lead to 4 multiplies, which is almost as expensive as     */
00151 /*    a divide (unless a floating-point or 64-bit multiply is         */
00152 /*    assumed to be available).                                       */
00153 /*                                                                    */
00154 /* 8. Unusual abbreviations that may be used in the commentary:       */
00155 /*      lhs -- left hand side (operand, of an operation)              */
00156 /*      lsd -- least significant digit (of coefficient)               */
00157 /*      lsu -- least significant Unit (of coefficient)                */
00158 /*      msd -- most significant digit (of coefficient)                */
00159 /*      msi -- most significant item (in an array)                    */
00160 /*      msu -- most significant Unit (of coefficient)                 */
00161 /*      rhs -- right hand side (operand, of an operation)             */
00162 /*      +ve -- positive                                               */
00163 /*      -ve -- negative                                               */
00164 /*      **  -- raise to the power                                     */
00165 /* ------------------------------------------------------------------ */
00166
00167 #include <stdlib.h>                // for malloc, free, etc.
00168 #include <stdio.h>                 // for printf [if needed]
00169 #include <string.h>                // for strcpy
00170 #include <ctype.h>                 // for lower
00171 #include "decNumber.h"             // base number library
00172 #include "decNumberLocal.h"        // decNumber local types, etc.
00173
00174 /* Constants */
00175 // Public lookup table used by the D2U macro
00176 const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
00177
00178 #define DECVERB     1              // set to 1 for verbose DECCHECK
00179 #define powers      DECPOWERS      // old internal name
00180
00181 // Local constants
00182 #define DIVIDE      0x80           // Divide operators
00183 #define REMAINDER   0x40           // ..
00184 #define DIVIDEINT   0x20           // ..
00185 #define REMNEAR     0x10           // ..
00186 #define COMPARE     0x01           // Compare operators
00187 #define COMPMAX     0x02           // ..
00188 #define COMPMIN     0x03           // ..
00189 #define COMPTOTAL   0x04           // ..
00190 #define COMPNAN     0x05           // .. [NaN processing]
00191 #define COMPSIG     0x06           // .. [signaling COMPARE]
00192 #define COMPMAXMAG  0x07           // ..
00193 #define COMPMINMAG  0x08           // ..
00194
00195 #define DEC_sNaN     0x40000000    // local status: sNaN signal
00196 #define BADINT  (Int)0x80000000    // most-negative Int; error indicator
00197 // Next two indicate an integer >= 10**6, and its parity (bottom bit)
00198 #define BIGEVEN (Int)0x80000002
00199 #define BIGODD  (Int)0x80000003
00200
00201 static Unit uarrone[1]={1};   // Unit array of 1, used for incrementing
00202
00203 /* Granularity-dependent code */
00204 #if DECDPUN<=4
00205   #define eInt  Int           // extended integer
00206   #define ueInt uInt          // unsigned extended integer
00207   // Constant multipliers for divide-by-power-of five using reciprocal
00208   // multiply, after removing powers of 2 by shifting, and final shift
00209   // of 17 [we only need up to **4]
00210   static const uInt multies[]={131073, 26215, 5243, 1049, 210};
00211   // QUOT10 -- macro to return the quotient of unit u divided by 10**n
00212   #define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
00213 #else
00214   // For DECDPUN>4 non-ANSI-89 64-bit types are needed.
00215   #if !DECUSE64
00216     #error decNumber.c: DECUSE64 must be 1 when DECDPUN>4
00217   #endif
00218   #define eInt  Long          // extended integer
00219   #define ueInt uLong         // unsigned extended integer
00220 #endif
00221
00222 /* Local routines */
00223 static decNumber * decAddOp(decNumber *, const decNumber *, const decNumber *,
00224                               decContext *, uByte, uInt *);
00225 static Flag        decBiStr(const char *, const char *, const char *);
00226 static uInt        decCheckMath(const decNumber *, decContext *, uInt *);
00227 static void        decApplyRound(decNumber *, decContext *, Int, uInt *);
00228 static Int         decCompare(const decNumber *lhs, const decNumber *rhs, Flag);
00229 static decNumber * decCompareOp(decNumber *, const decNumber *,
00230                               const decNumber *, decContext *,
00231                               Flag, uInt *);
00232 static void        decCopyFit(decNumber *, const decNumber *, decContext *,
00233                               Int *, uInt *);
00234 static decNumber * decDecap(decNumber *, Int);
00235 static decNumber * decDivideOp(decNumber *, const decNumber *,
00236                               const decNumber *, decContext *, Flag, uInt *);
00237 static decNumber * decExpOp(decNumber *, const decNumber *,
00238                               decContext *, uInt *);
00239 static void        decFinalize(decNumber *, decContext *, Int *, uInt *);
00240 static Int         decGetDigits(Unit *, Int);
00241 static Int         decGetInt(const decNumber *);
00242 static decNumber * decLnOp(decNumber *, const decNumber *,
00243                               decContext *, uInt *);
00244 static decNumber * decMultiplyOp(decNumber *, const decNumber *,
00245                               const decNumber *, decContext *,
00246                               uInt *);
00247 static decNumber * decNaNs(decNumber *, const decNumber *,
00248                               const decNumber *, decContext *, uInt *);
00249 static decNumber * decQuantizeOp(decNumber *, const decNumber *,
00250                               const decNumber *, decContext *, Flag,
00251                               uInt *);
00252 static void        decReverse(Unit *, Unit *);
00253 static void        decSetCoeff(decNumber *, decContext *, const Unit *,
00254                               Int, Int *, uInt *);
00255 static void        decSetMaxValue(decNumber *, decContext *);
00256 static void        decSetOverflow(decNumber *, decContext *, uInt *);
00257 static void        decSetSubnormal(decNumber *, decContext *, Int *, uInt *);
00258 static Int         decShiftToLeast(Unit *, Int, Int);
00259 static Int         decShiftToMost(Unit *, Int, Int);
00260 static void        decStatus(decNumber *, uInt, decContext *);
00261 static void        decToString(const decNumber *, char[], Flag);
00262 static decNumber * decTrim(decNumber *, decContext *, Flag, Flag, Int *);
00263 static Int         decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
00264                               Unit *, Int);
00265 static Int         decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
00266
00267 #if !DECSUBSET
00268 /* decFinish == decFinalize when no subset arithmetic needed */
00269 #define decFinish(a,b,c,d) decFinalize(a,b,c,d)
00270 #else
00271 static void        decFinish(decNumber *, decContext *, Int *, uInt *);
00272 static decNumber * decRoundOperand(const decNumber *, decContext *, uInt *);
00273 #endif
00274
00275 /* Local macros */
00276 // masked special-values bits
00277 #define SPECIALARG  (rhs->bits & DECSPECIAL)
00278 #define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)
00279
00280 /* Diagnostic macros, etc. */
00281 #if DECALLOC
00282 // Handle malloc/free accounting.  If enabled, our accountable routines
00283 // are used; otherwise the code just goes straight to the system malloc
00284 // and free routines.
00285 #define malloc(a) decMalloc(a)
00286 #define free(a) decFree(a)
00287 #define DECFENCE 0x5a              // corruption detector
00288 // 'Our' malloc and free:
00289 static void *decMalloc(size_t);
00290 static void  decFree(void *);
00291 uInt decAllocBytes=0;              // count of bytes allocated
00292 // Note that DECALLOC code only checks for storage buffer overflow.
00293 // To check for memory leaks, the decAllocBytes variable must be
00294 // checked to be 0 at appropriate times (e.g., after the test
00295 // harness completes a set of tests).  This checking may be unreliable
00296 // if the testing is done in a multi-thread environment.
00297 #endif
00298
00299 #if DECCHECK
00300 // Optional checking routines.  Enabling these means that decNumber
00301 // and decContext operands to operator routines are checked for
00302 // correctness.  This roughly doubles the execution time of the
00303 // fastest routines (and adds 600+ bytes), so should not normally be
00304 // used in 'production'.
00305 // decCheckInexact is used to check that inexact results have a full
00306 // complement of digits (where appropriate -- this is not the case
00307 // for Quantize, for example)
00308 #define DECUNRESU ((decNumber *)(void *)0xffffffff)
00309 #define DECUNUSED ((const decNumber *)(void *)0xffffffff)
00310 #define DECUNCONT ((decContext *)(void *)(0xffffffff))
00311 static Flag decCheckOperands(decNumber *, const decNumber *,
00312                              const decNumber *, decContext *);
00313 static Flag decCheckNumber(const decNumber *);
00314 static void decCheckInexact(const decNumber *, decContext *);
00315 #endif
00316
00317 #if DECTRACE || DECCHECK
00318 // Optional trace/debugging routines (may or may not be used)
00319 void decNumberShow(const decNumber *);  // displays the components of a number
00320 static void decDumpAr(char, const Unit *, Int);
00321 #endif
00322
00323 /* ================================================================== */
00324 /* Conversions                                                        */
00325 /* ================================================================== */
00326
00327 /* ------------------------------------------------------------------ */
00328 /* from-int32 -- conversion from Int or uInt                          */
00329 /*                                                                    */
00330 /*  dn is the decNumber to receive the integer                        */
00331 /*  in or uin is the integer to be converted                          */
00332 /*  returns dn                                                        */
00333 /*                                                                    */
00334 /* No error is possible.                                              */
00335 /* ------------------------------------------------------------------ */
00336 decNumber * decNumberFromInt32(decNumber *dn, Int in) {
00337   uInt unsig;
00338   if (in>=0) unsig=in;
00339    else {                               // negative (possibly BADINT)
00340     if (in==BADINT) unsig=(uInt)1073741824*2; // special case
00341      else unsig=-in;                    // invert
00342     }
00343   // in is now positive
00344   decNumberFromUInt32(dn, unsig);
00345   if (in<0) dn->bits=DECNEG;            // sign needed
00346   return dn;
00347   } // decNumberFromInt32
00348
00349 decNumber * decNumberFromUInt32(decNumber *dn, uInt uin) {
00350   Unit *up;                             // work pointer
00351   decNumberZero(dn);                    // clean
00352   if (uin==0) return dn;                // [or decGetDigits bad call]
00353   for (up=dn->lsu; uin>0; up++) {
00354     *up=(Unit)(uin%(DECDPUNMAX+1));
00355     uin=uin/(DECDPUNMAX+1);
00356     }
00357   dn->digits=decGetDigits(dn->lsu, up-dn->lsu);
00358   return dn;
00359   } // decNumberFromUInt32
00360
00361 /* ------------------------------------------------------------------ */
00362 /* to-int32 -- conversion to Int or uInt                              */
00363 /*                                                                    */
00364 /*  dn is the decNumber to convert                                    */
00365 /*  set is the context for reporting errors                           */
00366 /*  returns the converted decNumber, or 0 if Invalid is set           */
00367 /*                                                                    */
00368 /* Invalid is set if the decNumber does not have exponent==0 or if    */
00369 /* it is a NaN, Infinite, or out-of-range.                            */
00370 /* ------------------------------------------------------------------ */
00371 Int decNumberToInt32(const decNumber *dn, decContext *set) {
00372   #if DECCHECK
00373   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
00374   #endif
00375
00376   // special or too many digits, or bad exponent
00377   if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; // bad
00378    else { // is a finite integer with 10 or fewer digits
00379     Int d;                         // work
00380     const Unit *up;                // ..
00381     uInt hi=0, lo;                 // ..
00382     up=dn->lsu;                    // -> lsu
00383     lo=*up;                        // get 1 to 9 digits
00384     #if DECDPUN>1                  // split to higher
00385       hi=lo/10;
00386       lo=lo%10;
00387     #endif
00388     up++;
00389     // collect remaining Units, if any, into hi
00390     for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
00391     // now low has the lsd, hi the remainder
00392     if (hi>214748364 || (hi==214748364 && lo>7)) { // out of range?
00393       // most-negative is a reprieve
00394       if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000;
00395       // bad -- drop through
00396       }
00397      else { // in-range always
00398       Int i=X10(hi)+lo;
00399       if (dn->bits&DECNEG) return -i;
00400       return i;
00401       }
00402     } // integer
00403   decContextSetStatus(set, DEC_Invalid_operation); // [may not return]
00404   return 0;
00405   } // decNumberToInt32
00406
00407 uInt decNumberToUInt32(const decNumber *dn, decContext *set) {
00408   #if DECCHECK
00409   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
00410   #endif
00411   // special or too many digits, or bad exponent, or negative (<0)
00412   if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0
00413     || (dn->bits&DECNEG && !ISZERO(dn)));                   // bad
00414    else { // is a finite integer with 10 or fewer digits
00415     Int d;                         // work
00416     const Unit *up;                // ..
00417     uInt hi=0, lo;                 // ..
00418     up=dn->lsu;                    // -> lsu
00419     lo=*up;                        // get 1 to 9 digits
00420     #if DECDPUN>1                  // split to higher
00421       hi=lo/10;
00422       lo=lo%10;
00423     #endif
00424     up++;
00425     // collect remaining Units, if any, into hi
00426     for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
00427
00428     // now low has the lsd, hi the remainder
00429     if (hi>429496729 || (hi==429496729 && lo>5)) ; // no reprieve possible
00430      else return X10(hi)+lo;
00431     } // integer
00432   decContextSetStatus(set, DEC_Invalid_operation); // [may not return]
00433   return 0;
00434   } // decNumberToUInt32
00435
00436 /* ------------------------------------------------------------------ */
00437 /* to-scientific-string -- conversion to numeric string               */
00438 /* to-engineering-string -- conversion to numeric string              */
00439 /*                                                                    */
00440 /*   decNumberToString(dn, string);                                   */
00441 /*   decNumberToEngString(dn, string);                                */
00442 /*                                                                    */
00443 /*  dn is the decNumber to convert                                    */
00444 /*  string is the string where the result will be laid out            */
00445 /*                                                                    */
00446 /*  string must be at least dn->digits+14 characters long             */
00447 /*                                                                    */
00448 /*  No error is possible, and no status can be set.                   */
00449 /* ------------------------------------------------------------------ */
00450 char * decNumberToString(const decNumber *dn, char *string){
00451   decToString(dn, string, 0);
00452   return string;
00453   } // DecNumberToString
00454
00455 char * decNumberToEngString(const decNumber *dn, char *string){
00456   decToString(dn, string, 1);
00457   return string;
00458   } // DecNumberToEngString
00459
00460 /* ------------------------------------------------------------------ */
00461 /* to-number -- conversion from numeric string                        */
00462 /*                                                                    */
00463 /* decNumberFromString -- convert string to decNumber                 */
00464 /*   dn        -- the number structure to fill                        */
00465 /*   chars[]   -- the string to convert ('\0' terminated)             */
00466 /*   set       -- the context used for processing any error,          */
00467 /*                determining the maximum precision available         */
00468 /*                (set.digits), determining the maximum and minimum   */
00469 /*                exponent (set.emax and set.emin), determining if    */
00470 /*                extended values are allowed, and checking the       */
00471 /*                rounding mode if overflow occurs or rounding is     */
00472 /*                needed.                                             */
00473 /*                                                                    */
00474 /* The length of the coefficient and the size of the exponent are     */
00475 /* checked by this routine, so the correct error (Underflow or        */
00476 /* Overflow) can be reported or rounding applied, as necessary.       */
00477 /*                                                                    */
00478 /* If bad syntax is detected, the result will be a quiet NaN.         */
00479 /* ------------------------------------------------------------------ */
00480 decNumber * decNumberFromString(decNumber *dn, const char chars[],
00481                                 decContext *set) {
00482   Int   exponent=0;                // working exponent [assume 0]
00483   uByte bits=0;                    // working flags [assume +ve]
00484   Unit  *res;                      // where result will be built
00485   Unit  resbuff[SD2U(DECBUFFER+9)];// local buffer in case need temporary
00486                                    // [+9 allows for ln() constants]
00487   Unit  *allocres=NULL;            // -> allocated result, iff allocated
00488   Int   d=0;                       // count of digits found in decimal part
00489   const char *dotchar=NULL;        // where dot was found
00490   const char *cfirst=chars;        // -> first character of decimal part
00491   const char *last=NULL;           // -> last digit of decimal part
00492   const char *c;                   // work
00493   Unit  *up;                       // ..
00494   #if DECDPUN>1
00495   Int   cut, out;                  // ..
00496   #endif
00497   Int   residue;                   // rounding residue
00498   uInt  status=0;                  // error code
00499
00500   #if DECCHECK
00501   if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
00502     return decNumberZero(dn);
00503   #endif
00504
00505   do {                             // status & malloc protection
00506     for (c=chars;; c++) {          // -> input character
00507       if (*c>='0' && *c<='9') {    // test for Arabic digit
00508         last=c;
00509         d++;                       // count of real digits
00510         continue;                  // still in decimal part
00511         }
00512  // JPL french ------------------------------------------------------------
00513
00514  switch (_EnFr_){
00515
00516  case  DEC_English :    if (*c=='.' && dotchar==NULL) { // first '.'
00517         dotchar=c;                 // record offset into decimal part
00518         if (c==cfirst) cfirst++;   // first digit must follow
00519         continue;} break ;
00520  case   DEC_French :    if (*c==',' && dotchar==NULL) { // first ','
00521         dotchar=c;                 // record offset into decimal part
00522         if (c==cfirst) cfirst++;   // first digit must follow
00523         continue;} break ;
00524 // JPL french ------------------------------------------------------------
00525  }
00526
00527       if (c==chars) {              // first in string...
00528         if (*c=='-') {             // valid - sign
00529           cfirst++;
00530           bits=DECNEG;
00531           continue;}
00532         if (*c=='+') {             // valid + sign
00533           cfirst++;
00534           continue;}
00535         }
00536       // *c is not a digit, or a valid +, -, or '.'
00537       break;
00538       } // c
00539
00540     if (last==NULL) {              // no digits yet
00541       status=DEC_Conversion_syntax;// assume the worst
00542       if (*c=='\0') break;         // and no more to come...
00543       #if DECSUBSET
00544       // if subset then infinities and NaNs are not allowed
00545       if (!set->extended) break;   // hopeless
00546       #endif
00547       // Infinities and NaNs are possible, here
00548       if (dotchar!=NULL) break;    // .. unless had a dot
00549       decNumberZero(dn);           // be optimistic
00550       if (decBiStr(c, "infinity", "INFINITY")
00551        || decBiStr(c, "inf", "INF")) {
00552         dn->bits=bits | DECINF;
00553         status=0;                  // is OK
00554         break; // all done
00555         }
00556       // a NaN expected
00557       // 2003.09.10 NaNs are now permitted to have a sign
00558       dn->bits=bits | DECNAN;      // assume simple NaN
00559       if (*c=='s' || *c=='S') {    // looks like an sNaN
00560         c++;
00561         dn->bits=bits | DECSNAN;
00562         }
00563       if (*c!='n' && *c!='N') break;    // check caseless "NaN"
00564       c++;
00565       if (*c!='a' && *c!='A') break;    // ..
00566       c++;
00567       if (*c!='n' && *c!='N') break;    // ..
00568       c++;
00569       // now either nothing, or nnnn payload, expected
00570       // -> start of integer and skip leading 0s [including plain 0]
00571       for (cfirst=c; *cfirst=='0';) cfirst++;
00572       if (*cfirst=='\0') {         // "NaN" or "sNaN", maybe with all 0s
00573         status=0;                  // it's good
00574         break;                     // ..
00575         }
00576       // something other than 0s; setup last and d as usual [no dots]
00577       for (c=cfirst;; c++, d++) {
00578         if (*c<'0' || *c>'9') break; // test for Arabic digit
00579         last=c;
00580         }
00581       if (*c!='\0') break;         // not all digits
00582       if (d>set->digits-1) {
00583         // [NB: payload in a decNumber can be full length unless
00584         // clamped, in which case can only be digits-1]
00585         if (set->clamp) break;
00586         if (d>set->digits) break;
00587         } // too many digits?
00588       // good; drop through to convert the integer to coefficient
00589       status=0;                    // syntax is OK
00590       bits=dn->bits;               // for copy-back
00591       } // last==NULL
00592
00593      else if (*c!='\0') {          // more to process...
00594       // had some digits; exponent is only valid sequence now
00595       Flag nege;                   // 1=negative exponent
00596       const char *firstexp;        // -> first significant exponent digit
00597       status=DEC_Conversion_syntax;// assume the worst
00598       if (*c!='e' && *c!='E') break;
00599       /* Found 'e' or 'E' -- now process explicit exponent */
00600       // 1998.07.11: sign no longer required
00601       nege=0;
00602       c++;                         // to (possible) sign
00603
00604       if (*c=='-') {nege=1; c++;}
00605           else if (*c=='+') c++;
00606       if (*c=='\0') break;
00607
00608
00609       for (; *c=='0' && *(c+1)!='\0';) c++;  // strip insignificant zeros
00610       firstexp=c;                            // save exponent digit place
00611       for (; ;c++) {
00612         if (*c<'0' || *c>'9') break;         // not a digit
00613         exponent=X10(exponent)+(Int)*c-(Int)'0';
00614         } // c
00615       // if not now on a '\0', *c must not be a digit
00616       if (*c!='\0') break;
00617
00618       // (this next test must be after the syntax checks)
00619       // if it was too long the exponent may have wrapped, so check
00620       // carefully and set it to a certain overflow if wrap possible
00621       if (c>=firstexp+9+1) {
00622         if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2;
00623         // [up to 1999999999 is OK, for example 1E-1000000998]
00624         }
00625       if (nege) exponent=-exponent;     // was negative
00626       status=0;                         // is OK
00627       } // stuff after digits
00628
00629     // Here when whole string has been inspected; syntax is good
00630     // cfirst->first digit (never dot), last->last digit (ditto)
00631
00632     // strip leading zeros/dot [leave final 0 if all 0's]
00633     if (*cfirst=='0') {                 // [cfirst has stepped over .]
00634       for (c=cfirst; c<last; c++, cfirst++) {
00635 // JPL-------------------------------------------------------------------
00636         if (*c=='.' && _EnFr_ == DEC_English) continue;          // ignore dots
00637         if (*c==',' && _EnFr_ == DEC_French) continue;          // ignore dots
00638 // JPL-------------------------------------------------------------------
00639         if (*c!='0') break;             // non-zero found
00640         d--;                            // 0 stripped
00641         } // c
00642       #if DECSUBSET
00643       // make a rapid exit for easy zeros if !extended
00644       if (*cfirst=='0' && !set->extended) {
00645         decNumberZero(dn);              // clean result
00646         break;                          // [could be return]
00647         }
00648       #endif
00649       } // at least one leading 0
00650
00651     // Handle decimal point...
00652     if (dotchar!=NULL && dotchar<last)  // non-trailing '.' found?
00653       exponent-=(last-dotchar);         // adjust exponent
00654     // [we can now ignore the .]
00655
00656     // OK, the digits string is good.  Assemble in the decNumber, or in
00657     // a temporary units array if rounding is needed
00658     if (d<=set->digits) res=dn->lsu;    // fits into supplied decNumber
00659      else {                             // rounding needed
00660       Int needbytes=D2U(d)*sizeof(Unit);// bytes needed
00661       res=resbuff;                      // assume use local buffer
00662       if (needbytes>(Int)sizeof(resbuff)) { // too big for local
00663         allocres=(Unit *)malloc(needbytes);
00664         if (allocres==NULL) {status|=DEC_Insufficient_storage; break;}
00665         res=allocres;
00666         }
00667       }
00668     // res now -> number lsu, buffer, or allocated storage for Unit array
00669
00670     // Place the coefficient into the selected Unit array
00671     // [this is often 70% of the cost of this function when DECDPUN>1]
00672     #if DECDPUN>1
00673     out=0;                         // accumulator
00674     up=res+D2U(d)-1;               // -> msu
00675     cut=d-(up-res)*DECDPUN;        // digits in top unit
00676     for (c=cfirst;; c++) {         // along the digits
00677 // JPL ----------------------------------------------------------------------------
00678       if (*c=='.' && _EnFr_ ==DEC_English ) continue;       // ignore '.' [don't decrement cut]
00679       if (*c==',' && _EnFr_ ==DEC_French ) continue;       // ignore ',' [don't decrement cut]
00680 // JPL ----------------------------------------------------------------------------
00681       out=X10(out)+(Int)*c-(Int)'0';
00682       if (c==last) break;          // done [never get to trailing '.']
00683       cut--;
00684       if (cut>0) continue;         // more for this unit
00685       *up=(Unit)out;               // write unit
00686       up--;                        // prepare for unit below..
00687       cut=DECDPUN;                 // ..
00688       out=0;                       // ..
00689       } // c
00690     *up=(Unit)out;                 // write lsu
00691
00692     #else
00693     // DECDPUN==1
00694     up=res;                        // -> lsu
00695     for (c=last; c>=cfirst; c--) { // over each character, from least
00696   switch (_EnFr_){
00697
00698  case  DEC_English :
00699       if (*c=='.') continue; break;      // ignore . [don't step up]
00700
00701 // JPL french ------------------------------------------------------------
00702  case  DEC_French :
00703            if (*c==',') continue;  break     // ignore . [don't step up]
00704 // JPL french ------------------------------------------------------------
00705   }
00706       *up=(Unit)((Int)*c-(Int)'0');
00707       up++;
00708       } // c
00709     #endif
00710
00711     dn->bits=bits;
00712     dn->exponent=exponent;
00713     dn->digits=d;
00714
00715     // if not in number (too long) shorten into the number
00716     if (d>set->digits) {
00717       residue=0;
00718       decSetCoeff(dn, set, res, d, &residue, &status);
00719       // always check for overflow or subnormal and round as needed
00720       decFinalize(dn, set, &residue, &status);
00721       }
00722      else { // no rounding, but may still have overflow or subnormal
00723       // [these tests are just for performance; finalize repeats them]
00724       if ((dn->exponent-1<set->emin-dn->digits)
00725        || (dn->exponent-1>set->emax-set->digits)) {
00726         residue=0;
00727         decFinalize(dn, set, &residue, &status);
00728         }
00729       }
00730     // decNumberShow(dn);
00731     } while(0);                         // [for break]
00732
00733   if (allocres!=NULL) free(allocres);   // drop any storage used
00734   if (status!=0) decStatus(dn, status, set);
00735   return dn;
00736   } /* decNumberFromString */
00737
00738 /* ================================================================== */
00739 /* Operators                                                          */
00740 /* ================================================================== */
00741
00742 /* ------------------------------------------------------------------ */
00743 /* decNumberAbs -- absolute value operator                            */
00744 /*                                                                    */
00745 /*   This computes C = abs(A)                                         */
00746 /*                                                                    */
00747 /*   res is C, the result.  C may be A                                */
00748 /*   rhs is A                                                         */
00749 /*   set is the context                                               */
00750 /*                                                                    */
00751 /* See also decNumberCopyAbs for a quiet bitwise version of this.     */
00752 /* C must have space for set->digits digits.                          */
00753 /* ------------------------------------------------------------------ */
00754 /* This has the same effect as decNumberPlus unless A is negative,    */
00755 /* in which case it has the same effect as decNumberMinus.            */
00756 /* ------------------------------------------------------------------ */
00757 decNumber * decNumberAbs(decNumber *res, const decNumber *rhs,
00758                          decContext *set) {
00759   decNumber dzero;                      // for 0
00760   uInt status=0;                        // accumulator
00761
00762   #if DECCHECK
00763   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
00764   #endif
00765
00766   decNumberZero(&dzero);                // set 0
00767   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
00768   decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
00769   if (status!=0) decStatus(res, status, set);
00770   #if DECCHECK
00771   decCheckInexact(res, set);
00772   #endif
00773   return res;
00774   } // decNumberAbs
00775
00776 /* ------------------------------------------------------------------ */
00777 /* decNumberAdd -- add two Numbers                                    */
00778 /*                                                                    */
00779 /*   This computes C = A + B                                          */
00780 /*                                                                    */
00781 /*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
00782 /*   lhs is A                                                         */
00783 /*   rhs is B                                                         */
00784 /*   set is the context                                               */
00785 /*                                                                    */
00786 /* C must have space for set->digits digits.                          */
00787 /* ------------------------------------------------------------------ */
00788 /* This just calls the routine shared with Subtract                   */
00789 decNumber * decNumberAdd(decNumber *res, const decNumber *lhs,
00790                          const decNumber *rhs, decContext *set) {
00791   uInt status=0;                        // accumulator
00792   decAddOp(res, lhs, rhs, set, 0, &status);
00793   if (status!=0) decStatus(res, status, set);
00794   #if DECCHECK
00795   decCheckInexact(res, set);
00796   #endif
00797   return res;
00798   } // decNumberAdd
00799
00800 /* ------------------------------------------------------------------ */
00801 /* decNumberAnd -- AND two Numbers, digitwise                         */
00802 /*                                                                    */
00803 /*   This computes C = A & B                                          */
00804 /*                                                                    */
00805 /*   res is C, the result.  C may be A and/or B (e.g., X=X&X)         */
00806 /*   lhs is A                                                         */
00807 /*   rhs is B                                                         */
00808 /*   set is the context (used for result length and error report)     */
00809 /*                                                                    */
00810 /* C must have space for set->digits digits.                          */
00811 /*                                                                    */
00812 /* Logical function restrictions apply (see above); a NaN is          */
00813 /* returned with Invalid_operation if a restriction is violated.      */
00814 /* ------------------------------------------------------------------ */
00815 decNumber * decNumberAnd(decNumber *res, const decNumber *lhs,
00816                          const decNumber *rhs, decContext *set) {
00817   const Unit *ua, *ub;                  // -> operands
00818   const Unit *msua, *msub;              // -> operand msus
00819   Unit *uc,  *msuc;                     // -> result and its msu
00820   Int   msudigs;                        // digits in res msu
00821   #if DECCHECK
00822   if (decCheckOperands(res, lhs, rhs, set)) return res;
00823   #endif
00824
00825   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
00826    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
00827     decStatus(res, DEC_Invalid_operation, set);
00828     return res;
00829     }
00830
00831   // operands are valid
00832   ua=lhs->lsu;                          // bottom-up
00833   ub=rhs->lsu;                          // ..
00834   uc=res->lsu;                          // ..
00835   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
00836   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
00837   msuc=uc+D2U(set->digits)-1;           // -> msu of result
00838   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
00839   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
00840     Unit a, b;                          // extract units
00841     if (ua>msua) a=0;
00842      else a=*ua;
00843     if (ub>msub) b=0;
00844      else b=*ub;
00845     *uc=0;                              // can now write back
00846     if (a|b) {                          // maybe 1 bits to examine
00847       Int i, j;
00848       *uc=0;                            // can now write back
00849       // This loop could be unrolled and/or use BIN2BCD tables
00850       for (i=0; i<DECDPUN; i++) {
00851         if (a&b&1) *uc=*uc+(Unit)powers[i];  // effect AND
00852         j=a%10;
00853         a=a/10;
00854         j|=b%10;
00855         b=b/10;
00856         if (j>1) {
00857           decStatus(res, DEC_Invalid_operation, set);
00858           return res;
00859           }
00860         if (uc==msuc && i==msudigs-1) break; // just did final digit
00861         } // each digit
00862       } // both OK
00863     } // each unit
00864   // [here uc-1 is the msu of the result]
00865   res->digits=decGetDigits(res->lsu, uc-res->lsu);
00866   res->exponent=0;                      // integer
00867   res->bits=0;                          // sign=0
00868   return res;  // [no status to set]
00869   } // decNumberAnd
00870
00871 /* ------------------------------------------------------------------ */
00872 /* decNumberCompare -- compare two Numbers                            */
00873 /*                                                                    */
00874 /*   This computes C = A ? B                                          */
00875 /*                                                                    */
00876 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
00877 /*   lhs is A                                                         */
00878 /*   rhs is B                                                         */
00879 /*   set is the context                                               */
00880 /*                                                                    */
00881 /* C must have space for one digit (or NaN).                          */
00882 /* ------------------------------------------------------------------ */
00883 decNumber * decNumberCompare(decNumber *res, const decNumber *lhs,
00884                              const decNumber *rhs, decContext *set) {
00885   uInt status=0;                        // accumulator
00886   decCompareOp(res, lhs, rhs, set, COMPARE, &status);
00887   if (status!=0) decStatus(res, status, set);
00888   return res;
00889   } // decNumberCompare
00890
00891 /* ------------------------------------------------------------------ */
00892 /* decNumberCompareSignal -- compare, signalling on all NaNs          */
00893 /*                                                                    */
00894 /*   This computes C = A ? B                                          */
00895 /*                                                                    */
00896 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
00897 /*   lhs is A                                                         */
00898 /*   rhs is B                                                         */
00899 /*   set is the context                                               */
00900 /*                                                                    */
00901 /* C must have space for one digit (or NaN).                          */
00902 /* ------------------------------------------------------------------ */
00903 decNumber * decNumberCompareSignal(decNumber *res, const decNumber *lhs,
00904                                    const decNumber *rhs, decContext *set) {
00905   uInt status=0;                        // accumulator
00906   decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
00907   if (status!=0) decStatus(res, status, set);
00908   return res;
00909   } // decNumberCompareSignal
00910
00911 /* ------------------------------------------------------------------ */
00912 /* decNumberCompareTotal -- compare two Numbers, using total ordering */
00913 /*                                                                    */
00914 /*   This computes C = A ? B, under total ordering                    */
00915 /*                                                                    */
00916 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
00917 /*   lhs is A                                                         */
00918 /*   rhs is B                                                         */
00919 /*   set is the context                                               */
00920 /*                                                                    */
00921 /* C must have space for one digit; the result will always be one of  */
00922 /* -1, 0, or 1.                                                       */
00923 /* ------------------------------------------------------------------ */
00924 decNumber * decNumberCompareTotal(decNumber *res, const decNumber *lhs,
00925                                   const decNumber *rhs, decContext *set) {
00926   uInt status=0;                        // accumulator
00927   decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
00928   if (status!=0) decStatus(res, status, set);
00929   return res;
00930   } // decNumberCompareTotal
00931
00932 /* ------------------------------------------------------------------ */
00933 /* decNumberCompareTotalMag -- compare, total ordering of magnitudes  */
00934 /*                                                                    */
00935 /*   This computes C = |A| ? |B|, under total ordering                */
00936 /*                                                                    */
00937 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
00938 /*   lhs is A                                                         */
00939 /*   rhs is B                                                         */
00940 /*   set is the context                                               */
00941 /*                                                                    */
00942 /* C must have space for one digit; the result will always be one of  */
00943 /* -1, 0, or 1.                                                       */
00944 /* ------------------------------------------------------------------ */
00945 decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
00946                                      const decNumber *rhs, decContext *set) {
00947   uInt status=0;                   // accumulator
00948   uInt needbytes;                  // for space calculations
00949   decNumber bufa[D2N(DECBUFFER+1)];// +1 in case DECBUFFER=0
00950   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
00951   decNumber bufb[D2N(DECBUFFER+1)];
00952   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
00953   decNumber *a, *b;                // temporary pointers
00954
00955   #if DECCHECK
00956   if (decCheckOperands(res, lhs, rhs, set)) return res;
00957   #endif
00958
00959   do {                                  // protect allocated storage
00960     // if either is negative, take a copy and absolute
00961     if (decNumberIsNegative(lhs)) {     // lhs<0
00962       a=bufa;
00963       needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit);
00964       if (needbytes>sizeof(bufa)) {     // need malloc space
00965         allocbufa=(decNumber *)malloc(needbytes);
00966         if (allocbufa==NULL) {          // hopeless -- abandon
00967           status|=DEC_Insufficient_storage;
00968           break;}
00969         a=allocbufa;                    // use the allocated space
00970         }
00971       decNumberCopy(a, lhs);            // copy content
00972       a->bits&=~DECNEG;                 // .. and clear the sign
00973       lhs=a;                            // use copy from here on
00974       }
00975     if (decNumberIsNegative(rhs)) {     // rhs<0
00976       b=bufb;
00977       needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
00978       if (needbytes>sizeof(bufb)) {     // need malloc space
00979         allocbufb=(decNumber *)malloc(needbytes);
00980         if (allocbufb==NULL) {          // hopeless -- abandon
00981           status|=DEC_Insufficient_storage;
00982           break;}
00983         b=allocbufb;                    // use the allocated space
00984         }
00985       decNumberCopy(b, rhs);            // copy content
00986       b->bits&=~DECNEG;                 // .. and clear the sign
00987       rhs=b;                            // use copy from here on
00988       }
00989     decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
00990     } while(0);                         // end protected
00991
00992   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
00993   if (allocbufb!=NULL) free(allocbufb); // ..
00994   if (status!=0) decStatus(res, status, set);
00995   return res;
00996   } // decNumberCompareTotalMag
00997
00998 /* ------------------------------------------------------------------ */
00999 /* decNumberDivide -- divide one number by another                    */
01000 /*                                                                    */
01001 /*   This computes C = A / B                                          */
01002 /*                                                                    */
01003 /*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
01004 /*   lhs is A                                                         */
01005 /*   rhs is B                                                         */
01006 /*   set is the context                                               */
01007 /*                                                                    */
01008 /* C must have space for set->digits digits.                          */
01009 /* ------------------------------------------------------------------ */
01010 decNumber * decNumberDivide(decNumber *res, const decNumber *lhs,
01011                             const decNumber *rhs, decContext *set) {
01012   uInt status=0;                        // accumulator
01013   decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
01014   if (status!=0) decStatus(res, status, set);
01015   #if DECCHECK
01016   decCheckInexact(res, set);
01017   #endif
01018   return res;
01019   } // decNumberDivide
01020
01021 /* ------------------------------------------------------------------ */
01022 /* decNumberDivideInteger -- divide and return integer quotient       */
01023 /*                                                                    */
01024 /*   This computes C = A # B, where # is the integer divide operator  */
01025 /*                                                                    */
01026 /*   res is C, the result.  C may be A and/or B (e.g., X=X#X)         */
01027 /*   lhs is A                                                         */
01028 /*   rhs is B                                                         */
01029 /*   set is the context                                               */
01030 /*                                                                    */
01031 /* C must have space for set->digits digits.                          */
01032 /* ------------------------------------------------------------------ */
01033 decNumber * decNumberDivideInteger(decNumber *res, const decNumber *lhs,
01034                                    const decNumber *rhs, decContext *set) {
01035   uInt status=0;                        // accumulator
01036   decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
01037   if (status!=0) decStatus(res, status, set);
01038   return res;
01039   } // decNumberDivideInteger
01040
01041 /* ------------------------------------------------------------------ */
01042 /* decNumberExp -- exponentiation                                     */
01043 /*                                                                    */
01044 /*   This computes C = exp(A)                                         */
01045 /*                                                                    */
01046 /*   res is C, the result.  C may be A                                */
01047 /*   rhs is A                                                         */
01048 /*   set is the context; note that rounding mode has no effect        */
01049 /*                                                                    */
01050 /* C must have space for set->digits digits.                          */
01051 /*                                                                    */
01052 /* Mathematical function restrictions apply (see above); a NaN is     */
01053 /* returned with Invalid_operation if a restriction is violated.      */
01054 /*                                                                    */
01055 /* Finite results will always be full precision and Inexact, except   */
01056 /* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
01057 /*                                                                    */
01058 /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
01059 /* almost always be correctly rounded, but may be up to 1 ulp in      */
01060 /* error in rare cases.                                               */
01061 /* ------------------------------------------------------------------ */
01062 /* This is a wrapper for decExpOp which can handle the slightly wider */
01063 /* (double) range needed by Ln (which has to be able to calculate     */
01064 /* exp(-a) where a can be the tiniest number (Ntiny).                 */
01065 /* ------------------------------------------------------------------ */
01066 decNumber * decNumberExp(decNumber *res, const decNumber *rhs,
01067                          decContext *set) {
01068   uInt status=0;                        // accumulator
01069   #if DECSUBSET
01070   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01071   #endif
01072
01073   #if DECCHECK
01074   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01075   #endif
01076
01077   // Check restrictions; these restrictions ensure that if h=8 (see
01078   // decExpOp) then the result will either overflow or underflow to 0.
01079   // Other math functions restrict the input range, too, for inverses.
01080   // If not violated then carry out the operation.
01081   if (!decCheckMath(rhs, set, &status)) do { // protect allocation
01082     #if DECSUBSET
01083     if (!set->extended) {
01084       // reduce operand and set lostDigits status, as needed
01085       if (rhs->digits>set->digits) {
01086         allocrhs=decRoundOperand(rhs, set, &status);
01087         if (allocrhs==NULL) break;
01088         rhs=allocrhs;
01089         }
01090       }
01091     #endif
01092     decExpOp(res, rhs, set, &status);
01093     } while(0);                         // end protected
01094
01095   #if DECSUBSET
01096   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
01097   #endif
01098   // apply significant status
01099   if (status!=0) decStatus(res, status, set);
01100   #if DECCHECK
01101   decCheckInexact(res, set);
01102   #endif
01103   return res;
01104   } // decNumberExp
01105
01106 /* ------------------------------------------------------------------ */
01107 /* decNumberFMA -- fused multiply add                                 */
01108 /*                                                                    */
01109 /*   This computes D = (A * B) + C with only one rounding             */
01110 /*                                                                    */
01111 /*   res is D, the result.  D may be A or B or C (e.g., X=FMA(X,X,X)) */
01112 /*   lhs is A                                                         */
01113 /*   rhs is B                                                         */
01114 /*   fhs is C [far hand side]                                         */
01115 /*   set is the context                                               */
01116 /*                                                                    */
01117 /* Mathematical function restrictions apply (see above); a NaN is     */
01118 /* returned with Invalid_operation if a restriction is violated.      */
01119 /*                                                                    */
01120 /* C must have space for set->digits digits.                          */
01121 /* ------------------------------------------------------------------ */
01122 decNumber * decNumberFMA(decNumber *res, const decNumber *lhs,
01123                          const decNumber *rhs, const decNumber *fhs,
01124                          decContext *set) {
01125   uInt status=0;                   // accumulator
01126   decContext dcmul;                // context for the multiplication
01127   uInt needbytes;                  // for space calculations
01128   decNumber bufa[D2N(DECBUFFER*2+1)];
01129   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
01130   decNumber *acc;                  // accumulator pointer
01131   decNumber dzero;                 // work
01132
01133   #if DECCHECK
01134   if (decCheckOperands(res, lhs, rhs, set)) return res;
01135   if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;
01136   #endif
01137
01138   do {                                  // protect allocated storage
01139     #if DECSUBSET
01140     if (!set->extended) {               // [undefined if subset]
01141       status|=DEC_Invalid_operation;
01142       break;}
01143     #endif
01144     // Check math restrictions [these ensure no overflow or underflow]
01145     if ((!decNumberIsSpecial(lhs) && decCheckMath(lhs, set, &status))
01146      || (!decNumberIsSpecial(rhs) && decCheckMath(rhs, set, &status))
01147      || (!decNumberIsSpecial(fhs) && decCheckMath(fhs, set, &status))) break;
01148     // set up context for multiply
01149     dcmul=*set;
01150     dcmul.digits=lhs->digits+rhs->digits; // just enough
01151     // [The above may be an over-estimate for subset arithmetic, but that's OK]
01152     dcmul.emax=DEC_MAX_EMAX;            // effectively unbounded ..
01153     dcmul.emin=DEC_MIN_EMIN;            // [thanks to Math restrictions]
01154     // set up decNumber space to receive the result of the multiply
01155     acc=bufa;                           // may fit
01156     needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit);
01157     if (needbytes>sizeof(bufa)) {       // need malloc space
01158       allocbufa=(decNumber *)malloc(needbytes);
01159       if (allocbufa==NULL) {            // hopeless -- abandon
01160         status|=DEC_Insufficient_storage;
01161         break;}
01162       acc=allocbufa;                    // use the allocated space
01163       }
01164     // multiply with extended range and necessary precision
01165     //printf("emin=%ld\n", dcmul.emin);
01166     decMultiplyOp(acc, lhs, rhs, &dcmul, &status);
01167     // Only Invalid operation (from sNaN or Inf * 0) is possible in
01168     // status; if either is seen than ignore fhs (in case it is
01169     // another sNaN) and set acc to NaN unless we had an sNaN
01170     // [decMultiplyOp leaves that to caller]
01171     // Note sNaN has to go through addOp to shorten payload if
01172     // necessary
01173     if ((status&DEC_Invalid_operation)!=0) {
01174       if (!(status&DEC_sNaN)) {         // but be true invalid
01175         decNumberZero(res);             // acc not yet set
01176         res->bits=DECNAN;
01177         break;
01178         }
01179       decNumberZero(&dzero);            // make 0 (any non-NaN would do)
01180       fhs=&dzero;                       // use that
01181       }
01182     #if DECCHECK
01183      else { // multiply was OK
01184       if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
01185       }
01186     #endif
01187     // add the third operand and result -> res, and all is done
01188     decAddOp(res, acc, fhs, set, 0, &status);
01189     } while(0);                         // end protected
01190
01191   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
01192   if (status!=0) decStatus(res, status, set);
01193   #if DECCHECK
01194   decCheckInexact(res, set);
01195   #endif
01196   return res;
01197   } // decNumberFMA
01198
01199 /* ------------------------------------------------------------------ */
01200 /* decNumberInvert -- invert a Number, digitwise                      */
01201 /*                                                                    */
01202 /*   This computes C = ~A                                             */
01203 /*                                                                    */
01204 /*   res is C, the result.  C may be A (e.g., X=~X)                   */
01205 /*   rhs is A                                                         */
01206 /*   set is the context (used for result length and error report)     */
01207 /*                                                                    */
01208 /* C must have space for set->digits digits.                          */
01209 /*                                                                    */
01210 /* Logical function restrictions apply (see above); a NaN is          */
01211 /* returned with Invalid_operation if a restriction is violated.      */
01212 /* ------------------------------------------------------------------ */
01213 decNumber * decNumberInvert(decNumber *res, const decNumber *rhs,
01214                             decContext *set) {
01215   const Unit *ua, *msua;                // -> operand and its msu
01216   Unit  *uc, *msuc;                     // -> result and its msu
01217   Int   msudigs;                        // digits in res msu
01218   #if DECCHECK
01219   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01220   #endif
01221
01222   if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
01223     decStatus(res, DEC_Invalid_operation, set);
01224     return res;
01225     }
01226   // operand is valid
01227   ua=rhs->lsu;                          // bottom-up
01228   uc=res->lsu;                          // ..
01229   msua=ua+D2U(rhs->digits)-1;           // -> msu of rhs
01230   msuc=uc+D2U(set->digits)-1;           // -> msu of result
01231   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
01232   for (; uc<=msuc; ua++, uc++) {        // Unit loop
01233     Unit a;                             // extract unit
01234     Int  i, j;                          // work
01235     if (ua>msua) a=0;
01236      else a=*ua;
01237     *uc=0;                              // can now write back
01238     // always need to examine all bits in rhs
01239     // This loop could be unrolled and/or use BIN2BCD tables
01240     for (i=0; i<DECDPUN; i++) {
01241       if ((~a)&1) *uc=*uc+(Unit)powers[i];   // effect INVERT
01242       j=a%10;
01243       a=a/10;
01244       if (j>1) {
01245         decStatus(res, DEC_Invalid_operation, set);
01246         return res;
01247         }
01248       if (uc==msuc && i==msudigs-1) break;   // just did final digit
01249       } // each digit
01250     } // each unit
01251   // [here uc-1 is the msu of the result]
01252   res->digits=decGetDigits(res->lsu, uc-res->lsu);
01253   res->exponent=0;                      // integer
01254   res->bits=0;                          // sign=0
01255   return res;  // [no status to set]
01256   } // decNumberInvert
01257
01258 /* ------------------------------------------------------------------ */
01259 /* decNumberLn -- natural logarithm                                   */
01260 /*                                                                    */
01261 /*   This computes C = ln(A)                                          */
01262 /*                                                                    */
01263 /*   res is C, the result.  C may be A                                */
01264 /*   rhs is A                                                         */
01265 /*   set is the context; note that rounding mode has no effect        */
01266 /*                                                                    */
01267 /* C must have space for set->digits digits.                          */
01268 /*                                                                    */
01269 /* Notable cases:                                                     */
01270 /*   A<0 -> Invalid                                                   */
01271 /*   A=0 -> -Infinity (Exact)                                         */
01272 /*   A=+Infinity -> +Infinity (Exact)                                 */
01273 /*   A=1 exactly -> 0 (Exact)                                         */
01274 /*                                                                    */
01275 /* Mathematical function restrictions apply (see above); a NaN is     */
01276 /* returned with Invalid_operation if a restriction is violated.      */
01277 /*                                                                    */
01278 /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
01279 /* almost always be correctly rounded, but may be up to 1 ulp in      */
01280 /* error in rare cases.                                               */
01281 /* ------------------------------------------------------------------ */
01282 /* This is a wrapper for decLnOp which can handle the slightly wider  */
01283 /* (+11) range needed by Ln, Log10, etc. (which may have to be able   */
01284 /* to calculate at p+e+2).                                            */
01285 /* ------------------------------------------------------------------ */
01286 decNumber * decNumberLn(decNumber *res, const decNumber *rhs,
01287                         decContext *set) {
01288   uInt status=0;                   // accumulator
01289   #if DECSUBSET
01290   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01291   #endif
01292
01293   #if DECCHECK
01294   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01295   #endif
01296
01297   // Check restrictions; this is a math function; if not violated
01298   // then carry out the operation.
01299   if (!decCheckMath(rhs, set, &status)) do { // protect allocation
01300     #if DECSUBSET
01301     if (!set->extended) {
01302       // reduce operand and set lostDigits status, as needed
01303       if (rhs->digits>set->digits) {
01304         allocrhs=decRoundOperand(rhs, set, &status);
01305         if (allocrhs==NULL) break;
01306         rhs=allocrhs;
01307         }
01308       // special check in subset for rhs=0
01309       if (ISZERO(rhs)) {                // +/- zeros -> error
01310         status|=DEC_Invalid_operation;
01311         break;}
01312       } // extended=0
01313     #endif
01314     decLnOp(res, rhs, set, &status);
01315     } while(0);                         // end protected
01316
01317   #if DECSUBSET
01318   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
01319   #endif
01320   // apply significant status
01321   if (status!=0) decStatus(res, status, set);
01322   #if DECCHECK
01323   decCheckInexact(res, set);
01324   #endif
01325   return res;
01326   } // decNumberLn
01327
01328 /* ------------------------------------------------------------------ */
01329 /* decNumberLogB - get adjusted exponent, by 754 rules                */
01330 /*                                                                    */
01331 /*   This computes C = adjustedexponent(A)                            */
01332 /*                                                                    */
01333 /*   res is C, the result.  C may be A                                */
01334 /*   rhs is A                                                         */
01335 /*   set is the context, used only for digits and status              */
01336 /*                                                                    */
01337 /* C must have space for 10 digits (A might have 10**9 digits and     */
01338 /* an exponent of +999999999, or one digit and an exponent of         */
01339 /* -1999999999).                                                      */
01340 /*                                                                    */
01341 /* This returns the adjusted exponent of A after (in theory) padding  */
01342 /* with zeros on the right to set->digits digits while keeping the    */
01343 /* same value.  The exponent is not limited by emin/emax.             */
01344 /*                                                                    */
01345 /* Notable cases:                                                     */
01346 /*   A<0 -> Use |A|                                                   */
01347 /*   A=0 -> -Infinity (Division by zero)                              */
01348 /*   A=Infinite -> +Infinity (Exact)                                  */
01349 /*   A=1 exactly -> 0 (Exact)                                         */
01350 /*   NaNs are propagated as usual                                     */
01351 /* ------------------------------------------------------------------ */
01352 decNumber * decNumberLogB(decNumber *res, const decNumber *rhs,
01353                           decContext *set) {
01354   uInt status=0;                   // accumulator
01355
01356   #if DECCHECK
01357   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01358   #endif
01359
01360   // NaNs as usual; Infinities return +Infinity; 0->oops
01361   if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);
01362    else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs);
01363    else if (decNumberIsZero(rhs)) {
01364     decNumberZero(res);                 // prepare for Infinity
01365     res->bits=DECNEG|DECINF;            // -Infinity
01366     status|=DEC_Division_by_zero;       // as per 754
01367     }
01368    else { // finite non-zero
01369     Int ae=rhs->exponent+rhs->digits-1; // adjusted exponent
01370     decNumberFromInt32(res, ae);        // lay it out
01371     }
01372
01373   if (status!=0) decStatus(res, status, set);
01374   return res;
01375   } // decNumberLogB
01376
01377 /* ------------------------------------------------------------------ */
01378 /* decNumberLog10 -- logarithm in base 10                             */
01379 /*                                                                    */
01380 /*   This computes C = log10(A)                                       */
01381 /*                                                                    */
01382 /*   res is C, the result.  C may be A                                */
01383 /*   rhs is A                                                         */
01384 /*   set is the context; note that rounding mode has no effect        */
01385 /*                                                                    */
01386 /* C must have space for set->digits digits.                          */
01387 /*                                                                    */
01388 /* Notable cases:                                                     */
01389 /*   A<0 -> Invalid                                                   */
01390 /*   A=0 -> -Infinity (Exact)                                         */
01391 /*   A=+Infinity -> +Infinity (Exact)                                 */
01392 /*   A=10**n (if n is an integer) -> n (Exact)                        */
01393 /*                                                                    */
01394 /* Mathematical function restrictions apply (see above); a NaN is     */
01395 /* returned with Invalid_operation if a restriction is violated.      */
01396 /*                                                                    */
01397 /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
01398 /* almost always be correctly rounded, but may be up to 1 ulp in      */
01399 /* error in rare cases.                                               */
01400 /* ------------------------------------------------------------------ */
01401 /* This calculates ln(A)/ln(10) using appropriate precision.  For     */
01402 /* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the      */
01403 /* requested digits and t is the number of digits in the exponent     */
01404 /* (maximum 6).  For ln(10) it is p + 3; this is often handled by the */
01405 /* fastpath in decLnOp.  The final division is done to the requested  */
01406 /* precision.                                                         */
01407 /* ------------------------------------------------------------------ */
01408 decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
01409                           decContext *set) {
01410   uInt status=0, ignore=0;         // status accumulators
01411   uInt needbytes;                  // for space calculations
01412   Int p;                           // working precision
01413   Int t;                           // digits in exponent of A
01414
01415   // buffers for a and b working decimals
01416   // (adjustment calculator, same size)
01417   decNumber bufa[D2N(DECBUFFER+2)];
01418   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
01419   decNumber *a=bufa;               // temporary a
01420   decNumber bufb[D2N(DECBUFFER+2)];
01421   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
01422   decNumber *b=bufb;               // temporary b
01423   decNumber bufw[D2N(10)];         // working 2-10 digit number
01424   decNumber *w=bufw;               // ..
01425   #if DECSUBSET
01426   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01427   #endif
01428
01429   decContext aset;                 // working context
01430
01431   #if DECCHECK
01432   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01433   #endif
01434
01435   // Check restrictions; this is a math function; if not violated
01436   // then carry out the operation.
01437   if (!decCheckMath(rhs, set, &status)) do { // protect malloc
01438     #if DECSUBSET
01439     if (!set->extended) {
01440       // reduce operand and set lostDigits status, as needed
01441       if (rhs->digits>set->digits) {
01442         allocrhs=decRoundOperand(rhs, set, &status);
01443         if (allocrhs==NULL) break;
01444         rhs=allocrhs;
01445         }
01446       // special check in subset for rhs=0
01447       if (ISZERO(rhs)) {                // +/- zeros -> error
01448         status|=DEC_Invalid_operation;
01449         break;}
01450       } // extended=0
01451     #endif
01452
01453     decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
01454
01455     // handle exact powers of 10; only check if +ve finite
01456     if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {
01457       Int residue=0;               // (no residue)
01458       uInt copystat=0;             // clean status
01459
01460       // round to a single digit...
01461       aset.digits=1;
01462       decCopyFit(w, rhs, &aset, &residue, &copystat); // copy & shorten
01463       // if exact and the digit is 1, rhs is a power of 10
01464       if (!(copystat&DEC_Inexact) && w->lsu[0]==1) {
01465         // the exponent, conveniently, is the power of 10; making
01466         // this the result needs a little care as it might not fit,
01467         // so first convert it into the working number, and then move
01468         // to res
01469         decNumberFromInt32(w, w->exponent);
01470         residue=0;
01471         decCopyFit(res, w, set, &residue, &status); // copy & round
01472         decFinish(res, set, &residue, &status);     // cleanup/set flags
01473         break;
01474         } // not a power of 10
01475       } // not a candidate for exact
01476
01477     // simplify the information-content calculation to use 'total
01478     // number of digits in a, including exponent' as compared to the
01479     // requested digits, as increasing this will only rarely cost an
01480     // iteration in ln(a) anyway
01481     t=6;                                // it can never be >6
01482
01483     // allocate space when needed...
01484     p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
01485     needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
01486     if (needbytes>sizeof(bufa)) {       // need malloc space
01487       allocbufa=(decNumber *)malloc(needbytes);
01488       if (allocbufa==NULL) {            // hopeless -- abandon
01489         status|=DEC_Insufficient_storage;
01490         break;}
01491       a=allocbufa;                      // use the allocated space
01492       }
01493     aset.digits=p;                      // as calculated
01494     aset.emax=DEC_MAX_MATH;             // usual bounds
01495     aset.emin=-DEC_MAX_MATH;            // ..
01496     aset.clamp=0;                       // and no concrete format
01497     decLnOp(a, rhs, &aset, &status);    // a=ln(rhs)
01498
01499     // skip the division if the result so far is infinite, NaN, or
01500     // zero, or there was an error; note NaN from sNaN needs copy
01501     if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
01502     if (a->bits&DECSPECIAL || ISZERO(a)) {
01503       decNumberCopy(res, a);            // [will fit]
01504       break;}
01505
01506     // for ln(10) an extra 3 digits of precision are needed
01507     p=set->digits+3;
01508     needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
01509     if (needbytes>sizeof(bufb)) {       // need malloc space
01510       allocbufb=(decNumber *)malloc(needbytes);
01511       if (allocbufb==NULL) {            // hopeless -- abandon
01512         status|=DEC_Insufficient_storage;
01513         break;}
01514       b=allocbufb;                      // use the allocated space
01515       }
01516     decNumberZero(w);                   // set up 10...
01517     #if DECDPUN==1
01518     w->lsu[1]=1; w->lsu[0]=0;           // ..
01519     #else
01520     w->lsu[0]=10;                       // ..
01521     #endif
01522     w->digits=2;                        // ..
01523
01524     aset.digits=p;
01525     decLnOp(b, w, &aset, &ignore);      // b=ln(10)
01526
01527     aset.digits=set->digits;            // for final divide
01528     decDivideOp(res, a, b, &aset, DIVIDE, &status); // into result
01529     } while(0);                         // [for break]
01530
01531   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
01532   if (allocbufb!=NULL) free(allocbufb); // ..
01533   #if DECSUBSET
01534   if (allocrhs !=NULL) free(allocrhs);  // ..
01535   #endif
01536   // apply significant status
01537   if (status!=0) decStatus(res, status, set);
01538   #if DECCHECK
01539   decCheckInexact(res, set);
01540   #endif
01541   return res;
01542   } // decNumberLog10
01543
01544 /* ------------------------------------------------------------------ */
01545 /* decNumberMax -- compare two Numbers and return the maximum         */
01546 /*                                                                    */
01547 /*   This computes C = A ? B, returning the maximum by 754 rules      */
01548 /*                                                                    */
01549 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
01550 /*   lhs is A                                                         */
01551 /*   rhs is B                                                         */
01552 /*   set is the context                                               */
01553 /*                                                                    */
01554 /* C must have space for set->digits digits.                          */
01555 /* ------------------------------------------------------------------ */
01556 decNumber * decNumberMax(decNumber *res, const decNumber *lhs,
01557                          const decNumber *rhs, decContext *set) {
01558   uInt status=0;                        // accumulator
01559   decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
01560   if (status!=0) decStatus(res, status, set);
01561   #if DECCHECK
01562   decCheckInexact(res, set);
01563   #endif
01564   return res;
01565   } // decNumberMax
01566
01567 /* ------------------------------------------------------------------ */
01568 /* decNumberMaxMag -- compare and return the maximum by magnitude     */
01569 /*                                                                    */
01570 /*   This computes C = A ? B, returning the maximum by 754 rules      */
01571 /*                                                                    */
01572 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
01573 /*   lhs is A                                                         */
01574 /*   rhs is B                                                         */
01575 /*   set is the context                                               */
01576 /*                                                                    */
01577 /* C must have space for set->digits digits.                          */
01578 /* ------------------------------------------------------------------ */
01579 decNumber * decNumberMaxMag(decNumber *res, const decNumber *lhs,
01580                          const decNumber *rhs, decContext *set) {
01581   uInt status=0;                        // accumulator
01582   decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
01583   if (status!=0) decStatus(res, status, set);
01584   #if DECCHECK
01585   decCheckInexact(res, set);
01586   #endif
01587   return res;
01588   } // decNumberMaxMag
01589
01590 /* ------------------------------------------------------------------ */
01591 /* decNumberMin -- compare two Numbers and return the minimum         */
01592 /*                                                                    */
01593 /*   This computes C = A ? B, returning the minimum by 754 rules      */
01594 /*                                                                    */
01595 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
01596 /*   lhs is A                                                         */
01597 /*   rhs is B                                                         */
01598 /*   set is the context                                               */
01599 /*                                                                    */
01600 /* C must have space for set->digits digits.                          */
01601 /* ------------------------------------------------------------------ */
01602 decNumber * decNumberMin(decNumber *res, const decNumber *lhs,
01603                          const decNumber *rhs, decContext *set) {
01604   uInt status=0;                        // accumulator
01605   decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
01606   if (status!=0) decStatus(res, status, set);
01607   #if DECCHECK
01608   decCheckInexact(res, set);
01609   #endif
01610   return res;
01611   } // decNumberMin
01612
01613 /* ------------------------------------------------------------------ */
01614 /* decNumberMinMag -- compare and return the minimum by magnitude     */
01615 /*                                                                    */
01616 /*   This computes C = A ? B, returning the minimum by 754 rules      */
01617 /*                                                                    */
01618 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
01619 /*   lhs is A                                                         */
01620 /*   rhs is B                                                         */
01621 /*   set is the context                                               */
01622 /*                                                                    */
01623 /* C must have space for set->digits digits.                          */
01624 /* ------------------------------------------------------------------ */
01625 decNumber * decNumberMinMag(decNumber *res, const decNumber *lhs,
01626                          const decNumber *rhs, decContext *set) {
01627   uInt status=0;                        // accumulator
01628   decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
01629   if (status!=0) decStatus(res, status, set);
01630   #if DECCHECK
01631   decCheckInexact(res, set);
01632   #endif
01633   return res;
01634   } // decNumberMinMag
01635
01636 /* ------------------------------------------------------------------ */
01637 /* decNumberMinus -- prefix minus operator                            */
01638 /*                                                                    */
01639 /*   This computes C = 0 - A                                          */
01640 /*                                                                    */
01641 /*   res is C, the result.  C may be A                                */
01642 /*   rhs is A                                                         */
01643 /*   set is the context                                               */
01644 /*                                                                    */
01645 /* See also decNumberCopyNegate for a quiet bitwise version of this.  */
01646 /* C must have space for set->digits digits.                          */
01647 /* ------------------------------------------------------------------ */
01648 /* Simply use AddOp for the subtract, which will do the necessary.    */
01649 /* ------------------------------------------------------------------ */
01650 decNumber * decNumberMinus(decNumber *res, const decNumber *rhs,
01651                            decContext *set) {
01652   decNumber dzero;
01653   uInt status=0;                        // accumulator
01654
01655   #if DECCHECK
01656   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01657   #endif
01658
01659   decNumberZero(&dzero);                // make 0
01660   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
01661   decAddOp(res, &dzero, rhs, set, DECNEG, &status);
01662   if (status!=0) decStatus(res, status, set);
01663   #if DECCHECK
01664   decCheckInexact(res, set);
01665   #endif
01666   return res;
01667   } // decNumberMinus
01668
01669 /* ------------------------------------------------------------------ */
01670 /* decNumberNextMinus -- next towards -Infinity                       */
01671 /*                                                                    */
01672 /*   This computes C = A - infinitesimal, rounded towards -Infinity   */
01673 /*                                                                    */
01674 /*   res is C, the result.  C may be A                                */
01675 /*   rhs is A                                                         */
01676 /*   set is the context                                               */
01677 /*                                                                    */
01678 /* This is a generalization of 754 NextDown.                          */
01679 /* ------------------------------------------------------------------ */
01680 decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
01681                                decContext *set) {
01682   decNumber dtiny;                           // constant
01683   decContext workset=*set;                   // work
01684   uInt status=0;                             // accumulator
01685   #if DECCHECK
01686   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01687   #endif
01688
01689   // +Infinity is the special case
01690   if ((rhs->bits&(DECINF|DECNEG))==DECINF) {
01691     decSetMaxValue(res, set);                // is +ve
01692     // there is no status to set
01693     return res;
01694     }
01695   decNumberZero(&dtiny);                     // start with 0
01696   dtiny.lsu[0]=1;                            // make number that is ..
01697   dtiny.exponent=DEC_MIN_EMIN-1;             // .. smaller than tiniest
01698   workset.round=DEC_ROUND_FLOOR;
01699   decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
01700   status&=DEC_Invalid_operation|DEC_sNaN;    // only sNaN Invalid please
01701   if (status!=0) decStatus(res, status, set);
01702   return res;
01703   } // decNumberNextMinus
01704
01705 /* ------------------------------------------------------------------ */
01706 /* decNumberNextPlus -- next towards +Infinity                        */
01707 /*                                                                    */
01708 /*   This computes C = A + infinitesimal, rounded towards +Infinity   */
01709 /*                                                                    */
01710 /*   res is C, the result.  C may be A                                */
01711 /*   rhs is A                                                         */
01712 /*   set is the context                                               */
01713 /*                                                                    */
01714 /* This is a generalization of 754 NextUp.                            */
01715 /* ------------------------------------------------------------------ */
01716 decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
01717                               decContext *set) {
01718   decNumber dtiny;                           // constant
01719   decContext workset=*set;                   // work
01720   uInt status=0;                             // accumulator
01721   #if DECCHECK
01722   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01723   #endif
01724
01725   // -Infinity is the special case
01726   if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
01727     decSetMaxValue(res, set);
01728     res->bits=DECNEG;                        // negative
01729     // there is no status to set
01730     return res;
01731     }
01732   decNumberZero(&dtiny);                     // start with 0
01733   dtiny.lsu[0]=1;                            // make number that is ..
01734   dtiny.exponent=DEC_MIN_EMIN-1;             // .. smaller than tiniest
01735   workset.round=DEC_ROUND_CEILING;
01736   decAddOp(res, rhs, &dtiny, &workset, 0, &status);
01737   status&=DEC_Invalid_operation|DEC_sNaN;    // only sNaN Invalid please
01738   if (status!=0) decStatus(res, status, set);
01739   return res;
01740   } // decNumberNextPlus
01741
01742 /* ------------------------------------------------------------------ */
01743 /* decNumberNextToward -- next towards rhs                            */
01744 /*                                                                    */
01745 /*   This computes C = A +/- infinitesimal, rounded towards           */
01746 /*   +/-Infinity in the direction of B, as per 754-1985 nextafter     */
01747 /*   modified during revision but dropped from 754-2008.              */
01748 /*                                                                    */
01749 /*   res is C, the result.  C may be A or B.                          */
01750 /*   lhs is A                                                         */
01751 /*   rhs is B                                                         */
01752 /*   set is the context                                               */
01753 /*                                                                    */
01754 /* This is a generalization of 754-1985 NextAfter.                    */
01755 /* ------------------------------------------------------------------ */
01756 decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs,
01757                                 const decNumber *rhs, decContext *set) {
01758   decNumber dtiny;                           // constant
01759   decContext workset=*set;                   // work
01760   Int result;                                // ..
01761   uInt status=0;                             // accumulator
01762   #if DECCHECK
01763   if (decCheckOperands(res, lhs, rhs, set)) return res;
01764   #endif
01765
01766   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
01767     decNaNs(res, lhs, rhs, set, &status);
01768     }
01769    else { // Is numeric, so no chance of sNaN Invalid, etc.
01770     result=decCompare(lhs, rhs, 0);     // sign matters
01771     if (result==BADINT) status|=DEC_Insufficient_storage; // rare
01772      else { // valid compare
01773       if (result==0) decNumberCopySign(res, lhs, rhs); // easy
01774        else { // differ: need NextPlus or NextMinus
01775         uByte sub;                      // add or subtract
01776         if (result<0) {                 // lhs<rhs, do nextplus
01777           // -Infinity is the special case
01778           if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
01779             decSetMaxValue(res, set);
01780             res->bits=DECNEG;           // negative
01781             return res;                 // there is no status to set
01782             }
01783           workset.round=DEC_ROUND_CEILING;
01784           sub=0;                        // add, please
01785           } // plus
01786          else {                         // lhs>rhs, do nextminus
01787           // +Infinity is the special case
01788           if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
01789             decSetMaxValue(res, set);
01790             return res;                 // there is no status to set
01791             }
01792           workset.round=DEC_ROUND_FLOOR;
01793           sub=DECNEG;                   // subtract, please
01794           } // minus
01795         decNumberZero(&dtiny);          // start with 0
01796         dtiny.lsu[0]=1;                 // make number that is ..
01797         dtiny.exponent=DEC_MIN_EMIN-1;  // .. smaller than tiniest
01798         decAddOp(res, lhs, &dtiny, &workset, sub, &status); // + or -
01799         // turn off exceptions if the result is a normal number
01800         // (including Nmin), otherwise let all status through
01801         if (decNumberIsNormal(res, set)) status=0;
01802         } // unequal
01803       } // compare OK
01804     } // numeric
01805   if (status!=0) decStatus(res, status, set);
01806   return res;
01807   } // decNumberNextToward
01808
01809 /* ------------------------------------------------------------------ */
01810 /* decNumberOr -- OR two Numbers, digitwise                           */
01811 /*                                                                    */
01812 /*   This computes C = A | B                                          */
01813 /*                                                                    */
01814 /*   res is C, the result.  C may be A and/or B (e.g., X=X|X)         */
01815 /*   lhs is A                                                         */
01816 /*   rhs is B                                                         */
01817 /*   set is the context (used for result length and error report)     */
01818 /*                                                                    */
01819 /* C must have space for set->digits digits.                          */
01820 /*                                                                    */
01821 /* Logical function restrictions apply (see above); a NaN is          */
01822 /* returned with Invalid_operation if a restriction is violated.      */
01823 /* ------------------------------------------------------------------ */
01824 decNumber * decNumberOr(decNumber *res, const decNumber *lhs,
01825                         const decNumber *rhs, decContext *set) {
01826   const Unit *ua, *ub;                  // -> operands
01827   const Unit *msua, *msub;              // -> operand msus
01828   Unit  *uc, *msuc;                     // -> result and its msu
01829   Int   msudigs;                        // digits in res msu
01830   #if DECCHECK
01831   if (decCheckOperands(res, lhs, rhs, set)) return res;
01832   #endif
01833
01834   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
01835    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
01836     decStatus(res, DEC_Invalid_operation, set);
01837     return res;
01838     }
01839   // operands are valid
01840   ua=lhs->lsu;                          // bottom-up
01841   ub=rhs->lsu;                          // ..
01842   uc=res->lsu;                          // ..
01843   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
01844   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
01845   msuc=uc+D2U(set->digits)-1;           // -> msu of result
01846   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
01847   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
01848     Unit a, b;                          // extract units
01849     if (ua>msua) a=0;
01850      else a=*ua;
01851     if (ub>msub) b=0;
01852      else b=*ub;
01853     *uc=0;                              // can now write back
01854     if (a|b) {                          // maybe 1 bits to examine
01855       Int i, j;
01856       // This loop could be unrolled and/or use BIN2BCD tables
01857       for (i=0; i<DECDPUN; i++) {
01858         if ((a|b)&1) *uc=*uc+(Unit)powers[i];     // effect OR
01859         j=a%10;
01860         a=a/10;
01861         j|=b%10;
01862         b=b/10;
01863         if (j>1) {
01864           decStatus(res, DEC_Invalid_operation, set);
01865           return res;
01866           }
01867         if (uc==msuc && i==msudigs-1) break;      // just did final digit
01868         } // each digit
01869       } // non-zero
01870     } // each unit
01871   // [here uc-1 is the msu of the result]
01872   res->digits=decGetDigits(res->lsu, uc-res->lsu);
01873   res->exponent=0;                      // integer
01874   res->bits=0;                          // sign=0
01875   return res;  // [no status to set]
01876   } // decNumberOr
01877
01878 /* ------------------------------------------------------------------ */
01879 /* decNumberPlus -- prefix plus operator                              */
01880 /*                                                                    */
01881 /*   This computes C = 0 + A                                          */
01882 /*                                                                    */
01883 /*   res is C, the result.  C may be A                                */
01884 /*   rhs is A                                                         */
01885 /*   set is the context                                               */
01886 /*                                                                    */
01887 /* See also decNumberCopy for a quiet bitwise version of this.        */
01888 /* C must have space for set->digits digits.                          */
01889 /* ------------------------------------------------------------------ */
01890 /* This simply uses AddOp; Add will take fast path after preparing A. */
01891 /* Performance is a concern here, as this routine is often used to    */
01892 /* check operands and apply rounding and overflow/underflow testing.  */
01893 /* ------------------------------------------------------------------ */
01894 decNumber * decNumberPlus(decNumber *res, const decNumber *rhs,
01895                           decContext *set) {
01896   decNumber dzero;
01897   uInt status=0;                        // accumulator
01898   #if DECCHECK
01899   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01900   #endif
01901
01902   decNumberZero(&dzero);                // make 0
01903   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
01904   decAddOp(res, &dzero, rhs, set, 0, &status);
01905   if (status!=0) decStatus(res, status, set);
01906   #if DECCHECK
01907   decCheckInexact(res, set);
01908   #endif
01909   return res;
01910   } // decNumberPlus
01911
01912 /* ------------------------------------------------------------------ */
01913 /* decNumberMultiply -- multiply two Numbers                          */
01914 /*                                                                    */
01915 /*   This computes C = A x B                                          */
01916 /*                                                                    */
01917 /*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
01918 /*   lhs is A                                                         */
01919 /*   rhs is B                                                         */
01920 /*   set is the context                                               */
01921 /*                                                                    */
01922 /* C must have space for set->digits digits.                          */
01923 /* ------------------------------------------------------------------ */
01924 decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs,
01925                               const decNumber *rhs, decContext *set) {
01926   uInt status=0;                   // accumulator
01927   decMultiplyOp(res, lhs, rhs, set, &status);
01928   if (status!=0) decStatus(res, status, set);
01929   #if DECCHECK
01930   decCheckInexact(res, set);
01931   #endif
01932   return res;
01933   } // decNumberMultiply
01934
01935 /* ------------------------------------------------------------------ */
01936 /* decNumberPower -- raise a number to a power                        */
01937 /*                                                                    */
01938 /*   This computes C = A ** B                                         */
01939 /*                                                                    */
01940 /*   res is C, the result.  C may be A and/or B (e.g., X=X**X)        */
01941 /*   lhs is A                                                         */
01942 /*   rhs is B                                                         */
01943 /*   set is the context                                               */
01944 /*                                                                    */
01945 /* C must have space for set->digits digits.                          */
01946 /*                                                                    */
01947 /* Mathematical function restrictions apply (see above); a NaN is     */
01948 /* returned with Invalid_operation if a restriction is violated.      */
01949 /*                                                                    */
01950 /* However, if 1999999997<=B<=999999999 and B is an integer then the  */
01951 /* restrictions on A and the context are relaxed to the usual bounds, */
01952 /* for compatibility with the earlier (integer power only) version    */
01953 /* of this function.                                                  */
01954 /*                                                                    */
01955 /* When B is an integer, the result may be exact, even if rounded.    */
01956 /*                                                                    */
01957 /* The final result is rounded according to the context; it will      */
01958 /* almost always be correctly rounded, but may be up to 1 ulp in      */
01959 /* error in rare cases.                                               */
01960 /* ------------------------------------------------------------------ */
01961 decNumber * decNumberPower(decNumber *res, const decNumber *lhs,
01962                            const decNumber *rhs, decContext *set) {
01963   #if DECSUBSET
01964   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
01965   decNumber *allocrhs=NULL;        // .., rhs
01966   #endif
01967   decNumber *allocdac=NULL;        // -> allocated acc buffer, iff used
01968   decNumber *allocinv=NULL;        // -> allocated 1/x buffer, iff used
01969   Int   reqdigits=set->digits;     // requested DIGITS
01970   Int   n;                         // rhs in binary
01971   Flag  rhsint=0;                  // 1 if rhs is an integer
01972   Flag  useint=0;                  // 1 if can use integer calculation
01973   Flag  isoddint=0;                // 1 if rhs is an integer and odd
01974   Int   i;                         // work
01975   #if DECSUBSET
01976   Int   dropped;                   // ..
01977   #endif
01978   uInt  needbytes;                 // buffer size needed
01979   Flag  seenbit;                   // seen a bit while powering
01980   Int   residue=0;                 // rounding residue
01981   uInt  status=0;                  // accumulators
01982   uByte bits=0;                    // result sign if errors
01983   decContext aset;                 // working context
01984   decNumber dnOne;                 // work value 1...
01985   // local accumulator buffer [a decNumber, with digits+elength+1 digits]
01986   decNumber dacbuff[D2N(DECBUFFER+9)];
01987   decNumber *dac=dacbuff;          // -> result accumulator
01988   // same again for possible 1/lhs calculation
01989   decNumber invbuff[D2N(DECBUFFER+9)];
01990
01991   #if DECCHECK
01992   if (decCheckOperands(res, lhs, rhs, set)) return res;
01993   #endif
01994
01995   do {                             // protect allocated storage
01996     #if DECSUBSET
01997     if (!set->extended) { // reduce operands and set status, as needed
01998       if (lhs->digits>reqdigits) {
01999         alloclhs=decRoundOperand(lhs, set, &status);
02000         if (alloclhs==NULL) break;
02001         lhs=alloclhs;
02002         }
02003       if (rhs->digits>reqdigits) {
02004         allocrhs=decRoundOperand(rhs, set, &status);
02005         if (allocrhs==NULL) break;
02006         rhs=allocrhs;
02007         }
02008       }
02009     #endif
02010     // [following code does not require input rounding]
02011
02012     // handle NaNs and rhs Infinity (lhs infinity is harder)
02013     if (SPECIALARGS) {
02014       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { // NaNs
02015         decNaNs(res, lhs, rhs, set, &status);
02016         break;}
02017       if (decNumberIsInfinite(rhs)) {   // rhs Infinity
02018         Flag rhsneg=rhs->bits&DECNEG;   // save rhs sign
02019         if (decNumberIsNegative(lhs)    // lhs<0
02020          && !decNumberIsZero(lhs))      // ..
02021           status|=DEC_Invalid_operation;
02022          else {                         // lhs >=0
02023           decNumberZero(&dnOne);        // set up 1
02024           dnOne.lsu[0]=1;
02025           decNumberCompare(dac, lhs, &dnOne, set); // lhs ? 1
02026           decNumberZero(res);           // prepare for 0/1/Infinity
02027           if (decNumberIsNegative(dac)) {    // lhs<1
02028             if (rhsneg) res->bits|=DECINF;   // +Infinity [else is +0]
02029             }
02030            else if (dac->lsu[0]==0) {        // lhs=1
02031             // 1**Infinity is inexact, so return fully-padded 1.0000
02032             Int shift=set->digits-1;
02033             *res->lsu=1;                     // was 0, make int 1
02034             res->digits=decShiftToMost(res->lsu, 1, shift);
02035             res->exponent=-shift;            // make 1.0000...
02036             status|=DEC_Inexact|DEC_Rounded; // deemed inexact
02037             }
02038            else {                            // lhs>1
02039             if (!rhsneg) res->bits|=DECINF;  // +Infinity [else is +0]
02040             }
02041           } // lhs>=0
02042         break;}
02043       // [lhs infinity drops through]
02044       } // specials
02045
02046     // Original rhs may be an integer that fits and is in range
02047     n=decGetInt(rhs);
02048     if (n!=BADINT) {                    // it is an integer
02049       rhsint=1;                         // record the fact for 1**n
02050       isoddint=(Flag)n&1;               // [works even if big]
02051       if (n!=BIGEVEN && n!=BIGODD)      // can use integer path?
02052         useint=1;                       // looks good
02053       }
02054
02055     if (decNumberIsNegative(lhs)        // -x ..
02056       && isoddint) bits=DECNEG;         // .. to an odd power
02057
02058     // handle LHS infinity
02059     if (decNumberIsInfinite(lhs)) {     // [NaNs already handled]
02060       uByte rbits=rhs->bits;            // save
02061       decNumberZero(res);               // prepare
02062       if (n==0) *res->lsu=1;            // [-]Inf**0 => 1
02063        else {
02064         // -Inf**nonint -> error
02065         if (!rhsint && decNumberIsNegative(lhs)) {
02066           status|=DEC_Invalid_operation;     // -Inf**nonint is error
02067           break;}
02068         if (!(rbits & DECNEG)) bits|=DECINF; // was not a **-n
02069         // [otherwise will be 0 or -0]
02070         res->bits=bits;
02071         }
02072       break;}
02073
02074     // similarly handle LHS zero
02075     if (decNumberIsZero(lhs)) {
02076       if (n==0) {                            // 0**0 => Error
02077         #if DECSUBSET
02078         if (!set->extended) {                // [unless subset]
02079           decNumberZero(res);
02080           *res->lsu=1;                       // return 1
02081           break;}
02082         #endif
02083         status|=DEC_Invalid_operation;
02084         }
02085        else {                                // 0**x
02086         uByte rbits=rhs->bits;               // save
02087         if (rbits & DECNEG) {                // was a 0**(-n)
02088           #if DECSUBSET
02089           if (!set->extended) {              // [bad if subset]
02090             status|=DEC_Invalid_operation;
02091             break;}
02092           #endif
02093           bits|=DECINF;
02094           }
02095         decNumberZero(res);                  // prepare
02096         // [otherwise will be 0 or -0]
02097         res->bits=bits;
02098         }
02099       break;}
02100
02101     // here both lhs and rhs are finite; rhs==0 is handled in the
02102     // integer path.  Next handle the non-integer cases
02103     if (!useint) {                      // non-integral rhs
02104       // any -ve lhs is bad, as is either operand or context out of
02105       // bounds
02106       if (decNumberIsNegative(lhs)) {
02107         status|=DEC_Invalid_operation;
02108         break;}
02109       if (decCheckMath(lhs, set, &status)
02110        || decCheckMath(rhs, set, &status)) break; // variable status
02111
02112       decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
02113       aset.emax=DEC_MAX_MATH;           // usual bounds
02114       aset.emin=-DEC_MAX_MATH;          // ..
02115       aset.clamp=0;                     // and no concrete format
02116
02117       // calculate the result using exp(ln(lhs)*rhs), which can
02118       // all be done into the accumulator, dac.  The precision needed
02119       // is enough to contain the full information in the lhs (which
02120       // is the total digits, including exponent), or the requested
02121       // precision, if larger, + 4; 6 is used for the exponent
02122       // maximum length, and this is also used when it is shorter
02123       // than the requested digits as it greatly reduces the >0.5 ulp
02124       // cases at little cost (because Ln doubles digits each
02125       // iteration so a few extra digits rarely causes an extra
02126       // iteration)
02127       aset.digits=MAXI(lhs->digits, set->digits)+6+4;
02128       } // non-integer rhs
02129
02130      else { // rhs is in-range integer
02131       if (n==0) {                       // x**0 = 1
02132         // (0**0 was handled above)
02133         decNumberZero(res);             // result=1
02134         *res->lsu=1;                    // ..
02135         break;}
02136       // rhs is a non-zero integer
02137       if (n<0) n=-n;                    // use abs(n)
02138
02139       aset=*set;                        // clone the context
02140       aset.round=DEC_ROUND_HALF_EVEN;   // internally use balanced
02141       // calculate the working DIGITS
02142       aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
02143       #if DECSUBSET
02144       if (!set->extended) aset.digits--;     // use classic precision
02145       #endif
02146       // it's an error if this is more than can be handled
02147       if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}
02148       } // integer path
02149
02150     // aset.digits is the count of digits for the accumulator needed
02151     // if accumulator is too long for local storage, then allocate
02152     needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);
02153     // [needbytes also used below if 1/lhs needed]
02154     if (needbytes>sizeof(dacbuff)) {
02155       allocdac=(decNumber *)malloc(needbytes);
02156       if (allocdac==NULL) {   // hopeless -- abandon
02157         status|=DEC_Insufficient_storage;
02158         break;}
02159       dac=allocdac;           // use the allocated space
02160       }
02161     // here, aset is set up and accumulator is ready for use
02162
02163     if (!useint) {                           // non-integral rhs
02164       // x ** y; special-case x=1 here as it will otherwise always
02165       // reduce to integer 1; decLnOp has a fastpath which detects
02166       // the case of x=1
02167       decLnOp(dac, lhs, &aset, &status);     // dac=ln(lhs)
02168       // [no error possible, as lhs 0 already handled]
02169       if (ISZERO(dac)) {                     // x==1, 1.0, etc.
02170         // need to return fully-padded 1.0000 etc., but rhsint->1
02171         *dac->lsu=1;                         // was 0, make int 1
02172         if (!rhsint) {                       // add padding
02173           Int shift=set->digits-1;
02174           dac->digits=decShiftToMost(dac->lsu, 1, shift);
02175           dac->exponent=-shift;              // make 1.0000...
02176           status|=DEC_Inexact|DEC_Rounded;   // deemed inexact
02177           }
02178         }
02179        else {
02180         decMultiplyOp(dac, dac, rhs, &aset, &status);  // dac=dac*rhs
02181         decExpOp(dac, dac, &aset, &status);            // dac=exp(dac)
02182         }
02183       // and drop through for final rounding
02184       } // non-integer rhs
02185
02186      else {                             // carry on with integer
02187       decNumberZero(dac);               // acc=1
02188       *dac->lsu=1;                      // ..
02189
02190       // if a negative power the constant 1 is needed, and if not subset
02191       // invert the lhs now rather than inverting the result later
02192       if (decNumberIsNegative(rhs)) {   // was a **-n [hence digits>0]
02193         decNumber *inv=invbuff;         // asssume use fixed buffer
02194         decNumberCopy(&dnOne, dac);     // dnOne=1;  [needed now or later]
02195         #if DECSUBSET
02196         if (set->extended) {            // need to calculate 1/lhs
02197         #endif
02198           // divide lhs into 1, putting result in dac [dac=1/dac]
02199           decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);
02200           // now locate or allocate space for the inverted lhs
02201           if (needbytes>sizeof(invbuff)) {
02202             allocinv=(decNumber *)malloc(needbytes);
02203             if (allocinv==NULL) {       // hopeless -- abandon
02204               status|=DEC_Insufficient_storage;
02205               break;}
02206             inv=allocinv;               // use the allocated space
02207             }
02208           // [inv now points to big-enough buffer or allocated storage]
02209           decNumberCopy(inv, dac);      // copy the 1/lhs
02210           decNumberCopy(dac, &dnOne);   // restore acc=1
02211           lhs=inv;                      // .. and go forward with new lhs
02212         #if DECSUBSET
02213           }
02214         #endif
02215         }
02216
02217       // Raise-to-the-power loop...
02218       seenbit=0;                   // set once a 1-bit is encountered
02219       for (i=1;;i++){              // for each bit [top bit ignored]
02220         // abandon if had overflow or terminal underflow
02221         if (status & (DEC_Overflow|DEC_Underflow)) { // interesting?
02222           if (status&DEC_Overflow || ISZERO(dac)) break;
02223           }
02224         // [the following two lines revealed an optimizer bug in a C++
02225         // compiler, with symptom: 5**3 -> 25, when n=n+n was used]
02226         n=n<<1;                    // move next bit to testable position
02227         if (n<0) {                 // top bit is set
02228           seenbit=1;               // OK, significant bit seen
02229           decMultiplyOp(dac, dac, lhs, &aset, &status); // dac=dac*x
02230           }
02231         if (i==31) break;          // that was the last bit
02232         if (!seenbit) continue;    // no need to square 1
02233         decMultiplyOp(dac, dac, dac, &aset, &status); // dac=dac*dac [square]
02234         } /*i*/ // 32 bits
02235
02236       // complete internal overflow or underflow processing
02237       if (status & (DEC_Overflow|DEC_Underflow)) {
02238         #if DECSUBSET
02239         // If subset, and power was negative, reverse the kind of -erflow
02240         // [1/x not yet done]
02241         if (!set->extended && decNumberIsNegative(rhs)) {
02242           if (status & DEC_Overflow)
02243             status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;
02244            else { // trickier -- Underflow may or may not be set
02245             status&=~(DEC_Underflow | DEC_Subnormal); // [one or both]
02246             status|=DEC_Overflow;
02247             }
02248           }
02249         #endif
02250         dac->bits=(dac->bits & ~DECNEG) | bits; // force correct sign
02251         // round subnormals [to set.digits rather than aset.digits]
02252         // or set overflow result similarly as required
02253         decFinalize(dac, set, &residue, &status);
02254         decNumberCopy(res, dac);   // copy to result (is now OK length)
02255         break;
02256         }
02257
02258       #if DECSUBSET
02259       if (!set->extended &&                  // subset math
02260           decNumberIsNegative(rhs)) {        // was a **-n [hence digits>0]
02261         // so divide result into 1 [dac=1/dac]
02262         decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);
02263         }
02264       #endif
02265       } // rhs integer path
02266
02267     // reduce result to the requested length and copy to result
02268     decCopyFit(res, dac, set, &residue, &status);
02269     decFinish(res, set, &residue, &status);  // final cleanup
02270     #if DECSUBSET
02271     if (!set->extended) decTrim(res, set, 0, 1, &dropped); // trailing zeros
02272     #endif
02273     } while(0);                         // end protected
02274
02275   if (allocdac!=NULL) free(allocdac);   // drop any storage used
02276   if (allocinv!=NULL) free(allocinv);   // ..
02277   #if DECSUBSET
02278   if (alloclhs!=NULL) free(alloclhs);   // ..
02279   if (allocrhs!=NULL) free(allocrhs);   // ..
02280   #endif
02281   if (status!=0) decStatus(res, status, set);
02282   #if DECCHECK
02283   decCheckInexact(res, set);
02284   #endif
02285   return res;
02286   } // decNumberPower
02287
02288 /* ------------------------------------------------------------------ */
02289 /* decNumberQuantize -- force exponent to requested value             */
02290 /*                                                                    */
02291 /*   This computes C = op(A, B), where op adjusts the coefficient     */
02292 /*   of C (by rounding or shifting) such that the exponent (-scale)   */
02293 /*   of C has exponent of B.  The numerical value of C will equal A,  */
02294 /*   except for the effects of any rounding that occurred.            */
02295 /*                                                                    */
02296 /*   res is C, the result.  C may be A or B                           */
02297 /*   lhs is A, the number to adjust                                   */
02298 /*   rhs is B, the number with exponent to match                      */
02299 /*   set is the context                                               */
02300 /*                                                                    */
02301 /* C must have space for set->digits digits.                          */
02302 /*                                                                    */
02303 /* Unless there is an error or the result is infinite, the exponent   */
02304 /* after the operation is guaranteed to be equal to that of B.        */
02305 /* ------------------------------------------------------------------ */
02306 decNumber * decNumberQuantize(decNumber *res, const decNumber *lhs,
02307                               const decNumber *rhs, decContext *set) {
02308   uInt status=0;                        // accumulator
02309   decQuantizeOp(res, lhs, rhs, set, 1, &status);
02310   if (status!=0) decStatus(res, status, set);
02311   return res;
02312   } // decNumberQuantize
02313
02314 /* ------------------------------------------------------------------ */
02315 /* decNumberReduce -- remove trailing zeros                           */
02316 /*                                                                    */
02317 /*   This computes C = 0 + A, and normalizes the result               */
02318 /*                                                                    */
02319 /*   res is C, the result.  C may be A                                */
02320 /*   rhs is A                                                         */
02321 /*   set is the context                                               */
02322 /*                                                                    */
02323 /* C must have space for set->digits digits.                          */
02324 /* ------------------------------------------------------------------ */
02325 // Previously known as Normalize
02326 decNumber * decNumberNormalize(decNumber *res, const decNumber *rhs,
02327                                decContext *set) {
02328   return decNumberReduce(res, rhs, set);
02329   } // decNumberNormalize
02330
02331 decNumber * decNumberReduce(decNumber *res, const decNumber *rhs,
02332                             decContext *set) {
02333   #if DECSUBSET
02334   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
02335   #endif
02336   uInt status=0;                   // as usual
02337   Int  residue=0;                  // as usual
02338   Int  dropped;                    // work
02339
02340   #if DECCHECK
02341   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
02342   #endif
02343
02344   do {                             // protect allocated storage
02345     #if DECSUBSET
02346     if (!set->extended) {
02347       // reduce operand and set lostDigits status, as needed
02348       if (rhs->digits>set->digits) {
02349         allocrhs=decRoundOperand(rhs, set, &status);
02350         if (allocrhs==NULL) break;
02351         rhs=allocrhs;
02352         }
02353       }
02354     #endif
02355     // [following code does not require input rounding]
02356
02357     // Infinities copy through; NaNs need usual treatment
02358     if (decNumberIsNaN(rhs)) {
02359       decNaNs(res, rhs, NULL, set, &status);
02360       break;
02361       }
02362
02363     // reduce result to the requested length and copy to result
02364     decCopyFit(res, rhs, set, &residue, &status); // copy & round
02365     decFinish(res, set, &residue, &status);       // cleanup/set flags
02366     decTrim(res, set, 1, 0, &dropped);            // normalize in place
02367                                                   // [may clamp]
02368     } while(0);                              // end protected
02369
02370   #if DECSUBSET
02371   if (allocrhs !=NULL) free(allocrhs);       // ..
02372   #endif
02373   if (status!=0) decStatus(res, status, set);// then report status
02374   return res;
02375   } // decNumberReduce
02376
02377 /* ------------------------------------------------------------------ */
02378 /* decNumberRescale -- force exponent to requested value              */
02379 /*                                                                    */
02380 /*   This computes C = op(A, B), where op adjusts the coefficient     */
02381 /*   of C (by rounding or shifting) such that the exponent (-scale)   */
02382 /*   of C has the value B.  The numerical value of C will equal A,    */
02383 /*   except for the effects of any rounding that occurred.            */
02384 /*                                                                    */
02385 /*   res is C, the result.  C may be A or B                           */
02386 /*   lhs is A, the number to adjust                                   */
02387 /*   rhs is B, the requested exponent                                 */
02388 /*   set is the context                                               */
02389 /*                                                                    */
02390 /* C must have space for set->digits digits.                          */
02391 /*                                                                    */
02392 /* Unless there is an error or the result is infinite, the exponent   */
02393 /* after the operation is guaranteed to be equal to B.                */
02394 /* ------------------------------------------------------------------ */
02395 decNumber * decNumberRescale(decNumber *res, const decNumber *lhs,
02396                              const decNumber *rhs, decContext *set) {
02397   uInt status=0;                        // accumulator
02398   decQuantizeOp(res, lhs, rhs, set, 0, &status);
02399   if (status!=0) decStatus(res, status, set);
02400   return res;
02401   } // decNumberRescale
02402
02403 /* ------------------------------------------------------------------ */
02404 /* decNumberRemainder -- divide and return remainder                  */
02405 /*                                                                    */
02406 /*   This computes C = A % B                                          */
02407 /*                                                                    */
02408 /*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
02409 /*   lhs is A                                                         */
02410 /*   rhs is B                                                         */
02411 /*   set is the context                                               */
02412 /*                                                                    */
02413 /* C must have space for set->digits digits.                          */
02414 /* ------------------------------------------------------------------ */
02415 decNumber * decNumberRemainder(decNumber *res, const decNumber *lhs,
02416                                const decNumber *rhs, decContext *set) {
02417   uInt status=0;                        // accumulator
02418   decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
02419   if (status!=0) decStatus(res, status, set);
02420   #if DECCHECK
02421   decCheckInexact(res, set);
02422   #endif
02423   return res;
02424   } // decNumberRemainder
02425
02426 /* ------------------------------------------------------------------ */
02427 /* decNumberRemainderNear -- divide and return remainder from nearest */
02428 /*                                                                    */
02429 /*   This computes C = A % B, where % is the IEEE remainder operator  */
02430 /*                                                                    */
02431 /*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
02432 /*   lhs is A                                                         */
02433 /*   rhs is B                                                         */
02434 /*   set is the context                                               */
02435 /*                                                                    */
02436 /* C must have space for set->digits digits.                          */
02437 /* ------------------------------------------------------------------ */
02438 decNumber * decNumberRemainderNear(decNumber *res, const decNumber *lhs,
02439                                    const decNumber *rhs, decContext *set) {
02440   uInt status=0;                        // accumulator
02441   decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
02442   if (status!=0) decStatus(res, status, set);
02443   #if DECCHECK
02444   decCheckInexact(res, set);
02445   #endif
02446   return res;
02447   } // decNumberRemainderNear
02448
02449 /* ------------------------------------------------------------------ */
02450 /* decNumberRotate -- rotate the coefficient of a Number left/right   */
02451 /*                                                                    */
02452 /*   This computes C = A rot B  (in base ten and rotating set->digits */
02453 /*   digits).                                                         */
02454 /*                                                                    */
02455 /*   res is C, the result.  C may be A and/or B (e.g., X=XrotX)       */
02456 /*   lhs is A                                                         */
02457 /*   rhs is B, the number of digits to rotate (-ve to right)          */
02458 /*   set is the context                                               */
02459 /*                                                                    */
02460 /* The digits of the coefficient of A are rotated to the left (if B   */
02461 /* is positive) or to the right (if B is negative) without adjusting  */
02462 /* the exponent or the sign of A.  If lhs->digits is less than        */
02463 /* set->digits the coefficient is padded with zeros on the left       */
02464 /* before the rotate.  Any leading zeros in the result are removed    */
02465 /* as usual.                                                          */
02466 /*                                                                    */
02467 /* B must be an integer (q=0) and in the range -set->digits through   */
02468 /* +set->digits.                                                      */
02469 /* C must have space for set->digits digits.                          */
02470 /* NaNs are propagated as usual.  Infinities are unaffected (but      */
02471 /* B must be valid).  No status is set unless B is invalid or an      */
02472 /* operand is an sNaN.                                                */
02473 /* ------------------------------------------------------------------ */
02474 decNumber * decNumberRotate(decNumber *res, const decNumber *lhs,
02475                            const decNumber *rhs, decContext *set) {
02476   uInt status=0;              // accumulator
02477   Int  rotate;                // rhs as an Int
02478
02479   #if DECCHECK
02480   if (decCheckOperands(res, lhs, rhs, set)) return res;
02481   #endif
02482
02483   // NaNs propagate as normal
02484   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02485     decNaNs(res, lhs, rhs, set, &status);
02486    // rhs must be an integer
02487    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02488     status=DEC_Invalid_operation;
02489    else { // both numeric, rhs is an integer
02490     rotate=decGetInt(rhs);                   // [cannot fail]
02491     if (rotate==BADINT                       // something bad ..
02492      || rotate==BIGODD || rotate==BIGEVEN    // .. very big ..
02493      || abs(rotate)>set->digits)             // .. or out of range
02494       status=DEC_Invalid_operation;
02495      else {                                  // rhs is OK
02496       decNumberCopy(res, lhs);
02497       // convert -ve rotate to equivalent positive rotation
02498       if (rotate<0) rotate=set->digits+rotate;
02499       if (rotate!=0 && rotate!=set->digits   // zero or full rotation
02500        && !decNumberIsInfinite(res)) {       // lhs was infinite
02501         // left-rotate to do; 0 < rotate < set->digits
02502         uInt units, shift;                   // work
02503         uInt msudigits;                      // digits in result msu
02504         Unit *msu=res->lsu+D2U(res->digits)-1;    // current msu
02505         Unit *msumax=res->lsu+D2U(set->digits)-1; // rotation msu
02506         for (msu++; msu<=msumax; msu++) *msu=0;   // ensure high units=0
02507         res->digits=set->digits;                  // now full-length
02508         msudigits=MSUDIGITS(res->digits);         // actual digits in msu
02509
02510         // rotation here is done in-place, in three steps
02511         // 1. shift all to least up to one unit to unit-align final
02512         //    lsd [any digits shifted out are rotated to the left,
02513         //    abutted to the original msd (which may require split)]
02514         //
02515         //    [if there are no whole units left to rotate, the
02516         //    rotation is now complete]
02517         //
02518         // 2. shift to least, from below the split point only, so that
02519         //    the final msd is in the right place in its Unit [any
02520         //    digits shifted out will fit exactly in the current msu,
02521         //    left aligned, no split required]
02522         //
02523         // 3. rotate all the units by reversing left part, right
02524         //    part, and then whole
02525         //
02526         // example: rotate right 8 digits (2 units + 2), DECDPUN=3.
02527         //
02528         //   start: 00a bcd efg hij klm npq
02529         //
02530         //      1a  000 0ab cde fgh|ijk lmn [pq saved]
02531         //      1b  00p qab cde fgh|ijk lmn
02532         //
02533         //      2a  00p qab cde fgh|00i jkl [mn saved]
02534         //      2b  mnp qab cde fgh|00i jkl
02535         //
02536         //      3a  fgh cde qab mnp|00i jkl
02537         //      3b  fgh cde qab mnp|jkl 00i
02538         //      3c  00i jkl mnp qab cde fgh
02539
02540         // Step 1: amount to shift is the partial right-rotate count
02541         rotate=set->digits-rotate;      // make it right-rotate
02542         units=rotate/DECDPUN;           // whole units to rotate
02543         shift=rotate%DECDPUN;           // left-over digits count
02544         if (shift>0) {                  // not an exact number of units
02545           uInt save=res->lsu[0]%powers[shift];    // save low digit(s)
02546           decShiftToLeast(res->lsu, D2U(res->digits), shift);
02547           if (shift>msudigits) {        // msumax-1 needs >0 digits
02548             uInt rem=save%powers[shift-msudigits];// split save
02549             *msumax=(Unit)(save/powers[shift-msudigits]); // and insert
02550             *(msumax-1)=*(msumax-1)
02551                        +(Unit)(rem*powers[DECDPUN-(shift-msudigits)]); // ..
02552             }
02553            else { // all fits in msumax
02554             *msumax=*msumax+(Unit)(save*powers[msudigits-shift]); // [maybe *1]
02555             }
02556           } // digits shift needed
02557
02558         // If whole units to rotate...
02559         if (units>0) {                  // some to do
02560           // Step 2: the units to touch are the whole ones in rotate,
02561           //   if any, and the shift is DECDPUN-msudigits (which may be
02562           //   0, again)
02563           shift=DECDPUN-msudigits;
02564           if (shift>0) {                // not an exact number of units
02565             uInt save=res->lsu[0]%powers[shift];  // save low digit(s)
02566             decShiftToLeast(res->lsu, units, shift);
02567             *msumax=*msumax+(Unit)(save*powers[msudigits]);
02568             } // partial shift needed
02569
02570           // Step 3: rotate the units array using triple reverse
02571           // (reversing is easy and fast)
02572           decReverse(res->lsu+units, msumax);     // left part
02573           decReverse(res->lsu, res->lsu+units-1); // right part
02574           decReverse(res->lsu, msumax);           // whole
02575           } // whole units to rotate
02576         // the rotation may have left an undetermined number of zeros
02577         // on the left, so true length needs to be calculated
02578         res->digits=decGetDigits(res->lsu, msumax-res->lsu+1);
02579         } // rotate needed
02580       } // rhs OK
02581     } // numerics
02582   if (status!=0) decStatus(res, status, set);
02583   return res;
02584   } // decNumberRotate
02585
02586 /* ------------------------------------------------------------------ */
02587 /* decNumberSameQuantum -- test for equal exponents                   */
02588 /*                                                                    */
02589 /*   res is the result number, which will contain either 0 or 1       */
02590 /*   lhs is a number to test                                          */
02591 /*   rhs is the second (usually a pattern)                            */
02592 /*                                                                    */
02593 /* No errors are possible and no context is needed.                   */
02594 /* ------------------------------------------------------------------ */
02595 decNumber * decNumberSameQuantum(decNumber *res, const decNumber *lhs,
02596                                  const decNumber *rhs) {
02597   Unit ret=0;                      // return value
02598
02599   #if DECCHECK
02600   if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;
02601   #endif
02602
02603   if (SPECIALARGS) {
02604     if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1;
02605      else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1;
02606      // [anything else with a special gives 0]
02607     }
02608    else if (lhs->exponent==rhs->exponent) ret=1;
02609
02610   decNumberZero(res);              // OK to overwrite an operand now
02611   *res->lsu=ret;
02612   return res;
02613   } // decNumberSameQuantum
02614
02615 /* ------------------------------------------------------------------ */
02616 /* decNumberScaleB -- multiply by a power of 10                       */
02617 /*                                                                    */
02618 /* This computes C = A x 10**B where B is an integer (q=0) with       */
02619 /* maximum magnitude 2*(emax+digits)                                  */
02620 /*                                                                    */
02621 /*   res is C, the result.  C may be A or B                           */
02622 /*   lhs is A, the number to adjust                                   */
02623 /*   rhs is B, the requested power of ten to use                      */
02624 /*   set is the context                                               */
02625 /*                                                                    */
02626 /* C must have space for set->digits digits.                          */
02627 /*                                                                    */
02628 /* The result may underflow or overflow.                              */
02629 /* ------------------------------------------------------------------ */
02630 decNumber * decNumberScaleB(decNumber *res, const decNumber *lhs,
02631                             const decNumber *rhs, decContext *set) {
02632   Int  reqexp;                // requested exponent change [B]
02633   uInt status=0;              // accumulator
02634   Int  residue;               // work
02635
02636   #if DECCHECK
02637   if (decCheckOperands(res, lhs, rhs, set)) return res;
02638   #endif
02639
02640   // Handle special values except lhs infinite
02641   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02642     decNaNs(res, lhs, rhs, set, &status);
02643     // rhs must be an integer
02644    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02645     status=DEC_Invalid_operation;
02646    else {
02647     // lhs is a number; rhs is a finite with q==0
02648     reqexp=decGetInt(rhs);                   // [cannot fail]
02649     if (reqexp==BADINT                       // something bad ..
02650      || reqexp==BIGODD || reqexp==BIGEVEN    // .. very big ..
02651      || abs(reqexp)>(2*(set->digits+set->emax))) // .. or out of range
02652       status=DEC_Invalid_operation;
02653      else {                                  // rhs is OK
02654       decNumberCopy(res, lhs);               // all done if infinite lhs
02655       if (!decNumberIsInfinite(res)) {       // prepare to scale
02656         res->exponent+=reqexp;               // adjust the exponent
02657         residue=0;
02658         decFinalize(res, set, &residue, &status); // .. and check
02659         } // finite LHS
02660       } // rhs OK
02661     } // rhs finite
02662   if (status!=0) decStatus(res, status, set);
02663   return res;
02664   } // decNumberScaleB
02665
02666 /* ------------------------------------------------------------------ */
02667 /* decNumberShift -- shift the coefficient of a Number left or right  */
02668 /*                                                                    */
02669 /*   This computes C = A << B or C = A >> -B  (in base ten).          */
02670 /*                                                                    */
02671 /*   res is C, the result.  C may be A and/or B (e.g., X=X<<X)        */
02672 /*   lhs is A                                                         */
02673 /*   rhs is B, the number of digits to shift (-ve to right)           */
02674 /*   set is the context                                               */
02675 /*                                                                    */
02676 /* The digits of the coefficient of A are shifted to the left (if B   */
02677 /* is positive) or to the right (if B is negative) without adjusting  */
02678 /* the exponent or the sign of A.                                     */
02679 /*                                                                    */
02680 /* B must be an integer (q=0) and in the range -set->digits through   */
02681 /* +set->digits.                                                      */
02682 /* C must have space for set->digits digits.                          */
02683 /* NaNs are propagated as usual.  Infinities are unaffected (but      */
02684 /* B must be valid).  No status is set unless B is invalid or an      */
02685 /* operand is an sNaN.                                                */
02686 /* ------------------------------------------------------------------ */
02687 decNumber * decNumberShift(decNumber *res, const decNumber *lhs,
02688                            const decNumber *rhs, decContext *set) {
02689   uInt status=0;              // accumulator
02690   Int  shift;                 // rhs as an Int
02691
02692   #if DECCHECK
02693   if (decCheckOperands(res, lhs, rhs, set)) return res;
02694   #endif
02695
02696   // NaNs propagate as normal
02697   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02698     decNaNs(res, lhs, rhs, set, &status);
02699    // rhs must be an integer
02700    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02701     status=DEC_Invalid_operation;
02702    else { // both numeric, rhs is an integer
02703     shift=decGetInt(rhs);                    // [cannot fail]
02704     if (shift==BADINT                        // something bad ..
02705      || shift==BIGODD || shift==BIGEVEN      // .. very big ..
02706      || abs(shift)>set->digits)              // .. or out of range
02707       status=DEC_Invalid_operation;
02708      else {                                  // rhs is OK
02709       decNumberCopy(res, lhs);
02710       if (shift!=0 && !decNumberIsInfinite(res)) { // something to do
02711         if (shift>0) {                       // to left
02712           if (shift==set->digits) {          // removing all
02713             *res->lsu=0;                     // so place 0
02714             res->digits=1;                   // ..
02715             }
02716            else {                            //
02717             // first remove leading digits if necessary
02718             if (res->digits+shift>set->digits) {
02719               decDecap(res, res->digits+shift-set->digits);
02720               // that updated res->digits; may have gone to 1 (for a
02721               // single digit or for zero
02722               }
02723             if (res->digits>1 || *res->lsu)  // if non-zero..
02724               res->digits=decShiftToMost(res->lsu, res->digits, shift);
02725             } // partial left
02726           } // left
02727          else { // to right
02728           if (-shift>=res->digits) {         // discarding all
02729             *res->lsu=0;                     // so place 0
02730             res->digits=1;                   // ..
02731             }
02732            else {
02733             decShiftToLeast(res->lsu, D2U(res->digits), -shift);
02734             res->digits-=(-shift);
02735             }
02736           } // to right
02737         } // non-0 non-Inf shift
02738       } // rhs OK
02739     } // numerics
02740   if (status!=0) decStatus(res, status, set);
02741   return res;
02742   } // decNumberShift
02743
02744 /* ------------------------------------------------------------------ */
02745 /* decNumberSquareRoot -- square root operator                        */
02746 /*                                                                    */
02747 /*   This computes C = squareroot(A)                                  */
02748 /*                                                                    */
02749 /*   res is C, the result.  C may be A                                */
02750 /*   rhs is A                                                         */
02751 /*   set is the context; note that rounding mode has no effect        */
02752 /*                                                                    */
02753 /* C must have space for set->digits digits.                          */
02754 /* ------------------------------------------------------------------ */
02755 /* This uses the following varying-precision algorithm in:            */
02756 /*                                                                    */
02757 /*   Properly Rounded Variable Precision Square Root, T. E. Hull and  */
02758 /*   A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */
02759 /*   pp229-237, ACM, September 1985.                                  */
02760 /*                                                                    */
02761 /* The square-root is calculated using Newton's method, after which   */
02762 /* a check is made to ensure the result is correctly rounded.         */
02763 /*                                                                    */
02764 /* % [Reformatted original Numerical Turing source code follows.]     */
02765 /* function sqrt(x : real) : real                                     */
02766 /* % sqrt(x) returns the properly rounded approximation to the square */
02767 /* % root of x, in the precision of the calling environment, or it    */
02768 /* % fails if x < 0.                                                  */
02769 /* % t e hull and a abrham, august, 1984                              */
02770 /* if x <= 0 then                                                     */
02771 /*   if x < 0 then                                                    */
02772 /*     assert false                                                   */
02773 /*   else                                                             */
02774 /*     result 0                                                       */
02775 /*   end if                                                           */
02776 /* end if                                                             */
02777 /* var f := setexp(x, 0)  % fraction part of x   [0.1 <= x < 1]       */
02778 /* var e := getexp(x)     % exponent part of x                        */
02779 /* var approx : real                                                  */
02780 /* if e mod 2 = 0  then                                               */
02781 /*   approx := .259 + .819 * f   % approx to root of f                */
02782 /* else                                                               */
02783 /*   f := f/l0                   % adjustments                        */
02784 /*   e := e + 1                  %   for odd                          */
02785 /*   approx := .0819 + 2.59 * f  %   exponent                         */
02786 /* end if                                                             */
02787 /*                                                                    */
02788 /* var p:= 3                                                          */
02789 /* const maxp := currentprecision + 2                                 */
02790 /* loop                                                               */
02791 /*   p := min(2*p - 2, maxp)     % p = 4,6,10, . . . , maxp           */
02792 /*   precision p                                                      */
02793 /*   approx := .5 * (approx + f/approx)                               */
02794 /*   exit when p = maxp                                               */
02795 /* end loop                                                           */
02796 /*                                                                    */
02797 /* % approx is now within 1 ulp of the properly rounded square root   */
02798 /* % of f; to ensure proper rounding, compare squares of (approx -    */
02799 /* % l/2 ulp) and (approx + l/2 ulp) with f.                          */
02800 /* p := currentprecision                                              */
02801 /* begin                                                              */
02802 /*   precision p + 2                                                  */
02803 /*   const approxsubhalf := approx - setexp(.5, -p)                   */
02804 /*   if mulru(approxsubhalf, approxsubhalf) > f then                  */
02805 /*     approx := approx - setexp(.l, -p + 1)                          */
02806 /*   else                                                             */
02807 /*     const approxaddhalf := approx + setexp(.5, -p)                 */
02808 /*     if mulrd(approxaddhalf, approxaddhalf) < f then                */
02809 /*       approx := approx + setexp(.l, -p + 1)                        */
02810 /*     end if                                                         */
02811 /*   end if                                                           */
02812 /* end                                                                */
02813 /* result setexp(approx, e div 2)  % fix exponent                     */
02814 /* end sqrt                                                           */
02815 /* ------------------------------------------------------------------ */
02816 decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
02817                                 decContext *set) {
02818   decContext workset, approxset;   // work contexts
02819   decNumber dzero;                 // used for constant zero
02820   Int  maxp;                       // largest working precision
02821   Int  workp;                      // working precision
02822   Int  residue=0;                  // rounding residue
02823   uInt status=0, ignore=0;         // status accumulators
02824   uInt rstatus;                    // ..
02825   Int  exp;                        // working exponent
02826   Int  ideal;                      // ideal (preferred) exponent
02827   Int  needbytes;                  // work
02828   Int  dropped;                    // ..
02829
02830   #if DECSUBSET
02831   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
02832   #endif
02833   // buffer for f [needs +1 in case DECBUFFER 0]
02834   decNumber buff[D2N(DECBUFFER+1)];
02835   // buffer for a [needs +2 to match likely maxp]
02836   decNumber bufa[D2N(DECBUFFER+2)];
02837   // buffer for temporary, b [must be same size as a]
02838   decNumber bufb[D2N(DECBUFFER+2)];
02839   decNumber *allocbuff=NULL;       // -> allocated buff, iff allocated
02840   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
02841   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
02842   decNumber *f=buff;               // reduced fraction
02843   decNumber *a=bufa;               // approximation to result
02844   decNumber *b=bufb;               // intermediate result
02845   // buffer for temporary variable, up to 3 digits
02846   decNumber buft[D2N(3)];
02847   decNumber *t=buft;               // up-to-3-digit constant or work
02848
02849   #if DECCHECK
02850   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
02851   #endif
02852
02853   do {                             // protect allocated storage
02854     #if DECSUBSET
02855     if (!set->extended) {
02856       // reduce operand and set lostDigits status, as needed
02857       if (rhs->digits>set->digits) {
02858         allocrhs=decRoundOperand(rhs, set, &status);
02859         if (allocrhs==NULL) break;
02860         // [Note: 'f' allocation below could reuse this buffer if
02861         // used, but as this is rare they are kept separate for clarity.]
02862         rhs=allocrhs;
02863         }
02864       }
02865     #endif
02866     // [following code does not require input rounding]
02867
02868     // handle infinities and NaNs
02869     if (SPECIALARG) {
02870       if (decNumberIsInfinite(rhs)) {         // an infinity
02871         if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
02872          else decNumberCopy(res, rhs);        // +Infinity
02873         }
02874        else decNaNs(res, rhs, NULL, set, &status); // a NaN
02875       break;
02876       }
02877
02878     // calculate the ideal (preferred) exponent [floor(exp/2)]
02879     // [It would be nicer to write: ideal=rhs->exponent>>1, but this
02880     // generates a compiler warning.  Generated code is the same.]
02881     ideal=(rhs->exponent&~1)/2;         // target
02882
02883     // handle zeros
02884     if (ISZERO(rhs)) {
02885       decNumberCopy(res, rhs);          // could be 0 or -0
02886       res->exponent=ideal;              // use the ideal [safe]
02887       // use decFinish to clamp any out-of-range exponent, etc.
02888       decFinish(res, set, &residue, &status);
02889       break;
02890       }
02891
02892     // any other -x is an oops
02893     if (decNumberIsNegative(rhs)) {
02894       status|=DEC_Invalid_operation;
02895       break;
02896       }
02897
02898     // space is needed for three working variables
02899     //   f -- the same precision as the RHS, reduced to 0.01->0.99...
02900     //   a -- Hull's approximation -- precision, when assigned, is
02901     //        currentprecision+1 or the input argument precision,
02902     //        whichever is larger (+2 for use as temporary)
02903     //   b -- intermediate temporary result (same size as a)
02904     // if any is too long for local storage, then allocate
02905     workp=MAXI(set->digits+1, rhs->digits);  // actual rounding precision
02906     workp=MAXI(workp, 7);                    // at least 7 for low cases
02907     maxp=workp+2;                            // largest working precision
02908
02909     needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
02910     if (needbytes>(Int)sizeof(buff)) {
02911       allocbuff=(decNumber *)malloc(needbytes);
02912       if (allocbuff==NULL) {  // hopeless -- abandon
02913         status|=DEC_Insufficient_storage;
02914         break;}
02915       f=allocbuff;            // use the allocated space
02916       }
02917     // a and b both need to be able to hold a maxp-length number
02918     needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
02919     if (needbytes>(Int)sizeof(bufa)) {            // [same applies to b]
02920       allocbufa=(decNumber *)malloc(needbytes);
02921       allocbufb=(decNumber *)malloc(needbytes);
02922       if (allocbufa==NULL || allocbufb==NULL) {   // hopeless
02923         status|=DEC_Insufficient_storage;
02924         break;}
02925       a=allocbufa;            // use the allocated spaces
02926       b=allocbufb;            // ..
02927       }
02928
02929     // copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1
02930     decNumberCopy(f, rhs);
02931     exp=f->exponent+f->digits;               // adjusted to Hull rules
02932     f->exponent=-(f->digits);                // to range
02933
02934     // set up working context
02935     decContextDefault(&workset, DEC_INIT_DECIMAL64);
02936     workset.emax=DEC_MAX_EMAX;
02937     workset.emin=DEC_MIN_EMIN;
02938
02939     // [Until further notice, no error is possible and status bits
02940     // (Rounded, etc.) should be ignored, not accumulated.]
02941
02942     // Calculate initial approximation, and allow for odd exponent
02943     workset.digits=workp;                    // p for initial calculation
02944     t->bits=0; t->digits=3;
02945     a->bits=0; a->digits=3;
02946     if ((exp & 1)==0) {                      // even exponent
02947       // Set t=0.259, a=0.819
02948       t->exponent=-3;
02949       a->exponent=-3;
02950       #if DECDPUN>=3
02951         t->lsu[0]=259;
02952         a->lsu[0]=819;
02953       #elif DECDPUN==2
02954         t->lsu[0]=59; t->lsu[1]=2;
02955         a->lsu[0]=19; a->lsu[1]=8;
02956       #else
02957         t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
02958         a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
02959       #endif
02960       }
02961      else {                                  // odd exponent
02962       // Set t=0.0819, a=2.59
02963       f->exponent--;                         // f=f/10
02964       exp++;                                 // e=e+1
02965       t->exponent=-4;
02966       a->exponent=-2;
02967       #if DECDPUN>=3
02968         t->lsu[0]=819;
02969         a->lsu[0]=259;
02970       #elif DECDPUN==2
02971         t->lsu[0]=19; t->lsu[1]=8;
02972         a->lsu[0]=59; a->lsu[1]=2;
02973       #else
02974         t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
02975         a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
02976       #endif
02977       }
02978
02979     decMultiplyOp(a, a, f, &workset, &ignore);    // a=a*f
02980     decAddOp(a, a, t, &workset, 0, &ignore);      // ..+t
02981     // [a is now the initial approximation for sqrt(f), calculated with
02982     // currentprecision, which is also a's precision.]
02983
02984     // the main calculation loop
02985     decNumberZero(&dzero);                   // make 0
02986     decNumberZero(t);                        // set t = 0.5
02987     t->lsu[0]=5;                             // ..
02988     t->exponent=-1;                          // ..
02989     workset.digits=3;                        // initial p
02990     for (; workset.digits<maxp;) {
02991       // set p to min(2*p - 2, maxp)  [hence 3; or: 4, 6, 10, ... , maxp]
02992       workset.digits=MINI(workset.digits*2-2, maxp);
02993       // a = 0.5 * (a + f/a)
02994       // [calculated at p then rounded to currentprecision]
02995       decDivideOp(b, f, a, &workset, DIVIDE, &ignore); // b=f/a
02996       decAddOp(b, b, a, &workset, 0, &ignore);         // b=b+a
02997       decMultiplyOp(a, b, t, &workset, &ignore);       // a=b*0.5
02998       } // loop
02999
03000     // Here, 0.1 <= a < 1 [Hull], and a has maxp digits
03001     // now reduce to length, etc.; this needs to be done with a
03002     // having the correct exponent so as to handle subnormals
03003     // correctly
03004     approxset=*set;                          // get emin, emax, etc.
03005     approxset.round=DEC_ROUND_HALF_EVEN;
03006     a->exponent+=exp/2;                      // set correct exponent
03007     rstatus=0;                               // clear status
03008     residue=0;                               // .. and accumulator
03009     decCopyFit(a, a, &approxset, &residue, &rstatus);  // reduce (if needed)
03010     decFinish(a, &approxset, &residue, &rstatus);      // clean and finalize
03011
03012     // Overflow was possible if the input exponent was out-of-range,
03013     // in which case quit
03014     if (rstatus&DEC_Overflow) {
03015       status=rstatus;                        // use the status as-is
03016       decNumberCopy(res, a);                 // copy to result
03017       break;
03018       }
03019
03020     // Preserve status except Inexact/Rounded
03021     status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));
03022
03023     // Carry out the Hull correction
03024     a->exponent-=exp/2;                      // back to 0.1->1
03025
03026     // a is now at final precision and within 1 ulp of the properly
03027     // rounded square root of f; to ensure proper rounding, compare
03028     // squares of (a - l/2 ulp) and (a + l/2 ulp) with f.
03029     // Here workset.digits=maxp and t=0.5, and a->digits determines
03030     // the ulp
03031     workset.digits--;                             // maxp-1 is OK now
03032     t->exponent=-a->digits-1;                     // make 0.5 ulp
03033     decAddOp(b, a, t, &workset, DECNEG, &ignore); // b = a - 0.5 ulp
03034     workset.round=DEC_ROUND_UP;
03035     decMultiplyOp(b, b, b, &workset, &ignore);    // b = mulru(b, b)
03036     decCompareOp(b, f, b, &workset, COMPARE, &ignore); // b ? f, reversed
03037     if (decNumberIsNegative(b)) {                 // f < b [i.e., b > f]
03038       // this is the more common adjustment, though both are rare
03039       t->exponent++;                              // make 1.0 ulp
03040       t->lsu[0]=1;                                // ..
03041       decAddOp(a, a, t, &workset, DECNEG, &ignore); // a = a - 1 ulp
03042       // assign to approx [round to length]
03043       approxset.emin-=exp/2;                      // adjust to match a
03044       approxset.emax-=exp/2;
03045       decAddOp(a, &dzero, a, &approxset, 0, &ignore);
03046       }
03047      else {
03048       decAddOp(b, a, t, &workset, 0, &ignore);    // b = a + 0.5 ulp
03049       workset.round=DEC_ROUND_DOWN;
03050       decMultiplyOp(b, b, b, &workset, &ignore);  // b = mulrd(b, b)
03051       decCompareOp(b, b, f, &workset, COMPARE, &ignore);   // b ? f
03052       if (decNumberIsNegative(b)) {               // b < f
03053         t->exponent++;                            // make 1.0 ulp
03054         t->lsu[0]=1;                              // ..
03055         decAddOp(a, a, t, &workset, 0, &ignore);  // a = a + 1 ulp
03056         // assign to approx [round to length]
03057         approxset.emin-=exp/2;                    // adjust to match a
03058         approxset.emax-=exp/2;
03059         decAddOp(a, &dzero, a, &approxset, 0, &ignore);
03060         }
03061       }
03062     // [no errors are possible in the above, and rounding/inexact during
03063     // estimation are irrelevant, so status was not accumulated]
03064
03065     // Here, 0.1 <= a < 1  (still), so adjust back
03066     a->exponent+=exp/2;                      // set correct exponent
03067
03068     // count droppable zeros [after any subnormal rounding] by
03069     // trimming a copy
03070     decNumberCopy(b, a);
03071     decTrim(b, set, 1, 1, &dropped);         // [drops trailing zeros]
03072
03073     // Set Inexact and Rounded.  The answer can only be exact if
03074     // it is short enough so that squaring it could fit in workp
03075     // digits, so this is the only (relatively rare) condition that
03076     // a careful check is needed
03077     if (b->digits*2-1 > workp) {             // cannot fit
03078       status|=DEC_Inexact|DEC_Rounded;
03079       }
03080      else {                                  // could be exact/unrounded
03081       uInt mstatus=0;                        // local status
03082       decMultiplyOp(b, b, b, &workset, &mstatus); // try the multiply
03083       if (mstatus&DEC_Overflow) {            // result just won't fit
03084         status|=DEC_Inexact|DEC_Rounded;
03085         }
03086        else {                                // plausible
03087         decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); // b ? rhs
03088         if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; // not equal
03089          else {                              // is Exact
03090           // here, dropped is the count of trailing zeros in 'a'
03091           // use closest exponent to ideal...
03092           Int todrop=ideal-a->exponent;      // most that can be dropped
03093           if (todrop<0) status|=DEC_Rounded; // ideally would add 0s
03094            else {                            // unrounded
03095             // there are some to drop, but emax may not allow all
03096             Int maxexp=set->emax-set->digits+1;
03097             Int maxdrop=maxexp-a->exponent;
03098             if (todrop>maxdrop && set->clamp) { // apply clamping
03099               todrop=maxdrop;
03100               status|=DEC_Clamped;
03101               }
03102             if (dropped<todrop) {            // clamp to those available
03103               todrop=dropped;
03104               status|=DEC_Clamped;
03105               }
03106             if (todrop>0) {                  // have some to drop
03107               decShiftToLeast(a->lsu, D2U(a->digits), todrop);
03108               a->exponent+=todrop;           // maintain numerical value
03109               a->digits-=todrop;             // new length
03110               }
03111             }
03112           }
03113         }
03114       }
03115
03116     // double-check Underflow, as perhaps the result could not have
03117     // been subnormal (initial argument too big), or it is now Exact
03118     if (status&DEC_Underflow) {
03119       Int ae=rhs->exponent+rhs->digits-1;    // adjusted exponent
03120       // check if truly subnormal
03121       #if DECEXTFLAG                         // DEC_Subnormal too
03122         if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow);
03123       #else
03124         if (ae>=set->emin*2) status&=~DEC_Underflow;
03125       #endif
03126       // check if truly inexact
03127       if (!(status&DEC_Inexact)) status&=~DEC_Underflow;
03128       }
03129
03130     decNumberCopy(res, a);                   // a is now the result
03131     } while(0);                              // end protected
03132
03133   if (allocbuff!=NULL) free(allocbuff);      // drop any storage used
03134   if (allocbufa!=NULL) free(allocbufa);      // ..
03135   if (allocbufb!=NULL) free(allocbufb);      // ..
03136   #if DECSUBSET
03137   if (allocrhs !=NULL) free(allocrhs);       // ..
03138   #endif
03139   if (status!=0) decStatus(res, status, set);// then report status
03140   #if DECCHECK
03141   decCheckInexact(res, set);
03142   #endif
03143   return res;
03144   } // decNumberSquareRoot
03145
03146 /* ------------------------------------------------------------------ */
03147 /* decNumberSubtract -- subtract two Numbers                          */
03148 /*                                                                    */
03149 /*   This computes C = A - B                                          */
03150 /*                                                                    */
03151 /*   res is C, the result.  C may be A and/or B (e.g., X=X-X)         */
03152 /*   lhs is A                                                         */
03153 /*   rhs is B                                                         */
03154 /*   set is the context                                               */
03155 /*                                                                    */
03156 /* C must have space for set->digits digits.                          */
03157 /* ------------------------------------------------------------------ */
03158 decNumber * decNumberSubtract(decNumber *res, const decNumber *lhs,
03159                               const decNumber *rhs, decContext *set) {
03160   uInt status=0;                        // accumulator
03161
03162   decAddOp(res, lhs, rhs, set, DECNEG, &status);
03163   if (status!=0) decStatus(res, status, set);
03164   #if DECCHECK
03165   decCheckInexact(res, set);
03166   #endif
03167   return res;
03168   } // decNumberSubtract
03169
03170 /* ------------------------------------------------------------------ */
03171 /* decNumberToIntegralExact -- round-to-integral-value with InExact   */
03172 /* decNumberToIntegralValue -- round-to-integral-value                */
03173 /*                                                                    */
03174 /*   res is the result                                                */
03175 /*   rhs is input number                                              */
03176 /*   set is the context                                               */
03177 /*                                                                    */
03178 /* res must have space for any value of rhs.                          */
03179 /*                                                                    */
03180 /* This implements the IEEE special operators and therefore treats    */
03181 /* special values as valid.  For finite numbers it returns            */
03182 /* rescale(rhs, 0) if rhs->exponent is <0.                            */
03183 /* Otherwise the result is rhs (so no error is possible, except for   */
03184 /* sNaN).                                                             */
03185 /*                                                                    */
03186 /* The context is used for rounding mode and status after sNaN, but   */
03187 /* the digits setting is ignored.  The Exact version will signal      */
03188 /* Inexact if the result differs numerically from rhs; the other      */
03189 /* never signals Inexact.                                             */
03190 /* ------------------------------------------------------------------ */
03191 decNumber * decNumberToIntegralExact(decNumber *res, const decNumber *rhs,
03192                                      decContext *set) {
03193   decNumber dn;
03194   decContext workset;              // working context
03195   uInt status=0;                   // accumulator
03196
03197   #if DECCHECK
03198   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
03199   #endif
03200
03201   // handle infinities and NaNs
03202   if (SPECIALARG) {
03203     if (decNumberIsInfinite(rhs)) decNumberCopy(res, rhs); // an Infinity
03204      else decNaNs(res, rhs, NULL, set, &status); // a NaN
03205     }
03206    else { // finite
03207     // have a finite number; no error possible (res must be big enough)
03208     if (rhs->exponent>=0) return decNumberCopy(res, rhs);
03209     // that was easy, but if negative exponent there is work to do...
03210     workset=*set;                  // clone rounding, etc.
03211     workset.digits=rhs->digits;    // no length rounding
03212     workset.traps=0;               // no traps
03213     decNumberZero(&dn);            // make a number with exponent 0
03214     decNumberQuantize(res, rhs, &dn, &workset);
03215     status|=workset.status;
03216     }
03217   if (status!=0) decStatus(res, status, set);
03218   return res;
03219   } // decNumberToIntegralExact
03220
03221 decNumber * decNumberToIntegralValue(decNumber *res, const decNumber *rhs,
03222                                      decContext *set) {
03223   decContext workset=*set;         // working context
03224   workset.traps=0;                 // no traps
03225   decNumberToIntegralExact(res, rhs, &workset);
03226   // this never affects set, except for sNaNs; NaN will have been set
03227   // or propagated already, so no need to call decStatus
03228   set->status|=workset.status&DEC_Invalid_operation;
03229   return res;
03230   } // decNumberToIntegralValue
03231
03232 /* ------------------------------------------------------------------ */
03233 /* decNumberXor -- XOR two Numbers, digitwise                         */
03234 /*                                                                    */
03235 /*   This computes C = A ^ B                                          */
03236 /*                                                                    */
03237 /*   res is C, the result.  C may be A and/or B (e.g., X=X^X)         */
03238 /*   lhs is A                                                         */
03239 /*   rhs is B                                                         */
03240 /*   set is the context (used for result length and error report)     */
03241 /*                                                                    */
03242 /* C must have space for set->digits digits.                          */
03243 /*                                                                    */
03244 /* Logical function restrictions apply (see above); a NaN is          */
03245 /* returned with Invalid_operation if a restriction is violated.      */
03246 /* ------------------------------------------------------------------ */
03247 decNumber * decNumberXor(decNumber *res, const decNumber *lhs,
03248                          const decNumber *rhs, decContext *set) {
03249   const Unit *ua, *ub;                  // -> operands
03250   const Unit *msua, *msub;              // -> operand msus
03251   Unit  *uc, *msuc;                     // -> result and its msu
03252   Int   msudigs;                        // digits in res msu
03253   #if DECCHECK
03254   if (decCheckOperands(res, lhs, rhs, set)) return res;
03255   #endif
03256
03257   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
03258    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
03259     decStatus(res, DEC_Invalid_operation, set);
03260     return res;
03261     }
03262   // operands are valid
03263   ua=lhs->lsu;                          // bottom-up
03264   ub=rhs->lsu;                          // ..
03265   uc=res->lsu;                          // ..
03266   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
03267   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
03268   msuc=uc+D2U(set->digits)-1;           // -> msu of result
03269   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
03270   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
03271     Unit a, b;                          // extract units
03272     if (ua>msua) a=0;
03273      else a=*ua;
03274     if (ub>msub) b=0;
03275      else b=*ub;
03276     *uc=0;                              // can now write back
03277     if (a|b) {                          // maybe 1 bits to examine
03278       Int i, j;
03279       // This loop could be unrolled and/or use BIN2BCD tables
03280       for (i=0; i<DECDPUN; i++) {
03281         if ((a^b)&1) *uc=*uc+(Unit)powers[i];     // effect XOR
03282         j=a%10;
03283         a=a/10;
03284         j|=b%10;
03285         b=b/10;
03286         if (j>1) {
03287           decStatus(res, DEC_Invalid_operation, set);
03288           return res;
03289           }
03290         if (uc==msuc && i==msudigs-1) break;      // just did final digit
03291         } // each digit
03292       } // non-zero
03293     } // each unit
03294   // [here uc-1 is the msu of the result]
03295   res->digits=decGetDigits(res->lsu, uc-res->lsu);
03296   res->exponent=0;                      // integer
03297   res->bits=0;                          // sign=0
03298   return res;  // [no status to set]
03299   } // decNumberXor
03300
03301
03302 /* ================================================================== */
03303 /* Utility routines                                                   */
03304 /* ================================================================== */
03305
03306 /* ------------------------------------------------------------------ */
03307 /* decNumberClass -- return the decClass of a decNumber               */
03308 /*   dn -- the decNumber to test                                      */
03309 /*   set -- the context to use for Emin                               */
03310 /*   returns the decClass enum                                        */
03311 /* ------------------------------------------------------------------ */
03312 enum decClass decNumberClass(const decNumber *dn, decContext *set) {
03313   if (decNumberIsSpecial(dn)) {
03314     if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN;
03315     if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN;
03316     // must be an infinity
03317     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF;
03318     return DEC_CLASS_POS_INF;
03319     }
03320   // is finite
03321   if (decNumberIsNormal(dn, set)) { // most common
03322     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL;
03323     return DEC_CLASS_POS_NORMAL;
03324     }
03325   // is subnormal or zero
03326   if (decNumberIsZero(dn)) {    // most common
03327     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO;
03328     return DEC_CLASS_POS_ZERO;
03329     }
03330   if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL;
03331   return DEC_CLASS_POS_SUBNORMAL;
03332   } // decNumberClass
03333
03334 /* ------------------------------------------------------------------ */
03335 /* decNumberClassToString -- convert decClass to a string             */
03336 /*                                                                    */
03337 /*  eclass is a valid decClass                                        */
03338 /*  returns a constant string describing the class (max 13+1 chars)   */
03339 /* ------------------------------------------------------------------ */
03340 const char *decNumberClassToString(enum decClass eclass) {
03341   if (eclass==DEC_CLASS_POS_NORMAL)    return DEC_ClassString_PN;
03342   if (eclass==DEC_CLASS_NEG_NORMAL)    return DEC_ClassString_NN;
03343   if (eclass==DEC_CLASS_POS_ZERO)      return DEC_ClassString_PZ;
03344   if (eclass==DEC_CLASS_NEG_ZERO)      return DEC_ClassString_NZ;
03345   if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS;
03346   if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS;
03347   if (eclass==DEC_CLASS_POS_INF)       return DEC_ClassString_PI;
03348   if (eclass==DEC_CLASS_NEG_INF)       return DEC_ClassString_NI;
03349   if (eclass==DEC_CLASS_QNAN)          return DEC_ClassString_QN;
03350   if (eclass==DEC_CLASS_SNAN)          return DEC_ClassString_SN;
03351   return DEC_ClassString_UN;           // Unknown
03352   } // decNumberClassToString
03353
03354 /* ------------------------------------------------------------------ */
03355 /* decNumberCopy -- copy a number                                     */
03356 /*                                                                    */
03357 /*   dest is the target decNumber                                     */
03358 /*   src  is the source decNumber                                     */
03359 /*   returns dest                                                     */
03360 /*                                                                    */
03361 /* (dest==src is allowed and is a no-op)                              */
03362 /* All fields are updated as required.  This is a utility operation,  */
03363 /* so special values are unchanged and no error is possible.          */
03364 /* ------------------------------------------------------------------ */
03365 decNumber * decNumberCopy(decNumber *dest, const decNumber *src) {
03366
03367   #if DECCHECK
03368   if (src==NULL) return decNumberZero(dest);
03369   #endif
03370
03371   if (dest==src) return dest;                // no copy required
03372
03373   // Use explicit assignments here as structure assignment could copy
03374   // more than just the lsu (for small DECDPUN).  This would not affect
03375   // the value of the results, but could disturb test harness spill
03376   // checking.
03377   dest->bits=src->bits;
03378   dest->exponent=src->exponent;
03379   dest->digits=src->digits;
03380   dest->lsu[0]=src->lsu[0];
03381   if (src->digits>DECDPUN) {                 // more Units to come
03382     const Unit *smsup, *s;                   // work
03383     Unit  *d;                                // ..
03384     // memcpy for the remaining Units would be safe as they cannot
03385     // overlap.  However, this explicit loop is faster in short cases.
03386     d=dest->lsu+1;                           // -> first destination
03387     smsup=src->lsu+D2U(src->digits);         // -> source msu+1
03388     for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
03389     }
03390   return dest;
03391   } // decNumberCopy
03392
03393 /* ------------------------------------------------------------------ */
03394 /* decNumberCopyAbs -- quiet absolute value operator                  */
03395 /*                                                                    */
03396 /*   This sets C = abs(A)                                             */
03397 /*                                                                    */
03398 /*   res is C, the result.  C may be A                                */
03399 /*   rhs is A                                                         */
03400 /*                                                                    */
03401 /* C must have space for set->digits digits.                          */
03402 /* No exception or error can occur; this is a quiet bitwise operation.*/
03403 /* See also decNumberAbs for a checking version of this.              */
03404 /* ------------------------------------------------------------------ */
03405 decNumber * decNumberCopyAbs(decNumber *res, const decNumber *rhs) {
03406   #if DECCHECK
03407   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03408   #endif
03409   decNumberCopy(res, rhs);
03410   res->bits&=~DECNEG;                   // turn off sign
03411   return res;
03412   } // decNumberCopyAbs
03413
03414 /* ------------------------------------------------------------------ */
03415 /* decNumberCopyNegate -- quiet negate value operator                 */
03416 /*                                                                    */
03417 /*   This sets C = negate(A)                                          */
03418 /*                                                                    */
03419 /*   res is C, the result.  C may be A                                */
03420 /*   rhs is A                                                         */
03421 /*                                                                    */
03422 /* C must have space for set->digits digits.                          */
03423 /* No exception or error can occur; this is a quiet bitwise operation.*/
03424 /* See also decNumberMinus for a checking version of this.            */
03425 /* ------------------------------------------------------------------ */
03426 decNumber * decNumberCopyNegate(decNumber *res, const decNumber *rhs) {
03427   #if DECCHECK
03428   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03429   #endif
03430   decNumberCopy(res, rhs);
03431   res->bits^=DECNEG;                    // invert the sign
03432   return res;
03433   } // decNumberCopyNegate
03434
03435 /* ------------------------------------------------------------------ */
03436 /* decNumberCopySign -- quiet copy and set sign operator              */
03437 /*                                                                    */
03438 /*   This sets C = A with the sign of B                               */
03439 /*                                                                    */
03440 /*   res is C, the result.  C may be A                                */
03441 /*   lhs is A                                                         */
03442 /*   rhs is B                                                         */
03443 /*                                                                    */
03444 /* C must have space for set->digits digits.                          */
03445 /* No exception or error can occur; this is a quiet bitwise operation.*/
03446 /* ------------------------------------------------------------------ */
03447 decNumber * decNumberCopySign(decNumber *res, const decNumber *lhs,
03448                               const decNumber *rhs) {
03449   uByte sign;                           // rhs sign
03450   #if DECCHECK
03451   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03452   #endif
03453   sign=rhs->bits & DECNEG;              // save sign bit
03454   decNumberCopy(res, lhs);
03455   res->bits&=~DECNEG;                   // clear the sign
03456   res->bits|=sign;                      // set from rhs
03457   return res;
03458   } // decNumberCopySign
03459
03460 /* ------------------------------------------------------------------ */
03461 /* decNumberGetBCD -- get the coefficient in BCD8                     */
03462 /*   dn is the source decNumber                                       */
03463 /*   bcd is the uInt array that will receive dn->digits BCD bytes,    */
03464 /*     most-significant at offset 0                                   */
03465 /*   returns bcd                                                      */
03466 /*                                                                    */
03467 /* bcd must have at least dn->digits bytes.  No error is possible; if */
03468 /* dn is a NaN or Infinite, digits must be 1 and the coefficient 0.   */
03469 /* ------------------------------------------------------------------ */
03470 uByte * decNumberGetBCD(const decNumber *dn, uByte *bcd) {
03471   uByte *ub=bcd+dn->digits-1;      // -> lsd
03472   const Unit *up=dn->lsu;          // Unit pointer, -> lsu
03473
03474   #if DECDPUN==1                   // trivial simple copy
03475     for (; ub>=bcd; ub--, up++) *ub=*up;
03476   #else                            // chopping needed
03477     uInt u=*up;                    // work
03478     uInt cut=DECDPUN;              // downcounter through unit
03479     for (; ub>=bcd; ub--) {
03480       *ub=(uByte)(u%10);           // [*6554 trick inhibits, here]
03481       u=u/10;
03482       cut--;
03483       if (cut>0) continue;         // more in this unit
03484       up++;
03485       u=*up;
03486       cut=DECDPUN;
03487       }
03488   #endif
03489   return bcd;
03490   } // decNumberGetBCD
03491
03492 /* ------------------------------------------------------------------ */
03493 /* decNumberSetBCD -- set (replace) the coefficient from BCD8         */
03494 /*   dn is the target decNumber                                       */
03495 /*   bcd is the uInt array that will source n BCD bytes, most-        */
03496 /*     significant at offset 0                                        */
03497 /*   n is the number of digits in the source BCD array (bcd)          */
03498 /*   returns dn                                                       */
03499 /*                                                                    */
03500 /* dn must have space for at least n digits.  No error is possible;   */
03501 /* if dn is a NaN, or Infinite, or is to become a zero, n must be 1   */
03502 /* and bcd[0] zero.                                                   */
03503 /* ------------------------------------------------------------------ */
03504 decNumber * decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) {
03505   Unit *up=dn->lsu+D2U(dn->digits)-1;   // -> msu [target pointer]
03506   const uByte *ub=bcd;                  // -> source msd
03507
03508   #if DECDPUN==1                        // trivial simple copy
03509     for (; ub<bcd+n; ub++, up--) *up=*ub;
03510   #else                                 // some assembly needed
03511     // calculate how many digits in msu, and hence first cut
03512     Int cut=MSUDIGITS(n);               // [faster than remainder]
03513     for (;up>=dn->lsu; up--) {          // each Unit from msu
03514       *up=0;                            // will take <=DECDPUN digits
03515       for (; cut>0; ub++, cut--) *up=X10(*up)+*ub;
03516       cut=DECDPUN;                      // next Unit has all digits
03517       }
03518   #endif
03519   dn->digits=n;                         // set digit count
03520   return dn;
03521   } // decNumberSetBCD
03522
03523 /* ------------------------------------------------------------------ */
03524 /* decNumberIsNormal -- test normality of a decNumber                 */
03525 /*   dn is the decNumber to test                                      */
03526 /*   set is the context to use for Emin                               */
03527 /*   returns 1 if |dn| is finite and >=Nmin, 0 otherwise              */
03528 /* ------------------------------------------------------------------ */
03529 Int decNumberIsNormal(const decNumber *dn, decContext *set) {
03530   Int ae;                               // adjusted exponent
03531   #if DECCHECK
03532   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
03533   #endif
03534
03535   if (decNumberIsSpecial(dn)) return 0; // not finite
03536   if (decNumberIsZero(dn)) return 0;    // not non-zero
03537
03538   ae=dn->exponent+dn->digits-1;         // adjusted exponent
03539   if (ae<set->emin) return 0;           // is subnormal
03540   return 1;
03541   } // decNumberIsNormal
03542
03543 /* ------------------------------------------------------------------ */
03544 /* decNumberIsSubnormal -- test subnormality of a decNumber           */
03545 /*   dn is the decNumber to test                                      */
03546 /*   set is the context to use for Emin                               */
03547 /*   returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise    */
03548 /* ------------------------------------------------------------------ */
03549 Int decNumberIsSubnormal(const decNumber *dn, decContext *set) {
03550   Int ae;                               // adjusted exponent
03551   #if DECCHECK
03552   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
03553   #endif
03554
03555   if (decNumberIsSpecial(dn)) return 0; // not finite
03556   if (decNumberIsZero(dn)) return 0;    // not non-zero
03557
03558   ae=dn->exponent+dn->digits-1;         // adjusted exponent
03559   if (ae<set->emin) return 1;           // is subnormal
03560   return 0;
03561   } // decNumberIsSubnormal
03562
03563 /* ------------------------------------------------------------------ */
03564 /* decNumberTrim -- remove insignificant zeros                        */
03565 /*                                                                    */
03566 /*   dn is the number to trim                                         */
03567 /*   returns dn                                                       */
03568 /*                                                                    */
03569 /* All fields are updated as required.  This is a utility operation,  */
03570 /* so special values are unchanged and no error is possible.  The     */
03571 /* zeros are removed unconditionally.                                 */
03572 /* ------------------------------------------------------------------ */
03573 decNumber * decNumberTrim(decNumber *dn) {
03574   Int  dropped;                    // work
03575   decContext set;                  // ..
03576   #if DECCHECK
03577   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
03578   #endif
03579   decContextDefault(&set, DEC_INIT_BASE);    // clamp=0
03580   return decTrim(dn, &set, 0, 1, &dropped);
03581   } // decNumberTrim
03582
03583 /* ------------------------------------------------------------------ */
03584 /* decNumberVersion -- return the name and version of this module     */
03585 /*                                                                    */
03586 /* No error is possible.                                              */
03587 /* ------------------------------------------------------------------ */
03588 const char * decNumberVersion(void) {
03589   return DECVERSION;
03590   } // decNumberVersion
03591
03592 /* ------------------------------------------------------------------ */
03593 /* decNumberZero -- set a number to 0                                 */
03594 /*                                                                    */
03595 /*   dn is the number to set, with space for one digit                */
03596 /*   returns dn                                                       */
03597 /*                                                                    */
03598 /* No error is possible.                                              */
03599 /* ------------------------------------------------------------------ */
03600 // Memset is not used as it is much slower in some environments.
03601 decNumber * decNumberZero(decNumber *dn) {
03602
03603   #if DECCHECK
03604   if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
03605   #endif
03606
03607   dn->bits=0;
03608   dn->exponent=0;
03609   dn->digits=1;
03610   dn->lsu[0]=0;
03611   return dn;
03612   } // decNumberZero
03613
03614 /* ================================================================== */
03615 /* Local routines                                                     */
03616 /* ================================================================== */
03617
03618 /* ------------------------------------------------------------------ */
03619 /* decToString -- lay out a number into a string                      */
03620 /*                                                                    */
03621 /*   dn     is the number to lay out                                  */
03622 /*   string is where to lay out the number                            */
03623 /*   eng    is 1 if Engineering, 0 if Scientific                      */
03624 /*                                                                    */
03625 /* string must be at least dn->digits+14 characters long              */
03626 /* No error is possible.                                              */
03627 /*                                                                    */
03628 /* Note that this routine can generate a -0 or 0.000.  These are      */
03629 /* never generated in subset to-number or arithmetic, but can occur   */
03630 /* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234).              */
03631 /* ------------------------------------------------------------------ */
03632 // If DECCHECK is enabled the string "?" is returned if a number is
03633 // invalid.
03634 static void decToString(const decNumber *dn, char *string, Flag eng) {
03635   Int exp=dn->exponent;       // local copy
03636   Int e;                      // E-part value
03637   Int pre;                    // digits before the '.'
03638   Int cut;                    // for counting digits in a Unit
03639   char *c=string;             // work [output pointer]
03640   const Unit *up=dn->lsu+D2U(dn->digits)-1; // -> msu [input pointer]
03641   uInt u, pow;                // work
03642
03643   #if DECCHECK
03644   if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
03645     strcpy(string, "?");
03646     return;}
03647   #endif
03648
03649   if (decNumberIsNegative(dn)) {   // Negatives get a minus
03650     *c='-';
03651     c++;
03652     }
03653   if (dn->bits&DECSPECIAL) {       // Is a special value
03654     if (decNumberIsInfinite(dn)) {
03655       strcpy(c,   "Inf");
03656       strcpy(c+3, "inity");
03657       return;}
03658     // a NaN
03659     if (dn->bits&DECSNAN) {        // signalling NaN
03660       *c='s';
03661       c++;
03662       }
03663     strcpy(c, "NaN");
03664     c+=3;                          // step past
03665     // if not a clean non-zero coefficient, that's all there is in a
03666     // NaN string
03667     if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;
03668     // [drop through to add integer]
03669     }
03670
03671   // calculate how many digits in msu, and hence first cut
03672   cut=MSUDIGITS(dn->digits);       // [faster than remainder]
03673   cut--;                           // power of ten for digit
03674
03675   if (exp==0) {                    // simple integer [common fastpath]
03676     for (;up>=dn->lsu; up--) {     // each Unit from msu
03677       u=*up;                       // contains DECDPUN digits to lay out
03678       for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);
03679       cut=DECDPUN-1;               // next Unit has all digits
03680       }
03681     *c='\0';                       // terminate the string
03682     return;}
03683
03684   /* non-0 exponent -- assume plain form */
03685   pre=dn->digits+exp;              // digits before '.'
03686   e=0;                             // no E
03687   if ((exp>0) || (pre<-5)) {       // need exponential form
03688     e=exp+dn->digits-1;            // calculate E value
03689     pre=1;                         // assume one digit before '.'
03690     if (eng && (e!=0)) {           // engineering: may need to adjust
03691       Int adj;                     // adjustment
03692       // The C remainder operator is undefined for negative numbers, so
03693       // a positive remainder calculation must be used here
03694       if (e<0) {
03695         adj=(-e)%3;
03696         if (adj!=0) adj=3-adj;
03697         }
03698        else { // e>0
03699         adj=e%3;
03700         }
03701       e=e-adj;
03702       // if dealing with zero still produce an exponent which is a
03703       // multiple of three, as expected, but there will only be the
03704       // one zero before the E, still.  Otherwise note the padding.
03705       if (!ISZERO(dn)) pre+=adj;
03706        else {  // is zero
03707         if (adj!=0) {              // 0.00Esnn needed
03708           e=e+3;
03709           pre=-(2-adj);
03710           }
03711         } // zero
03712       } // eng
03713     } // need exponent
03714
03715   /* lay out the digits of the coefficient, adding 0s and . as needed */
03716   u=*up;
03717   if (pre>0) {                     // xxx.xxx or xx00 (engineering) form
03718     Int n=pre;
03719     for (; pre>0; pre--, c++, cut--) {
03720       if (cut<0) {                 // need new Unit
03721         if (up==dn->lsu) break;    // out of input digits (pre>digits)
03722         up--;
03723         cut=DECDPUN-1;
03724         u=*up;
03725         }
03726       TODIGIT(u, cut, c, pow);
03727       }
03728     if (n<dn->digits) {            // more to come, after '.'
03729       *c='.'; c++;
03730       for (;; c++, cut--) {
03731         if (cut<0) {               // need new Unit
03732           if (up==dn->lsu) break;  // out of input digits
03733           up--;
03734           cut=DECDPUN-1;
03735           u=*up;
03736           }
03737         TODIGIT(u, cut, c, pow);
03738         }
03739       }
03740      else for (; pre>0; pre--, c++) *c='0'; // 0 padding (for engineering) needed
03741     }
03742    else {                          // 0.xxx or 0.000xxx form
03743     *c='0'; c++;
03744     *c='.'; c++;
03745     for (; pre<0; pre++, c++) *c='0';   // add any 0's after '.'
03746     for (; ; c++, cut--) {
03747       if (cut<0) {                 // need new Unit
03748         if (up==dn->lsu) break;    // out of input digits
03749         up--;
03750         cut=DECDPUN-1;
03751         u=*up;
03752         }
03753       TODIGIT(u, cut, c, pow);
03754       }
03755     }
03756
03757   /* Finally add the E-part, if needed.  It will never be 0, has a
03758      base maximum and minimum of +999999999 through -999999999, but
03759      could range down to -1999999998 for anormal numbers */
03760   if (e!=0) {
03761     Flag had=0;               // 1=had non-zero
03762     *c='E'; c++;
03763     *c='+'; c++;              // assume positive
03764     u=e;                      // ..
03765     if (e<0) {
03766       *(c-1)='-';             // oops, need -
03767       u=-e;                   // uInt, please
03768       }
03769     // lay out the exponent [_itoa or equivalent is not ANSI C]
03770     for (cut=9; cut>=0; cut--) {
03771       TODIGIT(u, cut, c, pow);
03772       if (*c=='0' && !had) continue;    // skip leading zeros
03773       had=1;                            // had non-0
03774       c++;                              // step for next
03775       } // cut
03776     }
03777   *c='\0';          // terminate the string (all paths)
03778   return;
03779   } // decToString
03780
03781 /* ------------------------------------------------------------------ */
03782 /* decAddOp -- add/subtract operation                                 */
03783 /*                                                                    */
03784 /*   This computes C = A + B                                          */
03785 /*                                                                    */
03786 /*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
03787 /*   lhs is A                                                         */
03788 /*   rhs is B                                                         */
03789 /*   set is the context                                               */
03790 /*   negate is DECNEG if rhs should be negated, or 0 otherwise        */
03791 /*   status accumulates status for the caller                         */
03792 /*                                                                    */
03793 /* C must have space for set->digits digits.                          */
03794 /* Inexact in status must be 0 for correct Exact zero sign in result  */
03795 /* ------------------------------------------------------------------ */
03796 /* If possible, the coefficient is calculated directly into C.        */
03797 /* However, if:                                                       */
03798 /*   -- a digits+1 calculation is needed because the numbers are      */
03799 /*      unaligned and span more than set->digits digits               */
03800 /*   -- a carry to digits+1 digits looks possible                     */
03801 /*   -- C is the same as A or B, and the result would destructively   */
03802 /*      overlap the A or B coefficient                                */
03803 /* then the result must be calculated into a temporary buffer.  In    */
03804 /* this case a local (stack) buffer is used if possible, and only if  */
03805 /* too long for that does malloc become the final resort.             */
03806 /*                                                                    */
03807 /* Misalignment is handled as follows:                                */
03808 /*   Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp.    */
03809 /*   BPad: Apply the padding by a combination of shifting (whole      */
03810 /*         units) and multiplication (part units).                    */
03811 /*                                                                    */
03812 /* Addition, especially x=x+1, is speed-critical.                     */
03813 /* The static buffer is larger than might be expected to allow for    */
03814 /* calls from higher-level funtions (notable exp).                    */
03815 /* ------------------------------------------------------------------ */
03816 static decNumber * decAddOp(decNumber *res, const decNumber *lhs,
03817                             const decNumber *rhs, decContext *set,
03818                             uByte negate, uInt *status) {
03819   #if DECSUBSET
03820   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
03821   decNumber *allocrhs=NULL;        // .., rhs
03822   #endif
03823   Int   rhsshift;                  // working shift (in Units)
03824   Int   maxdigits;                 // longest logical length
03825   Int   mult;                      // multiplier
03826   Int   residue;                   // rounding accumulator
03827   uByte bits;                      // result bits
03828   Flag  diffsign;                  // non-0 if arguments have different sign
03829   Unit  *acc;                      // accumulator for result
03830   Unit  accbuff[SD2U(DECBUFFER*2+20)]; // local buffer [*2+20 reduces many
03831                                    // allocations when called from
03832                                    // other operations, notable exp]
03833   Unit  *allocacc=NULL;            // -> allocated acc buffer, iff allocated
03834   Int   reqdigits=set->digits;     // local copy; requested DIGITS
03835   Int   padding;                   // work
03836
03837   #if DECCHECK
03838   if (decCheckOperands(res, lhs, rhs, set)) return res;
03839   #endif
03840
03841   do {                             // protect allocated storage
03842     #if DECSUBSET
03843     if (!set->extended) {
03844       // reduce operands and set lostDigits status, as needed
03845       if (lhs->digits>reqdigits) {
03846         alloclhs=decRoundOperand(lhs, set, status);
03847         if (alloclhs==NULL) break;
03848         lhs=alloclhs;
03849         }
03850       if (rhs->digits>reqdigits) {
03851         allocrhs=decRoundOperand(rhs, set, status);
03852         if (allocrhs==NULL) break;
03853         rhs=allocrhs;
03854         }
03855       }
03856     #endif
03857     // [following code does not require input rounding]
03858
03859     // note whether signs differ [used all paths]
03860     diffsign=(Flag)((lhs->bits^rhs->bits^negate)&DECNEG);
03861
03862     // handle infinities and NaNs
03863     if (SPECIALARGS) {                  // a special bit set
03864       if (SPECIALARGS & (DECSNAN | DECNAN))  // a NaN
03865         decNaNs(res, lhs, rhs, set, status);
03866        else { // one or two infinities
03867         if (decNumberIsInfinite(lhs)) { // LHS is infinity
03868           // two infinities with different signs is invalid
03869           if (decNumberIsInfinite(rhs) && diffsign) {
03870             *status|=DEC_Invalid_operation;
03871             break;
03872             }
03873           bits=lhs->bits & DECNEG;      // get sign from LHS
03874           }
03875          else bits=(rhs->bits^negate) & DECNEG;// RHS must be Infinity
03876         bits|=DECINF;
03877         decNumberZero(res);
03878         res->bits=bits;                 // set +/- infinity
03879         } // an infinity
03880       break;
03881       }
03882
03883     // Quick exit for add 0s; return the non-0, modified as need be
03884     if (ISZERO(lhs)) {
03885       Int adjust;                       // work
03886       Int lexp=lhs->exponent;           // save in case LHS==RES
03887       bits=lhs->bits;                   // ..
03888       residue=0;                        // clear accumulator
03889       decCopyFit(res, rhs, set, &residue, status); // copy (as needed)
03890       res->bits^=negate;                // flip if rhs was negated
03891       #if DECSUBSET
03892       if (set->extended) {              // exponents on zeros count
03893       #endif
03894         // exponent will be the lower of the two
03895         adjust=lexp-res->exponent;      // adjustment needed [if -ve]
03896         if (ISZERO(res)) {              // both 0: special IEEE 754 rules
03897           if (adjust<0) res->exponent=lexp;  // set exponent
03898           // 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0
03899           if (diffsign) {
03900             if (set->round!=DEC_ROUND_FLOOR) res->bits=0;
03901              else res->bits=DECNEG;     // preserve 0 sign
03902             }
03903           }
03904          else { // non-0 res
03905           if (adjust<0) {     // 0-padding needed
03906             if ((res->digits-adjust)>set->digits) {
03907               adjust=res->digits-set->digits;     // to fit exactly
03908               *status|=DEC_Rounded;               // [but exact]
03909               }
03910             res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
03911             res->exponent+=adjust;                // set the exponent.
03912             }
03913           } // non-0 res
03914       #if DECSUBSET
03915         } // extended
03916       #endif
03917       decFinish(res, set, &residue, status);      // clean and finalize
03918       break;}
03919
03920     if (ISZERO(rhs)) {                  // [lhs is non-zero]
03921       Int adjust;                       // work
03922       Int rexp=rhs->exponent;           // save in case RHS==RES
03923       bits=rhs->bits;                   // be clean
03924       residue=0;                        // clear accumulator
03925       decCopyFit(res, lhs, set, &residue, status); // copy (as needed)
03926       #if DECSUBSET
03927       if (set->extended) {              // exponents on zeros count
03928       #endif
03929         // exponent will be the lower of the two
03930         // [0-0 case handled above]
03931         adjust=rexp-res->exponent;      // adjustment needed [if -ve]
03932         if (adjust<0) {     // 0-padding needed
03933           if ((res->digits-adjust)>set->digits) {
03934             adjust=res->digits-set->digits;     // to fit exactly
03935             *status|=DEC_Rounded;               // [but exact]
03936             }
03937           res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
03938           res->exponent+=adjust;                // set the exponent.
03939           }
03940       #if DECSUBSET
03941         } // extended
03942       #endif
03943       decFinish(res, set, &residue, status);      // clean and finalize
03944       break;}
03945
03946     // [NB: both fastpath and mainpath code below assume these cases
03947     // (notably 0-0) have already been handled]
03948
03949     // calculate the padding needed to align the operands
03950     padding=rhs->exponent-lhs->exponent;
03951
03952     // Fastpath cases where the numbers are aligned and normal, the RHS
03953     // is all in one unit, no operand rounding is needed, and no carry,
03954     // lengthening, or borrow is needed
03955     if (padding==0
03956         && rhs->digits<=DECDPUN
03957         && rhs->exponent>=set->emin     // [some normals drop through]
03958         && rhs->exponent<=set->emax-set->digits+1 // [could clamp]
03959         && rhs->digits<=reqdigits
03960         && lhs->digits<=reqdigits) {
03961       Int partial=*lhs->lsu;
03962       if (!diffsign) {                  // adding
03963         partial+=*rhs->lsu;
03964         if ((partial<=DECDPUNMAX)       // result fits in unit
03965          && (lhs->digits>=DECDPUN ||    // .. and no digits-count change
03966              partial<(Int)powers[lhs->digits])) { // ..
03967           if (res!=lhs) decNumberCopy(res, lhs);  // not in place
03968           *res->lsu=(Unit)partial;      // [copy could have overwritten RHS]
03969           break;
03970           }
03971         // else drop out for careful add
03972         }
03973        else {                           // signs differ
03974         partial-=*rhs->lsu;
03975         if (partial>0) { // no borrow needed, and non-0 result
03976           if (res!=lhs) decNumberCopy(res, lhs);  // not in place
03977           *res->lsu=(Unit)partial;
03978           // this could have reduced digits [but result>0]
03979           res->digits=decGetDigits(res->lsu, D2U(res->digits));
03980           break;
03981           }
03982         // else drop out for careful subtract
03983         }
03984       }
03985
03986     // Now align (pad) the lhs or rhs so they can be added or
03987     // subtracted, as necessary.  If one number is much larger than
03988     // the other (that is, if in plain form there is a least one
03989     // digit between the lowest digit of one and the highest of the
03990     // other) padding with up to DIGITS-1 trailing zeros may be
03991     // needed; then apply rounding (as exotic rounding modes may be
03992     // affected by the residue).
03993     rhsshift=0;               // rhs shift to left (padding) in Units
03994     bits=lhs->bits;           // assume sign is that of LHS
03995     mult=1;                   // likely multiplier
03996
03997     // [if padding==0 the operands are aligned; no padding is needed]
03998     if (padding!=0) {
03999       // some padding needed; always pad the RHS, as any required
04000       // padding can then be effected by a simple combination of
04001       // shifts and a multiply
04002       Flag swapped=0;
04003       if (padding<0) {                  // LHS needs the padding
04004         const decNumber *t;
04005         padding=-padding;               // will be +ve
04006         bits=(uByte)(rhs->bits^negate); // assumed sign is now that of RHS
04007         t=lhs; lhs=rhs; rhs=t;
04008         swapped=1;
04009         }
04010
04011       // If, after pad, rhs would be longer than lhs by digits+1 or
04012       // more then lhs cannot affect the answer, except as a residue,
04013       // so only need to pad up to a length of DIGITS+1.
04014       if (rhs->digits+padding > lhs->digits+reqdigits+1) {
04015         // The RHS is sufficient
04016         // for residue use the relative sign indication...
04017         Int shift=reqdigits-rhs->digits;     // left shift needed
04018         residue=1;                           // residue for rounding
04019         if (diffsign) residue=-residue;      // signs differ
04020         // copy, shortening if necessary
04021         decCopyFit(res, rhs, set, &residue, status);
04022         // if it was already shorter, then need to pad with zeros
04023         if (shift>0) {
04024           res->digits=decShiftToMost(res->lsu, res->digits, shift);
04025           res->exponent-=shift;              // adjust the exponent.
04026           }
04027         // flip the result sign if unswapped and rhs was negated
04028         if (!swapped) res->bits^=negate;
04029         decFinish(res, set, &residue, status);    // done
04030         break;}
04031
04032       // LHS digits may affect result
04033       rhsshift=D2U(padding+1)-1;        // this much by Unit shift ..
04034       mult=powers[padding-(rhsshift*DECDPUN)]; // .. this by multiplication
04035       } // padding needed
04036
04037     if (diffsign) mult=-mult;           // signs differ
04038
04039     // determine the longer operand
04040     maxdigits=rhs->digits+padding;      // virtual length of RHS
04041     if (lhs->digits>maxdigits) maxdigits=lhs->digits;
04042
04043     // Decide on the result buffer to use; if possible place directly
04044     // into result.
04045     acc=res->lsu;                       // assume add direct to result
04046     // If destructive overlap, or the number is too long, or a carry or
04047     // borrow to DIGITS+1 might be possible, a buffer must be used.
04048     // [Might be worth more sophisticated tests when maxdigits==reqdigits]
04049     if ((maxdigits>=reqdigits)          // is, or could be, too large
04050      || (res==rhs && rhsshift>0)) {     // destructive overlap
04051       // buffer needed, choose it; units for maxdigits digits will be
04052       // needed, +1 Unit for carry or borrow
04053       Int need=D2U(maxdigits)+1;
04054       acc=accbuff;                      // assume use local buffer
04055       if (need*sizeof(Unit)>sizeof(accbuff)) {
04056         // printf("malloc add %ld %ld\n", need, sizeof(accbuff));
04057         allocacc=(Unit *)malloc(need*sizeof(Unit));
04058         if (allocacc==NULL) {           // hopeless -- abandon
04059           *status|=DEC_Insufficient_storage;
04060           break;}
04061         acc=allocacc;
04062         }
04063       }
04064
04065     res->bits=(uByte)(bits&DECNEG);     // it's now safe to overwrite..
04066     res->exponent=lhs->exponent;        // .. operands (even if aliased)
04067
04068     #if DECTRACE
04069       decDumpAr('A', lhs->lsu, D2U(lhs->digits));
04070       decDumpAr('B', rhs->lsu, D2U(rhs->digits));
04071       printf("  :h: %ld %ld\n", rhsshift, mult);
04072     #endif
04073
04074     // add [A+B*m] or subtract [A+B*(-m)]
04075     res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits),
04076                               rhs->lsu, D2U(rhs->digits),
04077                               rhsshift, acc, mult)
04078                *DECDPUN;           // [units -> digits]
04079     if (res->digits<0) {           // borrowed...
04080       res->digits=-res->digits;
04081       res->bits^=DECNEG;           // flip the sign
04082       }
04083     #if DECTRACE
04084       decDumpAr('+', acc, D2U(res->digits));
04085     #endif
04086
04087     // If a buffer was used the result must be copied back, possibly
04088     // shortening.  (If no buffer was used then the result must have
04089     // fit, so can't need rounding and residue must be 0.)
04090     residue=0;                     // clear accumulator
04091     if (acc!=res->lsu) {
04092       #if DECSUBSET
04093       if (set->extended) {         // round from first significant digit
04094       #endif
04095         // remove leading zeros that were added due to rounding up to
04096         // integral Units -- before the test for rounding.
04097         if (res->digits>reqdigits)
04098           res->digits=decGetDigits(acc, D2U(res->digits));
04099         decSetCoeff(res, set, acc, res->digits, &residue, status);
04100       #if DECSUBSET
04101         }
04102        else { // subset arithmetic rounds from original significant digit
04103         // May have an underestimate.  This only occurs when both
04104         // numbers fit in DECDPUN digits and are padding with a
04105         // negative multiple (-10, -100...) and the top digit(s) become
04106         // 0.  (This only matters when using X3.274 rules where the
04107         // leading zero could be included in the rounding.)
04108         if (res->digits<maxdigits) {
04109           *(acc+D2U(res->digits))=0; // ensure leading 0 is there
04110           res->digits=maxdigits;
04111           }
04112          else {
04113           // remove leading zeros that added due to rounding up to
04114           // integral Units (but only those in excess of the original
04115           // maxdigits length, unless extended) before test for rounding.
04116           if (res->digits>reqdigits) {
04117             res->digits=decGetDigits(acc, D2U(res->digits));
04118             if (res->digits<maxdigits) res->digits=maxdigits;
04119             }
04120           }
04121         decSetCoeff(res, set, acc, res->digits, &residue, status);
04122         // Now apply rounding if needed before removing leading zeros.
04123         // This is safe because subnormals are not a possibility
04124         if (residue!=0) {
04125           decApplyRound(res, set, residue, status);
04126           residue=0;                 // did what needed to be done
04127           }
04128         } // subset
04129       #endif
04130       } // used buffer
04131
04132     // strip leading zeros [these were left on in case of subset subtract]
04133     res->digits=decGetDigits(res->lsu, D2U(res->digits));
04134
04135     // apply checks and rounding
04136     decFinish(res, set, &residue, status);
04137
04138     // "When the sum of two operands with opposite signs is exactly
04139     // zero, the sign of that sum shall be '+' in all rounding modes
04140     // except round toward -Infinity, in which mode that sign shall be
04141     // '-'."  [Subset zeros also never have '-', set by decFinish.]
04142     if (ISZERO(res) && diffsign
04143      #if DECSUBSET
04144      && set->extended
04145      #endif
04146      && (*status&DEC_Inexact)==0) {
04147       if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG;   // sign -
04148                                   else res->bits&=~DECNEG;  // sign +
04149       }
04150     } while(0);                              // end protected
04151
04152   if (allocacc!=NULL) free(allocacc);        // drop any storage used
04153   #if DECSUBSET
04154   if (allocrhs!=NULL) free(allocrhs);        // ..
04155   if (alloclhs!=NULL) free(alloclhs);        // ..
04156   #endif
04157   return res;
04158   } // decAddOp
04159
04160 /* ------------------------------------------------------------------ */
04161 /* decDivideOp -- division operation                                  */
04162 /*                                                                    */
04163 /*  This routine performs the calculations for all four division      */
04164 /*  operators (divide, divideInteger, remainder, remainderNear).      */
04165 /*                                                                    */
04166 /*  C=A op B                                                          */
04167 /*                                                                    */
04168 /*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
04169 /*   lhs is A                                                         */
04170 /*   rhs is B                                                         */
04171 /*   set is the context                                               */
04172 /*   op  is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively.    */
04173 /*   status is the usual accumulator                                  */
04174 /*                                                                    */
04175 /* C must have space for set->digits digits.                          */
04176 /*                                                                    */
04177 /* ------------------------------------------------------------------ */
04178 /*   The underlying algorithm of this routine is the same as in the   */
04179 /*   1981 S/370 implementation, that is, non-restoring long division  */
04180 /*   with bi-unit (rather than bi-digit) estimation for each unit     */
04181 /*   multiplier.  In this pseudocode overview, complications for the  */
04182 /*   Remainder operators and division residues for exact rounding are */
04183 /*   omitted for clarity.                                             */
04184 /*                                                                    */
04185 /*     Prepare operands and handle special values                     */
04186 /*     Test for x/0 and then 0/x                                      */
04187 /*     Exp =Exp1 - Exp2                                               */
04188 /*     Exp =Exp +len(var1) -len(var2)                                 */
04189 /*     Sign=Sign1 * Sign2                                             */
04190 /*     Pad accumulator (Var1) to double-length with 0's (pad1)        */
04191 /*     Pad Var2 to same length as Var1                                */
04192 /*     msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round  */
04193 /*     have=0                                                         */
04194 /*     Do until (have=digits+1 OR residue=0)                          */
04195 /*       if exp<0 then if integer divide/residue then leave           */
04196 /*       this_unit=0                                                  */
04197 /*       Do forever                                                   */
04198 /*          compare numbers                                           */
04199 /*          if <0 then leave inner_loop                               */
04200 /*          if =0 then (* quick exit without subtract *) do           */
04201 /*             this_unit=this_unit+1; output this_unit                */
04202 /*             leave outer_loop; end                                  */
04203 /*          Compare lengths of numbers (mantissae):                   */
04204 /*          If same then tops2=msu2pair -- {units 1&2 of var2}        */
04205 /*                  else tops2=msu2plus -- {0, unit 1 of var2}        */
04206 /*          tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */
04207 /*          mult=tops1/tops2  -- Good and safe guess at divisor       */
04208 /*          if mult=0 then mult=1                                     */
04209 /*          this_unit=this_unit+mult                                  */
04210 /*          subtract                                                  */
04211 /*          end inner_loop                                            */
04212 /*        if have\=0 | this_unit\=0 then do                           */
04213 /*          output this_unit                                          */
04214 /*          have=have+1; end                                          */
04215 /*        var2=var2/10                                                */
04216 /*        exp=exp-1                                                   */
04217 /*        end outer_loop                                              */
04218 /*     exp=exp+1   -- set the proper exponent                         */
04219 /*     if have=0 then generate answer=0                               */
04220 /*     Return (Result is defined by Var1)                             */
04221 /*                                                                    */
04222 /* ------------------------------------------------------------------ */
04223 /* Two working buffers are needed during the division; one (digits+   */
04224 /* 1) to accumulate the result, and the other (up to 2*digits+1) for  */
04225 /* long subtractions.  These are acc and var1 respectively.           */
04226 /* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/
04227 /* The static buffers may be larger than might be expected to allow   */
04228 /* for calls from higher-level funtions (notable exp).                */
04229 /* ------------------------------------------------------------------ */
04230 static decNumber * decDivideOp(decNumber *res,
04231                                const decNumber *lhs, const decNumber *rhs,
04232                                decContext *set, Flag op, uInt *status) {
04233   #if DECSUBSET
04234   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
04235   decNumber *allocrhs=NULL;        // .., rhs
04236   #endif
04237   Unit  accbuff[SD2U(DECBUFFER+DECDPUN+10)]; // local buffer
04238   Unit  *acc=accbuff;              // -> accumulator array for result
04239   Unit  *allocacc=NULL;            // -> allocated buffer, iff allocated
04240   Unit  *accnext;                  // -> where next digit will go
04241   Int   acclength;                 // length of acc needed [Units]
04242   Int   accunits;                  // count of units accumulated
04243   Int   accdigits;                 // count of digits accumulated
04244
04245   Unit  varbuff[SD2U(DECBUFFER*2+DECDPUN)];  // buffer for var1
04246   Unit  *var1=varbuff;             // -> var1 array for long subtraction
04247   Unit  *varalloc=NULL;            // -> allocated buffer, iff used
04248   Unit  *msu1;                     // -> msu of var1
04249
04250   const Unit *var2;                // -> var2 array
04251   const Unit *msu2;                // -> msu of var2
04252   Int   msu2plus;                  // msu2 plus one [does not vary]
04253   eInt  msu2pair;                  // msu2 pair plus one [does not vary]
04254
04255   Int   var1units, var2units;      // actual lengths
04256   Int   var2ulen;                  // logical length (units)
04257   Int   var1initpad=0;             // var1 initial padding (digits)
04258   Int   maxdigits;                 // longest LHS or required acc length
04259   Int   mult;                      // multiplier for subtraction
04260   Unit  thisunit;                  // current unit being accumulated
04261   Int   residue;                   // for rounding
04262   Int   reqdigits=set->digits;     // requested DIGITS
04263   Int   exponent;                  // working exponent
04264   Int   maxexponent=0;             // DIVIDE maximum exponent if unrounded
04265   uByte bits;                      // working sign
04266   Unit  *target;                   // work
04267   const Unit *source;              // ..
04268   uInt  const *pow;                // ..
04269   Int   shift, cut;                // ..
04270   #if DECSUBSET
04271   Int   dropped;                   // work
04272   #endif
04273
04274   #if DECCHECK
04275   if (decCheckOperands(res, lhs, rhs, set)) return res;
04276   #endif
04277
04278   do {                             // protect allocated storage
04279     #if DECSUBSET
04280     if (!set->extended) {
04281       // reduce operands and set lostDigits status, as needed
04282       if (lhs->digits>reqdigits) {
04283         alloclhs=decRoundOperand(lhs, set, status);
04284         if (alloclhs==NULL) break;
04285         lhs=alloclhs;
04286         }
04287       if (rhs->digits>reqdigits) {
04288         allocrhs=decRoundOperand(rhs, set, status);
04289         if (allocrhs==NULL) break;
04290         rhs=allocrhs;
04291         }
04292       }
04293     #endif
04294     // [following code does not require input rounding]
04295
04296     bits=(lhs->bits^rhs->bits)&DECNEG;  // assumed sign for divisions
04297
04298     // handle infinities and NaNs
04299     if (SPECIALARGS) {                  // a special bit set
04300       if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
04301         decNaNs(res, lhs, rhs, set, status);
04302         break;
04303         }
04304       // one or two infinities
04305       if (decNumberIsInfinite(lhs)) {   // LHS (dividend) is infinite
04306         if (decNumberIsInfinite(rhs) || // two infinities are invalid ..
04307             op & (REMAINDER | REMNEAR)) { // as is remainder of infinity
04308           *status|=DEC_Invalid_operation;
04309           break;
04310           }
04311         // [Note that infinity/0 raises no exceptions]
04312         decNumberZero(res);
04313         res->bits=bits|DECINF;          // set +/- infinity
04314         break;
04315         }
04316        else {                           // RHS (divisor) is infinite
04317         residue=0;
04318         if (op&(REMAINDER|REMNEAR)) {
04319           // result is [finished clone of] lhs
04320           decCopyFit(res, lhs, set, &residue, status);
04321           }
04322          else {  // a division
04323           decNumberZero(res);
04324           res->bits=bits;               // set +/- zero
04325           // for DIVIDEINT the exponent is always 0.  For DIVIDE, result
04326           // is a 0 with infinitely negative exponent, clamped to minimum
04327           if (op&DIVIDE) {
04328             res->exponent=set->emin-set->digits+1;
04329             *status|=DEC_Clamped;
04330             }
04331           }
04332         decFinish(res, set, &residue, status);
04333         break;
04334         }
04335       }
04336
04337     // handle 0 rhs (x/0)
04338     if (ISZERO(rhs)) {                  // x/0 is always exceptional
04339       if (ISZERO(lhs)) {
04340         decNumberZero(res);             // [after lhs test]
04341         *status|=DEC_Division_undefined;// 0/0 will become NaN
04342         }
04343        else {
04344         decNumberZero(res);
04345         if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation;
04346          else {
04347           *status|=DEC_Division_by_zero; // x/0
04348           res->bits=bits|DECINF;         // .. is +/- Infinity
04349           }
04350         }
04351       break;}
04352
04353     // handle 0 lhs (0/x)
04354     if (ISZERO(lhs)) {                  // 0/x [x!=0]
04355       #if DECSUBSET
04356       if (!set->extended) decNumberZero(res);
04357        else {
04358       #endif
04359         if (op&DIVIDE) {
04360           residue=0;
04361           exponent=lhs->exponent-rhs->exponent; // ideal exponent
04362           decNumberCopy(res, lhs);      // [zeros always fit]
04363           res->bits=bits;               // sign as computed
04364           res->exponent=exponent;       // exponent, too
04365           decFinalize(res, set, &residue, status);   // check exponent
04366           }
04367          else if (op&DIVIDEINT) {
04368           decNumberZero(res);           // integer 0
04369           res->bits=bits;               // sign as computed
04370           }
04371          else {                         // a remainder
04372           exponent=rhs->exponent;       // [save in case overwrite]
04373           decNumberCopy(res, lhs);      // [zeros always fit]
04374           if (exponent<res->exponent) res->exponent=exponent; // use lower
04375           }
04376       #if DECSUBSET
04377         }
04378       #endif
04379       break;}
04380
04381     // Precalculate exponent.  This starts off adjusted (and hence fits
04382     // in 31 bits) and becomes the usual unadjusted exponent as the
04383     // division proceeds.  The order of evaluation is important, here,
04384     // to avoid wrap.
04385     exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits);
04386
04387     // If the working exponent is -ve, then some quick exits are
04388     // possible because the quotient is known to be <1
04389     // [for REMNEAR, it needs to be < -1, as -0.5 could need work]
04390     if (exponent<0 && !(op==DIVIDE)) {
04391       if (op&DIVIDEINT) {
04392         decNumberZero(res);                  // integer part is 0
04393         #if DECSUBSET
04394         if (set->extended)
04395         #endif
04396           res->bits=bits;                    // set +/- zero
04397         break;}
04398       // fastpath remainders so long as the lhs has the smaller
04399       // (or equal) exponent
04400       if (lhs->exponent<=rhs->exponent) {
04401         if (op&REMAINDER || exponent<-1) {
04402           // It is REMAINDER or safe REMNEAR; result is [finished
04403           // clone of] lhs  (r = x - 0*y)
04404           residue=0;
04405           decCopyFit(res, lhs, set, &residue, status);
04406           decFinish(res, set, &residue, status);
04407           break;
04408           }
04409         // [unsafe REMNEAR drops through]
04410         }
04411       } // fastpaths
04412
04413     /* Long (slow) division is needed; roll up the sleeves... */
04414
04415     // The accumulator will hold the quotient of the division.
04416     // If it needs to be too long for stack storage, then allocate.
04417     acclength=D2U(reqdigits+DECDPUN);   // in Units
04418     if (acclength*sizeof(Unit)>sizeof(accbuff)) {
04419       // printf("malloc dvacc %ld units\n", acclength);
04420       allocacc=(Unit *)malloc(acclength*sizeof(Unit));
04421       if (allocacc==NULL) {             // hopeless -- abandon
04422         *status|=DEC_Insufficient_storage;
04423         break;}
04424       acc=allocacc;                     // use the allocated space
04425       }
04426
04427     // var1 is the padded LHS ready for subtractions.
04428     // If it needs to be too long for stack storage, then allocate.
04429     // The maximum units needed for var1 (long subtraction) is:
04430     // Enough for
04431     //     (rhs->digits+reqdigits-1) -- to allow full slide to right
04432     // or  (lhs->digits)             -- to allow for long lhs
04433     // whichever is larger
04434     //   +1                -- for rounding of slide to right
04435     //   +1                -- for leading 0s
04436     //   +1                -- for pre-adjust if a remainder or DIVIDEINT
04437     // [Note: unused units do not participate in decUnitAddSub data]
04438     maxdigits=rhs->digits+reqdigits-1;
04439     if (lhs->digits>maxdigits) maxdigits=lhs->digits;
04440     var1units=D2U(maxdigits)+2;
04441     // allocate a guard unit above msu1 for REMAINDERNEAR
04442     if (!(op&DIVIDE)) var1units++;
04443     if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) {
04444       // printf("malloc dvvar %ld units\n", var1units+1);
04445       varalloc=(Unit *)malloc((var1units+1)*sizeof(Unit));
04446       if (varalloc==NULL) {             // hopeless -- abandon
04447         *status|=DEC_Insufficient_storage;
04448         break;}
04449       var1=varalloc;                    // use the allocated space
04450       }
04451
04452     // Extend the lhs and rhs to full long subtraction length.  The lhs
04453     // is truly extended into the var1 buffer, with 0 padding, so a
04454     // subtract in place is always possible.  The rhs (var2) has
04455     // virtual padding (implemented by decUnitAddSub).
04456     // One guard unit was allocated above msu1 for rem=rem+rem in
04457     // REMAINDERNEAR.
04458     msu1=var1+var1units-1;              // msu of var1
04459     source=lhs->lsu+D2U(lhs->digits)-1; // msu of input array
04460     for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;
04461     for (; target>=var1; target--) *target=0;
04462
04463     // rhs (var2) is left-aligned with var1 at the start
04464     var2ulen=var1units;                 // rhs logical length (units)
04465     var2units=D2U(rhs->digits);         // rhs actual length (units)
04466     var2=rhs->lsu;                      // -> rhs array
04467     msu2=var2+var2units-1;              // -> msu of var2 [never changes]
04468     // now set up the variables which will be used for estimating the
04469     // multiplication factor.  If these variables are not exact, add
04470     // 1 to make sure that the multiplier is never overestimated.
04471     msu2plus=*msu2;                     // it's value ..
04472     if (var2units>1) msu2plus++;        // .. +1 if any more
04473     msu2pair=(eInt)*msu2*(DECDPUNMAX+1);// top two pair ..
04474     if (var2units>1) {                  // .. [else treat 2nd as 0]
04475       msu2pair+=*(msu2-1);              // ..
04476       if (var2units>2) msu2pair++;      // .. +1 if any more
04477       }
04478
04479     // The calculation is working in units, which may have leading zeros,
04480     // but the exponent was calculated on the assumption that they are
04481     // both left-aligned.  Adjust the exponent to compensate: add the
04482     // number of leading zeros in var1 msu and subtract those in var2 msu.
04483     // [This is actually done by counting the digits and negating, as
04484     // lead1=DECDPUN-digits1, and similarly for lead2.]
04485     for (pow=&powers[1]; *msu1>=*pow; pow++) exponent--;
04486     for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++;
04487
04488     // Now, if doing an integer divide or remainder, ensure that
04489     // the result will be Unit-aligned.  To do this, shift the var1
04490     // accumulator towards least if need be.  (It's much easier to
04491     // do this now than to reassemble the residue afterwards, if
04492     // doing a remainder.)  Also ensure the exponent is not negative.
04493     if (!(op&DIVIDE)) {
04494       Unit *u;                          // work
04495       // save the initial 'false' padding of var1, in digits
04496       var1initpad=(var1units-D2U(lhs->digits))*DECDPUN;
04497       // Determine the shift to do.
04498       if (exponent<0) cut=-exponent;
04499        else cut=DECDPUN-exponent%DECDPUN;
04500       decShiftToLeast(var1, var1units, cut);
04501       exponent+=cut;                    // maintain numerical value
04502       var1initpad-=cut;                 // .. and reduce padding
04503       // clean any most-significant units which were just emptied
04504       for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;
04505       } // align
04506      else { // is DIVIDE
04507       maxexponent=lhs->exponent-rhs->exponent;    // save
04508       // optimization: if the first iteration will just produce 0,
04509       // preadjust to skip it [valid for DIVIDE only]
04510       if (*msu1<*msu2) {
04511         var2ulen--;                     // shift down
04512         exponent-=DECDPUN;              // update the exponent
04513         }
04514       }
04515
04516     // ---- start the long-division loops ------------------------------
04517     accunits=0;                         // no units accumulated yet
04518     accdigits=0;                        // .. or digits
04519     accnext=acc+acclength-1;            // -> msu of acc [NB: allows digits+1]
04520     for (;;) {                          // outer forever loop
04521       thisunit=0;                       // current unit assumed 0
04522       // find the next unit
04523       for (;;) {                        // inner forever loop
04524         // strip leading zero units [from either pre-adjust or from
04525         // subtract last time around].  Leave at least one unit.
04526         for (; *msu1==0 && msu1>var1; msu1--) var1units--;
04527
04528         if (var1units<var2ulen) break;       // var1 too low for subtract
04529         if (var1units==var2ulen) {           // unit-by-unit compare needed
04530           // compare the two numbers, from msu
04531           const Unit *pv1, *pv2;
04532           Unit v2;                           // units to compare
04533           pv2=msu2;                          // -> msu
04534           for (pv1=msu1; ; pv1--, pv2--) {
04535             // v1=*pv1 -- always OK
04536             v2=0;                            // assume in padding
04537             if (pv2>=var2) v2=*pv2;          // in range
04538             if (*pv1!=v2) break;             // no longer the same
04539             if (pv1==var1) break;            // done; leave pv1 as is
04540             }
04541           // here when all inspected or a difference seen
04542           if (*pv1<v2) break;                // var1 too low to subtract
04543           if (*pv1==v2) {                    // var1 == var2
04544             // reach here if var1 and var2 are identical; subtraction
04545             // would increase digit by one, and the residue will be 0 so
04546             // the calculation is done; leave the loop with residue=0.
04547             thisunit++;                      // as though subtracted
04548             *var1=0;                         // set var1 to 0
04549             var1units=1;                     // ..
04550             break;  // from inner
04551             } // var1 == var2
04552           // *pv1>v2.  Prepare for real subtraction; the lengths are equal
04553           // Estimate the multiplier (there's always a msu1-1)...
04554           // Bring in two units of var2 to provide a good estimate.
04555           mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2pair);
04556           } // lengths the same
04557          else { // var1units > var2ulen, so subtraction is safe
04558           // The var2 msu is one unit towards the lsu of the var1 msu,
04559           // so only one unit for var2 can be used.
04560           mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2plus);
04561           }
04562         if (mult==0) mult=1;                 // must always be at least 1
04563         // subtraction needed; var1 is > var2
04564         thisunit=(Unit)(thisunit+mult);      // accumulate
04565         // subtract var1-var2, into var1; only the overlap needs
04566         // processing, as this is an in-place calculation
04567         shift=var2ulen-var2units;
04568         #if DECTRACE
04569           decDumpAr('1', &var1[shift], var1units-shift);
04570           decDumpAr('2', var2, var2units);
04571           printf("m=%ld\n", -mult);
04572         #endif
04573         decUnitAddSub(&var1[shift], var1units-shift,
04574                       var2, var2units, 0,
04575                       &var1[shift], -mult);
04576         #if DECTRACE
04577           decDumpAr('#', &var1[shift], var1units-shift);
04578         #endif
04579         // var1 now probably has leading zeros; these are removed at the
04580         // top of the inner loop.
04581         } // inner loop
04582
04583       // The next unit has been calculated in full; unless it's a
04584       // leading zero, add to acc
04585       if (accunits!=0 || thisunit!=0) {      // is first or non-zero
04586         *accnext=thisunit;                   // store in accumulator
04587         // account exactly for the new digits
04588         if (accunits==0) {
04589           accdigits++;                       // at least one
04590           for (pow=&powers[1]; thisunit>=*pow; pow++) accdigits++;
04591           }
04592          else accdigits+=DECDPUN;
04593         accunits++;                          // update count
04594         accnext--;                           // ready for next
04595         if (accdigits>reqdigits) break;      // have enough digits
04596         }
04597
04598       // if the residue is zero, the operation is done (unless divide
04599       // or divideInteger and still not enough digits yet)
04600       if (*var1==0 && var1units==1) {        // residue is 0
04601         if (op&(REMAINDER|REMNEAR)) break;
04602         if ((op&DIVIDE) && (exponent<=maxexponent)) break;
04603         // [drop through if divideInteger]
04604         }
04605       // also done enough if calculating remainder or integer
04606       // divide and just did the last ('units') unit
04607       if (exponent==0 && !(op&DIVIDE)) break;
04608
04609       // to get here, var1 is less than var2, so divide var2 by the per-
04610       // Unit power of ten and go for the next digit
04611       var2ulen--;                            // shift down
04612       exponent-=DECDPUN;                     // update the exponent
04613       } // outer loop
04614
04615     // ---- division is complete ---------------------------------------
04616     // here: acc      has at least reqdigits+1 of good results (or fewer
04617     //                if early stop), starting at accnext+1 (its lsu)
04618     //       var1     has any residue at the stopping point
04619     //       accunits is the number of digits collected in acc
04620     if (accunits==0) {             // acc is 0
04621       accunits=1;                  // show have a unit ..
04622       accdigits=1;                 // ..
04623       *accnext=0;                  // .. whose value is 0
04624       }
04625      else accnext++;               // back to last placed
04626     // accnext now -> lowest unit of result
04627
04628     residue=0;                     // assume no residue
04629     if (op&DIVIDE) {
04630       // record the presence of any residue, for rounding
04631       if (*var1!=0 || var1units>1) residue=1;
04632        else { // no residue
04633         // Had an exact division; clean up spurious trailing 0s.
04634         // There will be at most DECDPUN-1, from the final multiply,
04635         // and then only if the result is non-0 (and even) and the
04636         // exponent is 'loose'.
04637         #if DECDPUN>1
04638         Unit lsu=*accnext;
04639         if (!(lsu&0x01) && (lsu!=0)) {
04640           // count the trailing zeros
04641           Int drop=0;
04642           for (;; drop++) {    // [will terminate because lsu!=0]
04643             if (exponent>=maxexponent) break;     // don't chop real 0s
04644             #if DECDPUN<=4
04645               if ((lsu-QUOT10(lsu, drop+1)
04646                   *powers[drop+1])!=0) break;     // found non-0 digit
04647             #else
04648               if (lsu%powers[drop+1]!=0) break;   // found non-0 digit
04649             #endif
04650             exponent++;
04651             }
04652           if (drop>0) {
04653             accunits=decShiftToLeast(accnext, accunits, drop);
04654             accdigits=decGetDigits(accnext, accunits);
04655             accunits=D2U(accdigits);
04656             // [exponent was adjusted in the loop]
04657             }
04658           } // neither odd nor 0
04659         #endif
04660         } // exact divide
04661       } // divide
04662      else /* op!=DIVIDE */ {
04663       // check for coefficient overflow
04664       if (accdigits+exponent>reqdigits) {
04665         *status|=DEC_Division_impossible;
04666         break;
04667         }
04668       if (op & (REMAINDER|REMNEAR)) {
04669         // [Here, the exponent will be 0, because var1 was adjusted
04670         // appropriately.]
04671         Int postshift;                       // work
04672         Flag wasodd=0;                       // integer was odd
04673         Unit *quotlsu;                       // for save
04674         Int  quotdigits;                     // ..
04675
04676         bits=lhs->bits;                      // remainder sign is always as lhs
04677
04678         // Fastpath when residue is truly 0 is worthwhile [and
04679         // simplifies the code below]
04680         if (*var1==0 && var1units==1) {      // residue is 0
04681           Int exp=lhs->exponent;             // save min(exponents)
04682           if (rhs->exponent<exp) exp=rhs->exponent;
04683           decNumberZero(res);                // 0 coefficient
04684           #if DECSUBSET
04685           if (set->extended)
04686           #endif
04687           res->exponent=exp;                 // .. with proper exponent
04688           res->bits=(uByte)(bits&DECNEG);          // [cleaned]
04689           decFinish(res, set, &residue, status);   // might clamp
04690           break;
04691           }
04692         // note if the quotient was odd
04693         if (*accnext & 0x01) wasodd=1;       // acc is odd
04694         quotlsu=accnext;                     // save in case need to reinspect
04695         quotdigits=accdigits;                // ..
04696
04697         // treat the residue, in var1, as the value to return, via acc
04698         // calculate the unused zero digits.  This is the smaller of:
04699         //   var1 initial padding (saved above)
04700         //   var2 residual padding, which happens to be given by:
04701         postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;
04702         // [the 'exponent' term accounts for the shifts during divide]
04703         if (var1initpad<postshift) postshift=var1initpad;
04704
04705         // shift var1 the requested amount, and adjust its digits
04706         var1units=decShiftToLeast(var1, var1units, postshift);
04707         accnext=var1;
04708         accdigits=decGetDigits(var1, var1units);
04709         accunits=D2U(accdigits);
04710
04711         exponent=lhs->exponent;         // exponent is smaller of lhs & rhs
04712         if (rhs->exponent<exponent) exponent=rhs->exponent;
04713
04714         // Now correct the result if doing remainderNear; if it
04715         // (looking just at coefficients) is > rhs/2, or == rhs/2 and
04716         // the integer was odd then the result should be rem-rhs.
04717         if (op&REMNEAR) {
04718           Int compare, tarunits;        // work
04719           Unit *up;                     // ..
04720           // calculate remainder*2 into the var1 buffer (which has
04721           // 'headroom' of an extra unit and hence enough space)
04722           // [a dedicated 'double' loop would be faster, here]
04723           tarunits=decUnitAddSub(accnext, accunits, accnext, accunits,
04724                                  0, accnext, 1);
04725           // decDumpAr('r', accnext, tarunits);
04726
04727           // Here, accnext (var1) holds tarunits Units with twice the
04728           // remainder's coefficient, which must now be compared to the
04729           // RHS.  The remainder's exponent may be smaller than the RHS's.
04730           compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits),
04731                                  rhs->exponent-exponent);
04732           if (compare==BADINT) {             // deep trouble
04733             *status|=DEC_Insufficient_storage;
04734             break;}
04735
04736           // now restore the remainder by dividing by two; the lsu
04737           // is known to be even.
04738           for (up=accnext; up<accnext+tarunits; up++) {
04739             Int half;              // half to add to lower unit
04740             half=*up & 0x01;
04741             *up/=2;                // [shift]
04742             if (!half) continue;
04743             *(up-1)+=(DECDPUNMAX+1)/2;
04744             }
04745           // [accunits still describes the original remainder length]
04746
04747           if (compare>0 || (compare==0 && wasodd)) { // adjustment needed
04748             Int exp, expunits, exprem;       // work
04749             // This is effectively causing round-up of the quotient,
04750             // so if it was the rare case where it was full and all
04751             // nines, it would overflow and hence division-impossible
04752             // should be raised
04753             Flag allnines=0;                 // 1 if quotient all nines
04754             if (quotdigits==reqdigits) {     // could be borderline
04755               for (up=quotlsu; ; up++) {
04756                 if (quotdigits>DECDPUN) {
04757                   if (*up!=DECDPUNMAX) break;// non-nines
04758                   }
04759                  else {                      // this is the last Unit
04760                   if (*up==powers[quotdigits]-1) allnines=1;
04761                   break;
04762                   }
04763                 quotdigits-=DECDPUN;         // checked those digits
04764                 } // up
04765               } // borderline check
04766             if (allnines) {
04767               *status|=DEC_Division_impossible;
04768               break;}
04769
04770             // rem-rhs is needed; the sign will invert.  Again, var1
04771             // can safely be used for the working Units array.
04772             exp=rhs->exponent-exponent;      // RHS padding needed
04773             // Calculate units and remainder from exponent.
04774             expunits=exp/DECDPUN;
04775             exprem=exp%DECDPUN;
04776             // subtract [A+B*(-m)]; the result will always be negative
04777             accunits=-decUnitAddSub(accnext, accunits,
04778                                     rhs->lsu, D2U(rhs->digits),
04779                                     expunits, accnext, -(Int)powers[exprem]);
04780             accdigits=decGetDigits(accnext, accunits); // count digits exactly
04781             accunits=D2U(accdigits);    // and recalculate the units for copy
04782             // [exponent is as for original remainder]
04783             bits^=DECNEG;               // flip the sign
04784             }
04785           } // REMNEAR
04786         } // REMAINDER or REMNEAR
04787       } // not DIVIDE
04788
04789     // Set exponent and bits
04790     res->exponent=exponent;
04791     res->bits=(uByte)(bits&DECNEG);          // [cleaned]
04792
04793     // Now the coefficient.
04794     decSetCoeff(res, set, accnext, accdigits, &residue, status);
04795
04796     decFinish(res, set, &residue, status);   // final cleanup
04797
04798     #if DECSUBSET
04799     // If a divide then strip trailing zeros if subset [after round]
04800     if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped);
04801     #endif
04802     } while(0);                              // end protected
04803
04804   if (varalloc!=NULL) free(varalloc);   // drop any storage used
04805   if (allocacc!=NULL) free(allocacc);   // ..
04806   #if DECSUBSET
04807   if (allocrhs!=NULL) free(allocrhs);   // ..
04808   if (alloclhs!=NULL) free(alloclhs);   // ..
04809   #endif
04810   return res;
04811   } // decDivideOp
04812
04813 /* ------------------------------------------------------------------ */
04814 /* decMultiplyOp -- multiplication operation                          */
04815 /*                                                                    */
04816 /*  This routine performs the multiplication C=A x B.                 */
04817 /*                                                                    */
04818 /*   res is C, the result.  C may be A and/or B (e.g., X=X*X)         */
04819 /*   lhs is A                                                         */
04820 /*   rhs is B                                                         */
04821 /*   set is the context                                               */
04822 /*   status is the usual accumulator                                  */
04823 /*                                                                    */
04824 /* C must have space for set->digits digits.                          */
04825 /*                                                                    */
04826 /* ------------------------------------------------------------------ */
04827 /* 'Classic' multiplication is used rather than Karatsuba, as the     */
04828 /* latter would give only a minor improvement for the short numbers   */
04829 /* expected to be handled most (and uses much more memory).           */
04830 /*                                                                    */
04831 /* There are two major paths here: the general-purpose ('old code')   */
04832 /* path which handles all DECDPUN values, and a fastpath version      */
04833 /* which is used if 64-bit ints are available, DECDPUN<=4, and more   */
04834 /* than two calls to decUnitAddSub would be made.                     */
04835 /*                                                                    */
04836 /* The fastpath version lumps units together into 8-digit or 9-digit  */
04837 /* chunks, and also uses a lazy carry strategy to minimise expensive  */
04838 /* 64-bit divisions.  The chunks are then broken apart again into     */
04839 /* units for continuing processing.  Despite this overhead, the       */
04840 /* fastpath can speed up some 16-digit operations by 10x (and much    */
04841 /* more for higher-precision calculations).                           */
04842 /*                                                                    */
04843 /* A buffer always has to be used for the accumulator; in the         */
04844 /* fastpath, buffers are also always needed for the chunked copies of */
04845 /* of the operand coefficients.                                       */
04846 /* Static buffers are larger than needed just for multiply, to allow  */
04847 /* for calls from other operations (notably exp).                     */
04848 /* ------------------------------------------------------------------ */
04849 #define FASTMUL (DECUSE64 && DECDPUN<5)
04850 static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs,
04851                                  const decNumber *rhs, decContext *set,
04852                                  uInt *status) {
04853   Int    accunits;                 // Units of accumulator in use
04854   Int    exponent;                 // work
04855   Int    residue=0;                // rounding residue
04856   uByte  bits;                     // result sign
04857   Unit  *acc;                      // -> accumulator Unit array
04858   Int    needbytes;                // size calculator
04859   void  *allocacc=NULL;            // -> allocated accumulator, iff allocated
04860   Unit  accbuff[SD2U(DECBUFFER*4+1)]; // buffer (+1 for DECBUFFER==0,
04861                                    // *4 for calls from other operations)
04862   const Unit *mer, *mermsup;       // work
04863   Int   madlength;                 // Units in multiplicand
04864   Int   shift;                     // Units to shift multiplicand by
04865
04866   #if FASTMUL
04867     // if DECDPUN is 1 or 3 work in base 10**9, otherwise
04868     // (DECDPUN is 2 or 4) then work in base 10**8
04869     #if DECDPUN & 1                // odd
04870       #define FASTBASE 1000000000  // base
04871       #define FASTDIGS          9  // digits in base
04872       #define FASTLAZY         18  // carry resolution point [1->18]
04873     #else
04874       #define FASTBASE  100000000
04875       #define FASTDIGS          8
04876       #define FASTLAZY       1844  // carry resolution point [1->1844]
04877     #endif
04878     // three buffers are used, two for chunked copies of the operands
04879     // (base 10**8 or base 10**9) and one base 2**64 accumulator with
04880     // lazy carry evaluation
04881     uInt   zlhibuff[(DECBUFFER*2+1)/8+1]; // buffer (+1 for DECBUFFER==0)
04882     uInt  *zlhi=zlhibuff;                 // -> lhs array
04883     uInt  *alloclhi=NULL;                 // -> allocated buffer, iff allocated
04884     uInt   zrhibuff[(DECBUFFER*2+1)/8+1]; // buffer (+1 for DECBUFFER==0)
04885     uInt  *zrhi=zrhibuff;                 // -> rhs array
04886     uInt  *allocrhi=NULL;                 // -> allocated buffer, iff allocated
04887     uLong  zaccbuff[(DECBUFFER*2+1)/4+2]; // buffer (+1 for DECBUFFER==0)
04888     // [allocacc is shared for both paths, as only one will run]
04889     uLong *zacc=zaccbuff;          // -> accumulator array for exact result
04890     #if DECDPUN==1
04891     Int    zoff;                   // accumulator offset
04892     #endif
04893     uInt  *lip, *rip;              // item pointers
04894     uInt  *lmsi, *rmsi;            // most significant items
04895     Int    ilhs, irhs, iacc;       // item counts in the arrays
04896     Int    lazy;                   // lazy carry counter
04897     uLong  lcarry;                 // uLong carry
04898     uInt   carry;                  // carry (NB not uLong)
04899     Int    count;                  // work
04900     const  Unit *cup;              // ..
04901     Unit  *up;                     // ..
04902     uLong *lp;                     // ..
04903     Int    p;                      // ..
04904   #endif
04905
04906   #if DECSUBSET
04907     decNumber *alloclhs=NULL;      // -> allocated buffer, iff allocated
04908     decNumber *allocrhs=NULL;      // -> allocated buffer, iff allocated
04909   #endif
04910
04911   #if DECCHECK
04912   if (decCheckOperands(res, lhs, rhs, set)) return res;
04913   #endif
04914
04915   // precalculate result sign
04916   bits=(uByte)((lhs->bits^rhs->bits)&DECNEG);
04917
04918   // handle infinities and NaNs
04919   if (SPECIALARGS) {               // a special bit set
04920     if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
04921       decNaNs(res, lhs, rhs, set, status);
04922       return res;}
04923     // one or two infinities; Infinity * 0 is invalid
04924     if (((lhs->bits & DECINF)==0 && ISZERO(lhs))
04925       ||((rhs->bits & DECINF)==0 && ISZERO(rhs))) {
04926       *status|=DEC_Invalid_operation;
04927       return res;}
04928     decNumberZero(res);
04929     res->bits=bits|DECINF;         // infinity
04930     return res;}
04931
04932   // For best speed, as in DMSRCN [the original Rexx numerics
04933   // module], use the shorter number as the multiplier (rhs) and
04934   // the longer as the multiplicand (lhs) to minimise the number of
04935   // adds (partial products)
04936   if (lhs->digits<rhs->digits) {   // swap...
04937     const decNumber *hold=lhs;
04938     lhs=rhs;
04939     rhs=hold;
04940     }
04941
04942   do {                             // protect allocated storage
04943     #if DECSUBSET
04944     if (!set->extended) {
04945       // reduce operands and set lostDigits status, as needed
04946       if (lhs->digits>set->digits) {
04947         alloclhs=decRoundOperand(lhs, set, status);
04948         if (alloclhs==NULL) break;
04949         lhs=alloclhs;
04950         }
04951       if (rhs->digits>set->digits) {
04952         allocrhs=decRoundOperand(rhs, set, status);
04953         if (allocrhs==NULL) break;
04954         rhs=allocrhs;
04955         }
04956       }
04957     #endif
04958     // [following code does not require input rounding]
04959
04960     #if FASTMUL                    // fastpath can be used
04961     // use the fast path if there are enough digits in the shorter
04962     // operand to make the setup and takedown worthwhile
04963     #define NEEDTWO (DECDPUN*2)    // within two decUnitAddSub calls
04964     if (rhs->digits>NEEDTWO) {     // use fastpath...
04965       // calculate the number of elements in each array
04966       ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; // [ceiling]
04967       irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; // ..
04968       iacc=ilhs+irhs;
04969
04970       // allocate buffers if required, as usual
04971       needbytes=ilhs*sizeof(uInt);
04972       if (needbytes>(Int)sizeof(zlhibuff)) {
04973         alloclhi=(uInt *)malloc(needbytes);
04974         zlhi=alloclhi;}
04975       needbytes=irhs*sizeof(uInt);
04976       if (needbytes>(Int)sizeof(zrhibuff)) {
04977         allocrhi=(uInt *)malloc(needbytes);
04978         zrhi=allocrhi;}
04979
04980       // Allocating the accumulator space needs a special case when
04981       // DECDPUN=1 because when converting the accumulator to Units
04982       // after the multiplication each 8-byte item becomes 9 1-byte
04983       // units.  Therefore iacc extra bytes are needed at the front
04984       // (rounded up to a multiple of 8 bytes), and the uLong
04985       // accumulator starts offset the appropriate number of units
04986       // to the right to avoid overwrite during the unchunking.
04987       needbytes=iacc*sizeof(uLong);
04988       #if DECDPUN==1
04989       zoff=(iacc+7)/8;        // items to offset by
04990       needbytes+=zoff*8;
04991       #endif
04992       if (needbytes>(Int)sizeof(zaccbuff)) {
04993         allocacc=(uLong *)malloc(needbytes);
04994         zacc=(uLong *)allocacc;}
04995       if (zlhi==NULL||zrhi==NULL||zacc==NULL) {
04996         *status|=DEC_Insufficient_storage;
04997         break;}
04998
04999       acc=(Unit *)zacc;       // -> target Unit array
05000       #if DECDPUN==1
05001       zacc+=zoff;             // start uLong accumulator to right
05002       #endif
05003
05004       // assemble the chunked copies of the left and right sides
05005       for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)
05006         for (p=0, *lip=0; p<FASTDIGS && count>0;
05007              p+=DECDPUN, cup++, count-=DECDPUN)
05008           *lip+=*cup*powers[p];
05009       lmsi=lip-1;     // save -> msi
05010       for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)
05011         for (p=0, *rip=0; p<FASTDIGS && count>0;
05012              p+=DECDPUN, cup++, count-=DECDPUN)
05013           *rip+=*cup*powers[p];
05014       rmsi=rip-1;     // save -> msi
05015
05016       // zero the accumulator
05017       for (lp=zacc; lp<zacc+iacc; lp++) *lp=0;
05018
05019       /* Start the multiplication */
05020       // Resolving carries can dominate the cost of accumulating the
05021       // partial products, so this is only done when necessary.
05022       // Each uLong item in the accumulator can hold values up to
05023       // 2**64-1, and each partial product can be as large as
05024       // (10**FASTDIGS-1)**2.  When FASTDIGS=9, this can be added to
05025       // itself 18.4 times in a uLong without overflowing, so during
05026       // the main calculation resolution is carried out every 18th
05027       // add -- every 162 digits.  Similarly, when FASTDIGS=8, the
05028       // partial products can be added to themselves 1844.6 times in
05029       // a uLong without overflowing, so intermediate carry
05030       // resolution occurs only every 14752 digits.  Hence for common
05031       // short numbers usually only the one final carry resolution
05032       // occurs.
05033       // (The count is set via FASTLAZY to simplify experiments to
05034       // measure the value of this approach: a 35% improvement on a
05035       // [34x34] multiply.)
05036       lazy=FASTLAZY;                         // carry delay count
05037       for (rip=zrhi; rip<=rmsi; rip++) {     // over each item in rhs
05038         lp=zacc+(rip-zrhi);                  // where to add the lhs
05039         for (lip=zlhi; lip<=lmsi; lip++, lp++) { // over each item in lhs
05040           *lp+=(uLong)(*lip)*(*rip);         // [this should in-line]
05041           } // lip loop
05042         lazy--;
05043         if (lazy>0 && rip!=rmsi) continue;
05044         lazy=FASTLAZY;                       // reset delay count
05045         // spin up the accumulator resolving overflows
05046         for (lp=zacc; lp<zacc+iacc; lp++) {
05047           if (*lp<FASTBASE) continue;        // it fits
05048           lcarry=*lp/FASTBASE;               // top part [slow divide]
05049           // lcarry can exceed 2**32-1, so check again; this check
05050           // and occasional extra divide (slow) is well worth it, as
05051           // it allows FASTLAZY to be increased to 18 rather than 4
05052           // in the FASTDIGS=9 case
05053           if (lcarry<FASTBASE) carry=(uInt)lcarry;  // [usual]
05054            else { // two-place carry [fairly rare]
05055             uInt carry2=(uInt)(lcarry/FASTBASE);    // top top part
05056             *(lp+2)+=carry2;                        // add to item+2
05057             *lp-=((uLong)FASTBASE*FASTBASE*carry2); // [slow]
05058             carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); // [inline]
05059             }
05060           *(lp+1)+=carry;                    // add to item above [inline]
05061           *lp-=((uLong)FASTBASE*carry);      // [inline]
05062           } // carry resolution
05063         } // rip loop
05064
05065       // The multiplication is complete; time to convert back into
05066       // units.  This can be done in-place in the accumulator and in
05067       // 32-bit operations, because carries were resolved after the
05068       // final add.  This needs N-1 divides and multiplies for
05069       // each item in the accumulator (which will become up to N
05070       // units, where 2<=N<=9).
05071       for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {
05072         uInt item=(uInt)*lp;                 // decapitate to uInt
05073         for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) {
05074           uInt part=item/(DECDPUNMAX+1);
05075           *up=(Unit)(item-(part*(DECDPUNMAX+1)));
05076           item=part;
05077           } // p
05078         *up=(Unit)item; up++;                // [final needs no division]
05079         } // lp
05080       accunits=up-acc;                       // count of units
05081       }
05082      else { // here to use units directly, without chunking ['old code']
05083     #endif
05084
05085       // if accumulator will be too long for local storage, then allocate
05086       acc=accbuff;                 // -> assume buffer for accumulator
05087       needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit);
05088       if (needbytes>(Int)sizeof(accbuff)) {
05089         allocacc=(Unit *)malloc(needbytes);
05090         if (allocacc==NULL) {*status|=DEC_Insufficient_storage; break;}
05091         acc=(Unit *)allocacc;                // use the allocated space
05092         }
05093
05094       /* Now the main long multiplication loop */
05095       // Unlike the equivalent in the IBM Java implementation, there
05096       // is no advantage in calculating from msu to lsu.  So, do it
05097       // by the book, as it were.
05098       // Each iteration calculates ACC=ACC+MULTAND*MULT
05099       accunits=1;                  // accumulator starts at '0'
05100       *acc=0;                      // .. (lsu=0)
05101       shift=0;                     // no multiplicand shift at first
05102       madlength=D2U(lhs->digits);  // this won't change
05103       mermsup=rhs->lsu+D2U(rhs->digits); // -> msu+1 of multiplier
05104
05105       for (mer=rhs->lsu; mer<mermsup; mer++) {
05106         // Here, *mer is the next Unit in the multiplier to use
05107         // If non-zero [optimization] add it...
05108         if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift,
05109                                             lhs->lsu, madlength, 0,
05110                                             &acc[shift], *mer)
05111                                             + shift;
05112          else { // extend acc with a 0; it will be used shortly
05113           *(acc+accunits)=0;       // [this avoids length of <=0 later]
05114           accunits++;
05115           }
05116         // multiply multiplicand by 10**DECDPUN for next Unit to left
05117         shift++;                   // add this for 'logical length'
05118         } // n
05119     #if FASTMUL
05120       } // unchunked units
05121     #endif
05122     // common end-path
05123     #if DECTRACE
05124       decDumpAr('*', acc, accunits);         // Show exact result
05125     #endif
05126
05127     // acc now contains the exact result of the multiplication,
05128     // possibly with a leading zero unit; build the decNumber from
05129     // it, noting if any residue
05130     res->bits=bits;                          // set sign
05131     res->digits=decGetDigits(acc, accunits); // count digits exactly
05132
05133     // There can be a 31-bit wrap in calculating the exponent.
05134     // This can only happen if both input exponents are negative and
05135     // both their magnitudes are large.  If there was a wrap, set a
05136     // safe very negative exponent, from which decFinalize() will
05137     // raise a hard underflow shortly.
05138     exponent=lhs->exponent+rhs->exponent;    // calculate exponent
05139     if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)
05140       exponent=-2*DECNUMMAXE;                // force underflow
05141     res->exponent=exponent;                  // OK to overwrite now
05142
05143
05144     // Set the coefficient.  If any rounding, residue records
05145     decSetCoeff(res, set, acc, res->digits, &residue, status);
05146     decFinish(res, set, &residue, status);   // final cleanup
05147     } while(0);                         // end protected
05148
05149   if (allocacc!=NULL) free(allocacc);   // drop any storage used
05150   #if DECSUBSET
05151   if (allocrhs!=NULL) free(allocrhs);   // ..
05152   if (alloclhs!=NULL) free(alloclhs);   // ..
05153   #endif
05154   #if FASTMUL
05155   if (allocrhi!=NULL) free(allocrhi);   // ..
05156   if (alloclhi!=NULL) free(alloclhi);   // ..
05157   #endif
05158   return res;
05159   } // decMultiplyOp
05160
05161 /* ------------------------------------------------------------------ */
05162 /* decExpOp -- effect exponentiation                                  */
05163 /*                                                                    */
05164 /*   This computes C = exp(A)                                         */
05165 /*                                                                    */
05166 /*   res is C, the result.  C may be A                                */
05167 /*   rhs is A                                                         */
05168 /*   set is the context; note that rounding mode has no effect        */
05169 /*                                                                    */
05170 /* C must have space for set->digits digits. status is updated but    */
05171 /* not set.                                                           */
05172 /*                                                                    */
05173 /* Restrictions:                                                      */
05174 /*                                                                    */
05175 /*   digits, emax, and -emin in the context must be less than         */
05176 /*   2*DEC_MAX_MATH (1999998), and the rhs must be within these       */
05177 /*   bounds or a zero.  This is an internal routine, so these         */
05178 /*   restrictions are contractual and not enforced.                   */
05179 /*                                                                    */
05180 /* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
05181 /* almost always be correctly rounded, but may be up to 1 ulp in      */
05182 /* error in rare cases.                                               */
05183 /*                                                                    */
05184 /* Finite results will always be full precision and Inexact, except   */
05185 /* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
05186 /* ------------------------------------------------------------------ */
05187 /* This approach used here is similar to the algorithm described in   */
05188 /*                                                                    */
05189 /*   Variable Precision Exponential Function, T. E. Hull and          */
05190 /*   A. Abrham, ACM Transactions on Mathematical Software, Vol 12 #2, */
05191 /*   pp79-91, ACM, June 1986.                                         */
05192 /*                                                                    */
05193 /* with the main difference being that the iterations in the series   */
05194 /* evaluation are terminated dynamically (which does not require the  */
05195 /* extra variable-precision variables which are expensive in this     */
05196 /* context).                                                          */
05197 /*                                                                    */
05198 /* The error analysis in Hull & Abrham's paper applies except for the */
05199 /* round-off error accumulation during the series evaluation.  This   */
05200 /* code does not precalculate the number of iterations and so cannot  */
05201 /* use Horner's scheme.  Instead, the accumulation is done at double- */
05202 /* precision, which ensures that the additions of the terms are exact */
05203 /* and do not accumulate round-off (and any round-off errors in the   */
05204 /* terms themselves move 'to the right' faster than they can          */
05205 /* accumulate).  This code also extends the calculation by allowing,  */
05206 /* in the spirit of other decNumber operators, the input to be more   */
05207 /* precise than the result (the precision used is based on the more   */
05208 /* precise of the input or requested result).                         */
05209 /*                                                                    */
05210 /* Implementation notes:                                              */
05211 /*                                                                    */
05212 /* 1. This is separated out as decExpOp so it can be called from      */
05213 /*    other Mathematical functions (notably Ln) with a wider range    */
05214 /*    than normal.  In particular, it can handle the slightly wider   */
05215 /*    (double) range needed by Ln (which has to be able to calculate  */
05216 /*    exp(-x) where x can be the tiniest number (Ntiny).              */
05217 /*                                                                    */
05218 /* 2. Normalizing x to be <=0.1 (instead of <=1) reduces loop         */
05219 /*    iterations by appoximately a third with additional (although    */
05220 /*    diminishing) returns as the range is reduced to even smaller    */
05221 /*    fractions.  However, h (the power of 10 used to correct the     */
05222 /*    result at the end, see below) must be kept <=8 as otherwise     */
05223 /*    the final result cannot be computed.  Hence the leverage is a   */
05224 /*    sliding value (8-h), where potentially the range is reduced     */
05225 /*    more for smaller values.                                        */
05226 /*                                                                    */
05227 /*    The leverage that can be applied in this way is severely        */
05228 /*    limited by the cost of the raise-to-the power at the end,       */
05229 /*    which dominates when the number of iterations is small (less    */
05230 /*    than ten) or when rhs is short.  As an example, the adjustment  */
05231 /*    x**10,000,000 needs 31 multiplications, all but one full-width. */
05232 /*                                                                    */
05233 /* 3. The restrictions (especially precision) could be raised with    */
05234 /*    care, but the full decNumber range seems very hard within the   */
05235 /*    32-bit limits.                                                  */
05236 /*                                                                    */
05237 /* 4. The working precisions for the static buffers are twice the     */
05238 /*    obvious size to allow for calls from decNumberPower.            */
05239 /* ------------------------------------------------------------------ */
05240 decNumber * decExpOp(decNumber *res, const decNumber *rhs,
05241                          decContext *set, uInt *status) {
05242   uInt ignore=0;                   // working status
05243   Int h;                           // adjusted exponent for 0.xxxx
05244   Int p;                           // working precision
05245   Int residue;                     // rounding residue
05246   uInt needbytes;                  // for space calculations
05247   const decNumber *x=rhs;          // (may point to safe copy later)
05248   decContext aset, tset, dset;     // working contexts
05249   Int comp;                        // work
05250
05251   // the argument is often copied to normalize it, so (unusually) it
05252   // is treated like other buffers, using DECBUFFER, +1 in case
05253   // DECBUFFER is 0
05254   decNumber bufr[D2N(DECBUFFER*2+1)];
05255   decNumber *allocrhs=NULL;        // non-NULL if rhs buffer allocated
05256
05257   // the working precision will be no more than set->digits+8+1
05258   // so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER
05259   // is 0 (and twice that for the accumulator)
05260
05261   // buffer for t, term (working precision plus)
05262   decNumber buft[D2N(DECBUFFER*2+9+1)];
05263   decNumber *allocbuft=NULL;       // -> allocated buft, iff allocated
05264   decNumber *t=buft;               // term
05265   // buffer for a, accumulator (working precision * 2), at least 9
05266   decNumber bufa[D2N(DECBUFFER*4+18+1)];
05267   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
05268   decNumber *a=bufa;               // accumulator
05269   // decNumber for the divisor term; this needs at most 9 digits
05270   // and so can be fixed size [16 so can use standard context]
05271   decNumber bufd[D2N(16)];
05272   decNumber *d=bufd;               // divisor
05273   decNumber numone;                // constant 1
05274
05275   #if DECCHECK
05276   Int iterations=0;                // for later sanity check
05277   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
05278   #endif
05279
05280   do {                                  // protect allocated storage
05281     if (SPECIALARG) {                   // handle infinities and NaNs
05282       if (decNumberIsInfinite(rhs)) {   // an infinity
05283         if (decNumberIsNegative(rhs))   // -Infinity -> +0
05284           decNumberZero(res);
05285          else decNumberCopy(res, rhs);  // +Infinity -> self
05286         }
05287        else decNaNs(res, rhs, NULL, set, status); // a NaN
05288       break;}
05289
05290     if (ISZERO(rhs)) {                  // zeros -> exact 1
05291       decNumberZero(res);               // make clean 1
05292       *res->lsu=1;                      // ..
05293       break;}                           // [no status to set]
05294
05295     // e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path
05296     // positive and negative tiny cases which will result in inexact
05297     // 1.  This also allows the later add-accumulate to always be
05298     // exact (because its length will never be more than twice the
05299     // working precision).
05300     // The comparator (tiny) needs just one digit, so use the
05301     // decNumber d for it (reused as the divisor, etc., below); its
05302     // exponent is such that if x is positive it will have
05303     // set->digits-1 zeros between the decimal point and the digit,
05304     // which is 4, and if x is negative one more zero there as the
05305     // more precise result will be of the form 0.9999999 rather than
05306     // 1.0000001.  Hence, tiny will be 0.0000004  if digits=7 and x>0
05307     // or 0.00000004 if digits=7 and x<0.  If RHS not larger than
05308     // this then the result will be 1.000000
05309     decNumberZero(d);                   // clean
05310     *d->lsu=4;                          // set 4 ..
05311     d->exponent=-set->digits;           // * 10**(-d)
05312     if (decNumberIsNegative(rhs)) d->exponent--;  // negative case
05313     comp=decCompare(d, rhs, 1);         // signless compare
05314     if (comp==BADINT) {
05315       *status|=DEC_Insufficient_storage;
05316       break;}
05317     if (comp>=0) {                      // rhs < d
05318       Int shift=set->digits-1;
05319       decNumberZero(res);               // set 1
05320       *res->lsu=1;                      // ..
05321       res->digits=decShiftToMost(res->lsu, 1, shift);
05322       res->exponent=-shift;                  // make 1.0000...
05323       *status|=DEC_Inexact | DEC_Rounded;    // .. inexactly
05324       break;} // tiny
05325
05326     // set up the context to be used for calculating a, as this is
05327     // used on both paths below
05328     decContextDefault(&aset, DEC_INIT_DECIMAL64);
05329     // accumulator bounds are as requested (could underflow)
05330     aset.emax=set->emax;                // usual bounds
05331     aset.emin=set->emin;                // ..
05332     aset.clamp=0;                       // and no concrete format
05333
05334     // calculate the adjusted (Hull & Abrham) exponent (where the
05335     // decimal point is just to the left of the coefficient msd)
05336     h=rhs->exponent+rhs->digits;
05337     // if h>8 then 10**h cannot be calculated safely; however, when
05338     // h=8 then exp(|rhs|) will be at least exp(1E+7) which is at
05339     // least 6.59E+4342944, so (due to the restriction on Emax/Emin)
05340     // overflow (or underflow to 0) is guaranteed -- so this case can
05341     // be handled by simply forcing the appropriate excess
05342     if (h>8) {                          // overflow/underflow
05343       // set up here so Power call below will over or underflow to
05344       // zero; set accumulator to either 2 or 0.02
05345       // [stack buffer for a is always big enough for this]
05346       decNumberZero(a);
05347       *a->lsu=2;                        // not 1 but < exp(1)
05348       if (decNumberIsNegative(rhs)) a->exponent=-2; // make 0.02
05349       h=8;                              // clamp so 10**h computable
05350       p=9;                              // set a working precision
05351       }
05352      else {                             // h<=8
05353       Int maxlever=(rhs->digits>8?1:0);
05354       // [could/should increase this for precisions >40 or so, too]
05355
05356       // if h is 8, cannot normalize to a lower upper limit because
05357       // the final result will not be computable (see notes above),
05358       // but leverage can be applied whenever h is less than 8.
05359       // Apply as much as possible, up to a MAXLEVER digits, which
05360       // sets the tradeoff against the cost of the later a**(10**h).
05361       // As h is increased, the working precision below also
05362       // increases to compensate for the "constant digits at the
05363       // front" effect.
05364       Int lever=MINI(8-h, maxlever);    // leverage attainable
05365       Int use=-rhs->digits-lever;       // exponent to use for RHS
05366       h+=lever;                         // apply leverage selected
05367       if (h<0) {                        // clamp
05368         use+=h;                         // [may end up subnormal]
05369         h=0;
05370         }
05371       // Take a copy of RHS if it needs normalization (true whenever x>=1)
05372       if (rhs->exponent!=use) {
05373         decNumber *newrhs=bufr;         // assume will fit on stack
05374         needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
05375         if (needbytes>sizeof(bufr)) {   // need malloc space
05376           allocrhs=(decNumber *)malloc(needbytes);
05377           if (allocrhs==NULL) {         // hopeless -- abandon
05378             *status|=DEC_Insufficient_storage;
05379             break;}
05380           newrhs=allocrhs;              // use the allocated space
05381           }
05382         decNumberCopy(newrhs, rhs);     // copy to safe space
05383         newrhs->exponent=use;           // normalize; now <1
05384         x=newrhs;                       // ready for use
05385         // decNumberShow(x);
05386         }
05387
05388       // Now use the usual power series to evaluate exp(x).  The
05389       // series starts as 1 + x + x^2/2 ... so prime ready for the
05390       // third term by setting the term variable t=x, the accumulator
05391       // a=1, and the divisor d=2.
05392
05393       // First determine the working precision.  From Hull & Abrham
05394       // this is set->digits+h+2.  However, if x is 'over-precise' we
05395       // need to allow for all its digits to potentially participate
05396       // (consider an x where all the excess digits are 9s) so in
05397       // this case use x->digits+h+2
05398       p=MAXI(x->digits, set->digits)+h+2;    // [h<=8]
05399
05400       // a and t are variable precision, and depend on p, so space
05401       // must be allocated for them if necessary
05402
05403       // the accumulator needs to be able to hold 2p digits so that
05404       // the additions on the second and subsequent iterations are
05405       // sufficiently exact.
05406       needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit);
05407       if (needbytes>sizeof(bufa)) {     // need malloc space
05408         allocbufa=(decNumber *)malloc(needbytes);
05409         if (allocbufa==NULL) {          // hopeless -- abandon
05410           *status|=DEC_Insufficient_storage;
05411           break;}
05412         a=allocbufa;                    // use the allocated space
05413         }
05414       // the term needs to be able to hold p digits (which is
05415       // guaranteed to be larger than x->digits, so the initial copy
05416       // is safe); it may also be used for the raise-to-power
05417       // calculation below, which needs an extra two digits
05418       needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit);
05419       if (needbytes>sizeof(buft)) {     // need malloc space
05420         allocbuft=(decNumber *)malloc(needbytes);
05421         if (allocbuft==NULL) {          // hopeless -- abandon
05422           *status|=DEC_Insufficient_storage;
05423           break;}
05424         t=allocbuft;                    // use the allocated space
05425         }
05426
05427       decNumberCopy(t, x);              // term=x
05428       decNumberZero(a); *a->lsu=1;      // accumulator=1
05429       decNumberZero(d); *d->lsu=2;      // divisor=2
05430       decNumberZero(&numone); *numone.lsu=1; // constant 1 for increment
05431
05432       // set up the contexts for calculating a, t, and d
05433       decContextDefault(&tset, DEC_INIT_DECIMAL64);
05434       dset=tset;
05435       // accumulator bounds are set above, set precision now
05436       aset.digits=p*2;                  // double
05437       // term bounds avoid any underflow or overflow
05438       tset.digits=p;
05439       tset.emin=DEC_MIN_EMIN;           // [emax is plenty]
05440       // [dset.digits=16, etc., are sufficient]
05441
05442       // finally ready to roll
05443       for (;;) {
05444         #if DECCHECK
05445         iterations++;
05446         #endif
05447         // only the status from the accumulation is interesting
05448         // [but it should remain unchanged after first add]
05449         decAddOp(a, a, t, &aset, 0, status);           // a=a+t
05450         decMultiplyOp(t, t, x, &tset, &ignore);        // t=t*x
05451         decDivideOp(t, t, d, &tset, DIVIDE, &ignore);  // t=t/d
05452         // the iteration ends when the term cannot affect the result,
05453         // if rounded to p digits, which is when its value is smaller
05454         // than the accumulator by p+1 digits.  There must also be
05455         // full precision in a.
05456         if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))
05457             && (a->digits>=p)) break;
05458         decAddOp(d, d, &numone, &dset, 0, &ignore);    // d=d+1
05459         } // iterate
05460
05461       #if DECCHECK
05462       // just a sanity check; comment out test to show always
05463       if (iterations>p+3)
05464         printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
05465                (LI)iterations, (LI)*status, (LI)p, (LI)x->digits);
05466       #endif
05467       } // h<=8
05468
05469     // apply postconditioning: a=a**(10**h) -- this is calculated
05470     // at a slightly higher precision than Hull & Abrham suggest
05471     if (h>0) {
05472       Int seenbit=0;               // set once a 1-bit is seen
05473       Int i;                       // counter
05474       Int n=powers[h];             // always positive
05475       aset.digits=p+2;             // sufficient precision
05476       // avoid the overhead and many extra digits of decNumberPower
05477       // as all that is needed is the short 'multipliers' loop; here
05478       // accumulate the answer into t
05479       decNumberZero(t); *t->lsu=1; // acc=1
05480       for (i=1;;i++){              // for each bit [top bit ignored]
05481         // abandon if have had overflow or terminal underflow
05482         if (*status & (DEC_Overflow|DEC_Underflow)) { // interesting?
05483           if (*status&DEC_Overflow || ISZERO(t)) break;}
05484         n=n<<1;                    // move next bit to testable position
05485         if (n<0) {                 // top bit is set
05486           seenbit=1;               // OK, have a significant bit
05487           decMultiplyOp(t, t, a, &aset, status); // acc=acc*x
05488           }
05489         if (i==31) break;          // that was the last bit
05490         if (!seenbit) continue;    // no need to square 1
05491         decMultiplyOp(t, t, t, &aset, status); // acc=acc*acc [square]
05492         } /*i*/ // 32 bits
05493       // decNumberShow(t);
05494       a=t;                         // and carry on using t instead of a
05495       }
05496
05497     // Copy and round the result to res
05498     residue=1;                          // indicate dirt to right ..
05499     if (ISZERO(a)) residue=0;           // .. unless underflowed to 0
05500     aset.digits=set->digits;            // [use default rounding]
05501     decCopyFit(res, a, &aset, &residue, status); // copy & shorten
05502     decFinish(res, set, &residue, status);       // cleanup/set flags
05503     } while(0);                         // end protected
05504
05505   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
05506   if (allocbufa!=NULL) free(allocbufa); // ..
05507   if (allocbuft!=NULL) free(allocbuft); // ..
05508   // [status is handled by caller]
05509   return res;
05510   } // decExpOp
05511
05512 /* ------------------------------------------------------------------ */
05513 /* Initial-estimate natural logarithm table                           */
05514 /*                                                                    */
05515 /*   LNnn -- 90-entry 16-bit table for values from .10 through .99.   */
05516 /*           The result is a 4-digit encode of the coefficient (c=the */
05517 /*           top 14 bits encoding 0-9999) and a 2-digit encode of the */
05518 /*           exponent (e=the bottom 2 bits encoding 0-3)              */
05519 /*                                                                    */
05520 /*           The resulting value is given by:                         */
05521 /*                                                                    */
05522 /*             v = -c * 10**(-e-3)                                    */
05523 /*                                                                    */
05524 /*           where e and c are extracted from entry k = LNnn[x-10]    */
05525 /*           where x is truncated (NB) into the range 10 through 99,  */
05526 /*           and then c = k>>2 and e = k&3.                           */
05527 /* ------------------------------------------------------------------ */
05528 const uShort LNnn[90]={9016,  8652,  8316,  8008,  7724,  7456,  7208,
05529   6972,  6748,  6540,  6340,  6148,  5968,  5792,  5628,  5464,  5312,
05530   5164,  5020,  4884,  4748,  4620,  4496,  4376,  4256,  4144,  4032,
05531  39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
05532  29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
05533  22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
05534  15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
05535  10197,  9685,  9177,  8677,  8185,  7697,  7213,  6737,  6269,  5801,
05536   5341,  4889,  4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
05537  10130,  6046, 20055};
05538
05539 /* ------------------------------------------------------------------ */
05540 /* decLnOp -- effect natural logarithm                                */
05541 /*                                                                    */
05542 /*   This computes C = ln(A)                                          */
05543 /*                                                                    */
05544 /*   res is C, the result.  C may be A                                */
05545 /*   rhs is A                                                         */
05546 /*   set is the context; note that rounding mode has no effect        */
05547 /*                                                                    */
05548 /* C must have space for set->digits digits.                          */
05549 /*                                                                    */
05550 /* Notable cases:                                                     */
05551 /*   A<0 -> Invalid                                                   */
05552 /*   A=0 -> -Infinity (Exact)                                         */
05553 /*   A=+Infinity -> +Infinity (Exact)                                 */
05554 /*   A=1 exactly -> 0 (Exact)                                         */
05555 /*                                                                    */
05556 /* Restrictions (as for Exp):                                         */
05557 /*                                                                    */
05558 /*   digits, emax, and -emin in the context must be less than         */
05559 /*   DEC_MAX_MATH+11 (1000010), and the rhs must be within these      */
05560 /*   bounds or a zero.  This is an internal routine, so these         */
05561 /*   restrictions are contractual and not enforced.                   */
05562 /*                                                                    */
05563 /* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
05564 /* almost always be correctly rounded, but may be up to 1 ulp in      */
05565 /* error in rare cases.                                               */
05566 /* ------------------------------------------------------------------ */
05567 /* The result is calculated using Newton's method, with each          */
05568 /* iteration calculating a' = a + x * exp(-a) - 1.  See, for example, */
05569 /* Epperson 1989.                                                     */
05570 /*                                                                    */
05571 /* The iteration ends when the adjustment x*exp(-a)-1 is tiny enough. */
05572 /* This has to be calculated at the sum of the precision of x and the */
05573 /* working precision.                                                 */
05574 /*                                                                    */
05575 /* Implementation notes:                                              */
05576 /*                                                                    */
05577 /* 1. This is separated out as decLnOp so it can be called from       */
05578 /*    other Mathematical functions (e.g., Log 10) with a wider range  */
05579 /*    than normal.  In particular, it can handle the slightly wider   */
05580 /*    (+9+2) range needed by a power function.                        */
05581 /*                                                                    */
05582 /* 2. The speed of this function is about 10x slower than exp, as     */
05583 /*    it typically needs 4-6 iterations for short numbers, and the    */
05584 /*    extra precision needed adds a squaring effect, twice.           */
05585 /*                                                                    */
05586 /* 3. Fastpaths are included for ln(10) and ln(2), up to length 40,   */
05587 /*    as these are common requests.  ln(10) is used by log10(x).      */
05588 /*                                                                    */
05589 /* 4. An iteration might be saved by widening the LNnn table, and     */
05590 /*    would certainly save at least one if it were made ten times     */
05591 /*    bigger, too (for truncated fractions 0.100 through 0.999).      */
05592 /*    However, for most practical evaluations, at least four or five  */
05593 /*    iterations will be neede -- so this would only speed up by      */
05594 /*    20-25% and that probably does not justify increasing the table  */
05595 /*    size.                                                           */
05596 /*                                                                    */
05597 /* 5. The static buffers are larger than might be expected to allow   */
05598 /*    for calls from decNumberPower.                                  */
05599 /* ------------------------------------------------------------------ */
05600 decNumber * decLnOp(decNumber *res, const decNumber *rhs,
05601                     decContext *set, uInt *status) {
05602   uInt ignore=0;                   // working status accumulator
05603   uInt needbytes;                  // for space calculations
05604   Int residue;                     // rounding residue
05605   Int r;                           // rhs=f*10**r [see below]
05606   Int p;                           // working precision
05607   Int pp;                          // precision for iteration
05608   Int t;                           // work
05609
05610   // buffers for a (accumulator, typically precision+2) and b
05611   // (adjustment calculator, same size)
05612   decNumber bufa[D2N(DECBUFFER+12)];
05613   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
05614   decNumber *a=bufa;               // accumulator/work
05615   decNumber bufb[D2N(DECBUFFER*2+2)];
05616   decNumber *allocbufb=NULL;       // -> allocated bufa, iff allocated
05617   decNumber *b=bufb;               // adjustment/work
05618
05619   decNumber  numone;               // constant 1
05620   decNumber  cmp;                  // work
05621   decContext aset, bset;           // working contexts
05622
05623   #if DECCHECK
05624   Int iterations=0;                // for later sanity check
05625   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
05626   #endif
05627
05628   do {                                  // protect allocated storage
05629     if (SPECIALARG) {                   // handle infinities and NaNs
05630       if (decNumberIsInfinite(rhs)) {   // an infinity
05631         if (decNumberIsNegative(rhs))   // -Infinity -> error
05632           *status|=DEC_Invalid_operation;
05633          else decNumberCopy(res, rhs);  // +Infinity -> self
05634         }
05635        else decNaNs(res, rhs, NULL, set, status); // a NaN
05636       break;}
05637
05638     if (ISZERO(rhs)) {                  // +/- zeros -> -Infinity
05639       decNumberZero(res);               // make clean
05640       res->bits=DECINF|DECNEG;          // set - infinity
05641       break;}                           // [no status to set]
05642
05643     // Non-zero negatives are bad...
05644     if (decNumberIsNegative(rhs)) {     // -x -> error
05645       *status|=DEC_Invalid_operation;
05646       break;}
05647
05648     // Here, rhs is positive, finite, and in range
05649
05650     // lookaside fastpath code for ln(2) and ln(10) at common lengths
05651     if (rhs->exponent==0 && set->digits<=40) {
05652       #if DECDPUN==1
05653       if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { // ln(10)
05654       #else
05655       if (rhs->lsu[0]==10 && rhs->digits==2) {                  // ln(10)
05656       #endif
05657         aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
05658         #define LN10 "2.302585092994045684017991454684364207601"
05659         decNumberFromString(res, LN10, &aset);
05660         *status|=(DEC_Inexact | DEC_Rounded); // is inexact
05661         break;}
05662       if (rhs->lsu[0]==2 && rhs->digits==1) { // ln(2)
05663         aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
05664         #define LN2 "0.6931471805599453094172321214581765680755"
05665         decNumberFromString(res, LN2, &aset);
05666         *status|=(DEC_Inexact | DEC_Rounded);
05667         break;}
05668       } // integer and short
05669
05670     // Determine the working precision.  This is normally the
05671     // requested precision + 2, with a minimum of 9.  However, if
05672     // the rhs is 'over-precise' then allow for all its digits to
05673     // potentially participate (consider an rhs where all the excess
05674     // digits are 9s) so in this case use rhs->digits+2.
05675     p=MAXI(rhs->digits, MAXI(set->digits, 7))+2;
05676
05677     // Allocate space for the accumulator and the high-precision
05678     // adjustment calculator, if necessary.  The accumulator must
05679     // be able to hold p digits, and the adjustment up to
05680     // rhs->digits+p digits.  They are also made big enough for 16
05681     // digits so that they can be used for calculating the initial
05682     // estimate.
05683     needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))-1)*sizeof(Unit);
05684     if (needbytes>sizeof(bufa)) {     // need malloc space
05685       allocbufa=(decNumber *)malloc(needbytes);
05686       if (allocbufa==NULL) {          // hopeless -- abandon
05687         *status|=DEC_Insufficient_storage;
05688         break;}
05689       a=allocbufa;                    // use the allocated space
05690       }
05691     pp=p+rhs->digits;
05692     needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))-1)*sizeof(Unit);
05693     if (needbytes>sizeof(bufb)) {     // need malloc space
05694       allocbufb=(decNumber *)malloc(needbytes);
05695       if (allocbufb==NULL) {          // hopeless -- abandon
05696         *status|=DEC_Insufficient_storage;
05697         break;}
05698       b=allocbufb;                    // use the allocated space
05699       }
05700
05701     // Prepare an initial estimate in acc. Calculate this by
05702     // considering the coefficient of x to be a normalized fraction,
05703     // f, with the decimal point at far left and multiplied by
05704     // 10**r.  Then, rhs=f*10**r and 0.1<=f<1, and
05705     //   ln(x) = ln(f) + ln(10)*r
05706     // Get the initial estimate for ln(f) from a small lookup
05707     // table (see above) indexed by the first two digits of f,
05708     // truncated.
05709
05710     decContextDefault(&aset, DEC_INIT_DECIMAL64); // 16-digit extended
05711     r=rhs->exponent+rhs->digits;        // 'normalised' exponent
05712     decNumberFromInt32(a, r);           // a=r
05713     decNumberFromInt32(b, 2302585);     // b=ln(10) (2.302585)
05714     b->exponent=-6;                     //  ..
05715     decMultiplyOp(a, a, b, &aset, &ignore);  // a=a*b
05716     // now get top two digits of rhs into b by simple truncate and
05717     // force to integer
05718     residue=0;                          // (no residue)
05719     aset.digits=2; aset.round=DEC_ROUND_DOWN;
05720     decCopyFit(b, rhs, &aset, &residue, &ignore); // copy & shorten
05721     b->exponent=0;                      // make integer
05722     t=decGetInt(b);                     // [cannot fail]
05723     if (t<10) t=X10(t);                 // adjust single-digit b
05724     t=LNnn[t-10];                       // look up ln(b)
05725     decNumberFromInt32(b, t>>2);        // b=ln(b) coefficient
05726     b->exponent=-(t&3)-3;               // set exponent
05727     b->bits=DECNEG;                     // ln(0.10)->ln(0.99) always -ve
05728     aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; // restore
05729     decAddOp(a, a, b, &aset, 0, &ignore); // acc=a+b
05730     // the initial estimate is now in a, with up to 4 digits correct.
05731     // When rhs is at or near Nmax the estimate will be low, so we
05732     // will approach it from below, avoiding overflow when calling exp.
05733
05734     decNumberZero(&numone); *numone.lsu=1;   // constant 1 for adjustment
05735
05736     // accumulator bounds are as requested (could underflow, but
05737     // cannot overflow)
05738     aset.emax=set->emax;
05739     aset.emin=set->emin;
05740     aset.clamp=0;                       // no concrete format
05741     // set up a context to be used for the multiply and subtract
05742     bset=aset;
05743     bset.emax=DEC_MAX_MATH*2;           // use double bounds for the
05744     bset.emin=-DEC_MAX_MATH*2;          // adjustment calculation
05745                                         // [see decExpOp call below]
05746     // for each iteration double the number of digits to calculate,
05747     // up to a maximum of p
05748     pp=9;                               // initial precision
05749     // [initially 9 as then the sequence starts 7+2, 16+2, and
05750     // 34+2, which is ideal for standard-sized numbers]
05751     aset.digits=pp;                     // working context
05752     bset.digits=pp+rhs->digits;         // wider context
05753     for (;;) {                          // iterate
05754       #if DECCHECK
05755       iterations++;
05756       if (iterations>24) break;         // consider 9 * 2**24
05757       #endif
05758       // calculate the adjustment (exp(-a)*x-1) into b.  This is a
05759       // catastrophic subtraction but it really is the difference
05760       // from 1 that is of interest.
05761       // Use the internal entry point to Exp as it allows the double
05762       // range for calculating exp(-a) when a is the tiniest subnormal.
05763       a->bits^=DECNEG;                  // make -a
05764       decExpOp(b, a, &bset, &ignore);   // b=exp(-a)
05765       a->bits^=DECNEG;                  // restore sign of a
05766       // now multiply by rhs and subtract 1, at the wider precision
05767       decMultiplyOp(b, b, rhs, &bset, &ignore);        // b=b*rhs
05768       decAddOp(b, b, &numone, &bset, DECNEG, &ignore); // b=b-1
05769
05770       // the iteration ends when the adjustment cannot affect the
05771       // result by >=0.5 ulp (at the requested digits), which
05772       // is when its value is smaller than the accumulator by
05773       // set->digits+1 digits (or it is zero) -- this is a looser
05774       // requirement than for Exp because all that happens to the
05775       // accumulator after this is the final rounding (but note that
05776       // there must also be full precision in a, or a=0).
05777
05778       if (decNumberIsZero(b) ||
05779           (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {
05780         if (a->digits==p) break;
05781         if (decNumberIsZero(a)) {
05782           decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); // rhs=1 ?
05783           if (cmp.lsu[0]==0) a->exponent=0;            // yes, exact 0
05784            else *status|=(DEC_Inexact | DEC_Rounded);  // no, inexact
05785           break;
05786           }
05787         // force padding if adjustment has gone to 0 before full length
05788         if (decNumberIsZero(b)) b->exponent=a->exponent-p;
05789         }
05790
05791       // not done yet ...
05792       decAddOp(a, a, b, &aset, 0, &ignore);  // a=a+b for next estimate
05793       if (pp==p) continue;                   // precision is at maximum
05794       // lengthen the next calculation
05795       pp=pp*2;                               // double precision
05796       if (pp>p) pp=p;                        // clamp to maximum
05797       aset.digits=pp;                        // working context
05798       bset.digits=pp+rhs->digits;            // wider context
05799       } // Newton's iteration
05800
05801     #if DECCHECK
05802     // just a sanity check; remove the test to show always
05803     if (iterations>24)
05804       printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
05805             (LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits);
05806     #endif
05807
05808     // Copy and round the result to res
05809     residue=1;                          // indicate dirt to right
05810     if (ISZERO(a)) residue=0;           // .. unless underflowed to 0
05811     aset.digits=set->digits;            // [use default rounding]
05812     decCopyFit(res, a, &aset, &residue, status); // copy & shorten
05813     decFinish(res, set, &residue, status);       // cleanup/set flags
05814     } while(0);                         // end protected
05815
05816   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
05817   if (allocbufb!=NULL) free(allocbufb); // ..
05818   // [status is handled by caller]
05819   return res;
05820   } // decLnOp
05821
05822 /* ------------------------------------------------------------------ */
05823 /* decQuantizeOp  -- force exponent to requested value                */
05824 /*                                                                    */
05825 /*   This computes C = op(A, B), where op adjusts the coefficient     */
05826 /*   of C (by rounding or shifting) such that the exponent (-scale)   */
05827 /*   of C has the value B or matches the exponent of B.               */
05828 /*   The numerical value of C will equal A, except for the effects of */
05829 /*   any rounding that occurred.                                      */
05830 /*                                                                    */
05831 /*   res is C, the result.  C may be A or B                           */
05832 /*   lhs is A, the number to adjust                                   */
05833 /*   rhs is B, the requested exponent                                 */
05834 /*   set is the context                                               */
05835 /*   quant is 1 for quantize or 0 for rescale                         */
05836 /*   status is the status accumulator (this can be called without     */
05837 /*          risk of control loss)                                     */
05838 /*                                                                    */
05839 /* C must have space for set->digits digits.                          */
05840 /*                                                                    */
05841 /* Unless there is an error or the result is infinite, the exponent   */
05842 /* after the operation is guaranteed to be that requested.            */
05843 /* ------------------------------------------------------------------ */
05844 static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
05845                                  const decNumber *rhs, decContext *set,
05846                                  Flag quant, uInt *status) {
05847   #if DECSUBSET
05848   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
05849   decNumber *allocrhs=NULL;        // .., rhs
05850   #endif
05851   const decNumber *inrhs=rhs;      // save original rhs
05852   Int   reqdigits=set->digits;     // requested DIGITS
05853   Int   reqexp;                    // requested exponent [-scale]
05854   Int   residue=0;                 // rounding residue
05855   Int   etiny=set->emin-(reqdigits-1);
05856
05857   #if DECCHECK
05858   if (decCheckOperands(res, lhs, rhs, set)) return res;
05859   #endif
05860
05861   do {                             // protect allocated storage
05862     #if DECSUBSET
05863     if (!set->extended) {
05864       // reduce operands and set lostDigits status, as needed
05865       if (lhs->digits>reqdigits) {
05866         alloclhs=decRoundOperand(lhs, set, status);
05867         if (alloclhs==NULL) break;
05868         lhs=alloclhs;
05869         }
05870       if (rhs->digits>reqdigits) { // [this only checks lostDigits]
05871         allocrhs=decRoundOperand(rhs, set, status);
05872         if (allocrhs==NULL) break;
05873         rhs=allocrhs;
05874         }
05875       }
05876     #endif
05877     // [following code does not require input rounding]
05878
05879     // Handle special values
05880     if (SPECIALARGS) {
05881       // NaNs get usual processing
05882       if (SPECIALARGS & (DECSNAN | DECNAN))
05883         decNaNs(res, lhs, rhs, set, status);
05884       // one infinity but not both is bad
05885       else if ((lhs->bits ^ rhs->bits) & DECINF)
05886         *status|=DEC_Invalid_operation;
05887       // both infinity: return lhs
05888       else decNumberCopy(res, lhs);          // [nop if in place]
05889       break;
05890       }
05891
05892     // set requested exponent
05893     if (quant) reqexp=inrhs->exponent;  // quantize -- match exponents
05894      else {                             // rescale -- use value of rhs
05895       // Original rhs must be an integer that fits and is in range,
05896       // which could be from -1999999997 to +999999999, thanks to
05897       // subnormals
05898       reqexp=decGetInt(inrhs);               // [cannot fail]
05899       }
05900
05901     #if DECSUBSET
05902     if (!set->extended) etiny=set->emin;     // no subnormals
05903     #endif
05904
05905     if (reqexp==BADINT                       // bad (rescale only) or ..
05906      || reqexp==BIGODD || reqexp==BIGEVEN    // very big (ditto) or ..
05907      || (reqexp<etiny)                       // < lowest
05908      || (reqexp>set->emax)) {                // > emax
05909       *status|=DEC_Invalid_operation;
05910       break;}
05911
05912     // the RHS has been processed, so it can be overwritten now if necessary
05913     if (ISZERO(lhs)) {                       // zero coefficient unchanged
05914       decNumberCopy(res, lhs);               // [nop if in place]
05915       res->exponent=reqexp;                  // .. just set exponent
05916       #if DECSUBSET
05917       if (!set->extended) res->bits=0;       // subset specification; no -0
05918       #endif
05919       }
05920      else {                                  // non-zero lhs
05921       Int adjust=reqexp-lhs->exponent;       // digit adjustment needed
05922       // if adjusted coefficient will definitely not fit, give up now
05923       if ((lhs->digits-adjust)>reqdigits) {
05924         *status|=DEC_Invalid_operation;
05925         break;
05926         }
05927
05928       if (adjust>0) {                        // increasing exponent
05929         // this will decrease the length of the coefficient by adjust
05930         // digits, and must round as it does so
05931         decContext workset;                  // work
05932         workset=*set;                        // clone rounding, etc.
05933         workset.digits=lhs->digits-adjust;   // set requested length
05934         // [note that the latter can be <1, here]
05935         decCopyFit(res, lhs, &workset, &residue, status); // fit to result
05936         decApplyRound(res, &workset, residue, status);    // .. and round
05937         residue=0;                                        // [used]
05938         // If just rounded a 999s case, exponent will be off by one;
05939         // adjust back (after checking space), if so.
05940         if (res->exponent>reqexp) {
05941           // re-check needed, e.g., for quantize(0.9999, 0.001) under
05942           // set->digits==3
05943           if (res->digits==reqdigits) {      // cannot shift by 1
05944             *status&=~(DEC_Inexact | DEC_Rounded); // [clean these]
05945             *status|=DEC_Invalid_operation;
05946             break;
05947             }
05948           res->digits=decShiftToMost(res->lsu, res->digits, 1); // shift
05949           res->exponent--;                   // (re)adjust the exponent.
05950           }
05951         #if DECSUBSET
05952         if (ISZERO(res) && !set->extended) res->bits=0; // subset; no -0
05953         #endif
05954         } // increase
05955        else /* adjust<=0 */ {                // decreasing or = exponent
05956         // this will increase the length of the coefficient by -adjust
05957         // digits, by adding zero or more trailing zeros; this is
05958         // already checked for fit, above
05959         decNumberCopy(res, lhs);             // [it will fit]
05960         // if padding needed (adjust<0), add it now...
05961         if (adjust<0) {
05962           res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
05963           res->exponent+=adjust;             // adjust the exponent
05964           }
05965         } // decrease
05966       } // non-zero
05967
05968     // Check for overflow [do not use Finalize in this case, as an
05969     // overflow here is a "don't fit" situation]
05970     if (res->exponent>set->emax-res->digits+1) {  // too big
05971       *status|=DEC_Invalid_operation;
05972       break;
05973       }
05974      else {
05975       decFinalize(res, set, &residue, status);    // set subnormal flags
05976       *status&=~DEC_Underflow;          // suppress Underflow [as per 754]
05977       }
05978     } while(0);                         // end protected
05979
05980   #if DECSUBSET
05981   if (allocrhs!=NULL) free(allocrhs);   // drop any storage used
05982   if (alloclhs!=NULL) free(alloclhs);   // ..
05983   #endif
05984   return res;
05985   } // decQuantizeOp
05986
05987 /* ------------------------------------------------------------------ */
05988 /* decCompareOp -- compare, min, or max two Numbers                   */
05989 /*                                                                    */
05990 /*   This computes C = A ? B and carries out one of four operations:  */
05991 /*     COMPARE    -- returns the signum (as a number) giving the      */
05992 /*                   result of a comparison unless one or both        */
05993 /*                   operands is a NaN (in which case a NaN results)  */
05994 /*     COMPSIG    -- as COMPARE except that a quiet NaN raises        */
05995 /*                   Invalid operation.                               */
05996 /*     COMPMAX    -- returns the larger of the operands, using the    */
05997 /*                   754 maxnum operation                             */
05998 /*     COMPMAXMAG -- ditto, comparing absolute values                 */
05999 /*     COMPMIN    -- the 754 minnum operation                         */
06000 /*     COMPMINMAG -- ditto, comparing absolute values                 */
06001 /*     COMTOTAL   -- returns the signum (as a number) giving the      */
06002 /*                   result of a comparison using 754 total ordering  */
06003 /*                                                                    */
06004 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
06005 /*   lhs is A                                                         */
06006 /*   rhs is B                                                         */
06007 /*   set is the context                                               */
06008 /*   op  is the operation flag                                        */
06009 /*   status is the usual accumulator                                  */
06010 /*                                                                    */
06011 /* C must have space for one digit for COMPARE or set->digits for     */
06012 /* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG.                       */
06013 /* ------------------------------------------------------------------ */
06014 /* The emphasis here is on speed for common cases, and avoiding       */
06015 /* coefficient comparison if possible.                                */
06016 /* ------------------------------------------------------------------ */
06017 decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
06018                          const decNumber *rhs, decContext *set,
06019                          Flag op, uInt *status) {
06020   #if DECSUBSET
06021   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
06022   decNumber *allocrhs=NULL;        // .., rhs
06023   #endif
06024   Int   result=0;                  // default result value
06025   uByte merged;                    // work
06026
06027   #if DECCHECK
06028   if (decCheckOperands(res, lhs, rhs, set)) return res;
06029   #endif
06030
06031   do {                             // protect allocated storage
06032     #if DECSUBSET
06033     if (!set->extended) {
06034       // reduce operands and set lostDigits status, as needed
06035       if (lhs->digits>set->digits) {
06036         alloclhs=decRoundOperand(lhs, set, status);
06037         if (alloclhs==NULL) {result=BADINT; break;}
06038         lhs=alloclhs;
06039         }
06040       if (rhs->digits>set->digits) {
06041         allocrhs=decRoundOperand(rhs, set, status);
06042         if (allocrhs==NULL) {result=BADINT; break;}
06043         rhs=allocrhs;
06044         }
06045       }
06046     #endif
06047     // [following code does not require input rounding]
06048
06049     // If total ordering then handle differing signs 'up front'
06050     if (op==COMPTOTAL) {                // total ordering
06051       if (decNumberIsNegative(lhs) & !decNumberIsNegative(rhs)) {
06052         result=-1;
06053         break;
06054         }
06055       if (!decNumberIsNegative(lhs) & decNumberIsNegative(rhs)) {
06056         result=+1;
06057         break;
06058         }
06059       }
06060
06061     // handle NaNs specially; let infinities drop through
06062     // This assumes sNaN (even just one) leads to NaN.
06063     merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
06064     if (merged) {                       // a NaN bit set
06065       if (op==COMPARE);                 // result will be NaN
06066        else if (op==COMPSIG)            // treat qNaN as sNaN
06067         *status|=DEC_Invalid_operation | DEC_sNaN;
06068        else if (op==COMPTOTAL) {        // total ordering, always finite
06069         // signs are known to be the same; compute the ordering here
06070         // as if the signs are both positive, then invert for negatives
06071         if (!decNumberIsNaN(lhs)) result=-1;
06072          else if (!decNumberIsNaN(rhs)) result=+1;
06073          // here if both NaNs
06074          else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1;
06075          else if (decNumberIsQNaN(lhs) && decNumberIsSNaN(rhs)) result=+1;
06076          else { // both NaN or both sNaN
06077           // now it just depends on the payload
06078           result=decUnitCompare(lhs->lsu, D2U(lhs->digits),
06079                                 rhs->lsu, D2U(rhs->digits), 0);
06080           // [Error not possible, as these are 'aligned']
06081           } // both same NaNs
06082         if (decNumberIsNegative(lhs)) result=-result;
06083         break;
06084         } // total order
06085
06086        else if (merged & DECSNAN);           // sNaN -> qNaN
06087        else { // here if MIN or MAX and one or two quiet NaNs
06088         // min or max -- 754 rules ignore single NaN
06089         if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
06090           // just one NaN; force choice to be the non-NaN operand
06091           op=COMPMAX;
06092           if (lhs->bits & DECNAN) result=-1; // pick rhs
06093                              else result=+1; // pick lhs
06094           break;
06095           }
06096         } // max or min
06097       op=COMPNAN;                            // use special path
06098       decNaNs(res, lhs, rhs, set, status);   // propagate NaN
06099       break;
06100       }
06101     // have numbers
06102     if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1);
06103      else result=decCompare(lhs, rhs, 0);    // sign matters
06104     } while(0);                              // end protected
06105
06106   if (result==BADINT) *status|=DEC_Insufficient_storage; // rare
06107    else {
06108     if (op==COMPARE || op==COMPSIG ||op==COMPTOTAL) { // returning signum
06109       if (op==COMPTOTAL && result==0) {
06110         // operands are numerically equal or same NaN (and same sign,
06111         // tested first); if identical, leave result 0
06112         if (lhs->exponent!=rhs->exponent) {
06113           if (lhs->exponent<rhs->exponent) result=-1;
06114            else result=+1;
06115           if (decNumberIsNegative(lhs)) result=-result;
06116           } // lexp!=rexp
06117         } // total-order by exponent
06118       decNumberZero(res);               // [always a valid result]
06119       if (result!=0) {                  // must be -1 or +1
06120         *res->lsu=1;
06121         if (result<0) res->bits=DECNEG;
06122         }
06123       }
06124      else if (op==COMPNAN);             // special, drop through
06125      else {                             // MAX or MIN, non-NaN result
06126       Int residue=0;                    // rounding accumulator
06127       // choose the operand for the result
06128       const decNumber *choice;
06129       if (result==0) { // operands are numerically equal
06130         // choose according to sign then exponent (see 754)
06131         uByte slhs=(lhs->bits & DECNEG);
06132         uByte srhs=(rhs->bits & DECNEG);
06133         #if DECSUBSET
06134         if (!set->extended) {           // subset: force left-hand
06135           op=COMPMAX;
06136           result=+1;
06137           }
06138         else
06139         #endif
06140         if (slhs!=srhs) {          // signs differ
06141           if (slhs) result=-1;     // rhs is max
06142                else result=+1;     // lhs is max
06143           }
06144          else if (slhs && srhs) {  // both negative
06145           if (lhs->exponent<rhs->exponent) result=+1;
06146                                       else result=-1;
06147           // [if equal, use lhs, technically identical]
06148           }
06149          else {                    // both positive
06150           if (lhs->exponent>rhs->exponent) result=+1;
06151                                       else result=-1;
06152           // [ditto]
06153           }
06154         } // numerically equal
06155       // here result will be non-0; reverse if looking for MIN
06156       if (op==COMPMIN || op==COMPMINMAG) result=-result;
06157       choice=(result>0 ? lhs : rhs);    // choose
06158       // copy chosen to result, rounding if need be
06159       decCopyFit(res, choice, set, &residue, status);
06160       decFinish(res, set, &residue, status);
06161       }
06162     }
06163   #if DECSUBSET
06164   if (allocrhs!=NULL) free(allocrhs);   // free any storage used
06165   if (alloclhs!=NULL) free(alloclhs);   // ..
06166   #endif
06167   return res;
06168   } // decCompareOp
06169
06170 /* ------------------------------------------------------------------ */
06171 /* decCompare -- compare two decNumbers by numerical value            */
06172 /*                                                                    */
06173 /*  This routine compares A ? B without altering them.                */
06174 /*                                                                    */
06175 /*  Arg1 is A, a decNumber which is not a NaN                         */
06176 /*  Arg2 is B, a decNumber which is not a NaN                         */
06177 /*  Arg3 is 1 for a sign-independent compare, 0 otherwise             */
06178 /*                                                                    */
06179 /*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
06180 /*  (the only possible failure is an allocation error)                */
06181 /* ------------------------------------------------------------------ */
06182 static Int decCompare(const decNumber *lhs, const decNumber *rhs,
06183                       Flag abs) {
06184   Int   result;                    // result value
06185   Int   sigr;                      // rhs signum
06186   Int   compare;                   // work
06187
06188   result=1;                                  // assume signum(lhs)
06189   if (ISZERO(lhs)) result=0;
06190   if (abs) {
06191     if (ISZERO(rhs)) return result;          // LHS wins or both 0
06192     // RHS is non-zero
06193     if (result==0) return -1;                // LHS is 0; RHS wins
06194     // [here, both non-zero, result=1]
06195     }
06196    else {                                    // signs matter
06197     if (result && decNumberIsNegative(lhs)) result=-1;
06198     sigr=1;                                  // compute signum(rhs)
06199     if (ISZERO(rhs)) sigr=0;
06200      else if (decNumberIsNegative(rhs)) sigr=-1;
06201     if (result > sigr) return +1;            // L > R, return 1
06202     if (result < sigr) return -1;            // L < R, return -1
06203     if (result==0) return 0;                   // both 0
06204     }
06205
06206   // signums are the same; both are non-zero
06207   if ((lhs->bits | rhs->bits) & DECINF) {    // one or more infinities
06208     if (decNumberIsInfinite(rhs)) {
06209       if (decNumberIsInfinite(lhs)) result=0;// both infinite
06210        else result=-result;                  // only rhs infinite
06211       }
06212     return result;
06213     }
06214   // must compare the coefficients, allowing for exponents
06215   if (lhs->exponent>rhs->exponent) {         // LHS exponent larger
06216     // swap sides, and sign
06217     const decNumber *temp=lhs;
06218     lhs=rhs;
06219     rhs=temp;
06220     result=-result;
06221     }
06222   compare=decUnitCompare(lhs->lsu, D2U(lhs->digits),
06223                          rhs->lsu, D2U(rhs->digits),
06224                          rhs->exponent-lhs->exponent);
06225   if (compare!=BADINT) compare*=result;      // comparison succeeded
06226   return compare;
06227   } // decCompare
06228
06229 /* ------------------------------------------------------------------ */
06230 /* decUnitCompare -- compare two >=0 integers in Unit arrays          */
06231 /*                                                                    */
06232 /*  This routine compares A ? B*10**E where A and B are unit arrays   */
06233 /*  A is a plain integer                                              */
06234 /*  B has an exponent of E (which must be non-negative)               */
06235 /*                                                                    */
06236 /*  Arg1 is A first Unit (lsu)                                        */
06237 /*  Arg2 is A length in Units                                         */
06238 /*  Arg3 is B first Unit (lsu)                                        */
06239 /*  Arg4 is B length in Units                                         */
06240 /*  Arg5 is E (0 if the units are aligned)                            */
06241 /*                                                                    */
06242 /*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
06243 /*  (the only possible failure is an allocation error, which can      */
06244 /*  only occur if E!=0)                                               */
06245 /* ------------------------------------------------------------------ */
06246 static Int decUnitCompare(const Unit *a, Int alength,
06247                           const Unit *b, Int blength, Int exp) {
06248   Unit  *acc;                      // accumulator for result
06249   Unit  accbuff[SD2U(DECBUFFER*2+1)]; // local buffer
06250   Unit  *allocacc=NULL;            // -> allocated acc buffer, iff allocated
06251   Int   accunits, need;            // units in use or needed for acc
06252   const Unit *l, *r, *u;           // work
06253   Int   expunits, exprem, result;  // ..
06254
06255   if (exp==0) {                    // aligned; fastpath
06256     if (alength>blength) return 1;
06257     if (alength<blength) return -1;
06258     // same number of units in both -- need unit-by-unit compare
06259     l=a+alength-1;
06260     r=b+alength-1;
06261     for (;l>=a; l--, r--) {
06262       if (*l>*r) return 1;
06263       if (*l<*r) return -1;
06264       }
06265     return 0;                      // all units match
06266     } // aligned
06267
06268   // Unaligned.  If one is >1 unit longer than the other, padded
06269   // approximately, then can return easily
06270   if (alength>blength+(Int)D2U(exp)) return 1;
06271   if (alength+1<blength+(Int)D2U(exp)) return -1;
06272
06273   // Need to do a real subtract.  For this, a result buffer is needed
06274   // even though only the sign is of interest.  Its length needs
06275   // to be the larger of alength and padded blength, +2
06276   need=blength+D2U(exp);                // maximum real length of B
06277   if (need<alength) need=alength;
06278   need+=2;
06279   acc=accbuff;                          // assume use local buffer
06280   if (need*sizeof(Unit)>sizeof(accbuff)) {
06281     allocacc=(Unit *)malloc(need*sizeof(Unit));
06282     if (allocacc==NULL) return BADINT;  // hopeless -- abandon
06283     acc=allocacc;
06284     }
06285   // Calculate units and remainder from exponent.
06286   expunits=exp/DECDPUN;
06287   exprem=exp%DECDPUN;
06288   // subtract [A+B*(-m)]
06289   accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,
06290                          -(Int)powers[exprem]);
06291   // [UnitAddSub result may have leading zeros, even on zero]
06292   if (accunits<0) result=-1;            // negative result
06293    else {                               // non-negative result
06294     // check units of the result before freeing any storage
06295     for (u=acc; u<acc+accunits-1 && *u==0;) u++;
06296     result=(*u==0 ? 0 : +1);
06297     }
06298   // clean up and return the result
06299   if (allocacc!=NULL) free(allocacc);   // drop any storage used
06300   return result;
06301   } // decUnitCompare
06302
06303 /* ------------------------------------------------------------------ */
06304 /* decUnitAddSub -- add or subtract two >=0 integers in Unit arrays   */
06305 /*                                                                    */
06306 /*  This routine performs the calculation:                            */
06307 /*                                                                    */
06308 /*  C=A+(B*M)                                                         */
06309 /*                                                                    */
06310 /*  Where M is in the range -DECDPUNMAX through +DECDPUNMAX.          */
06311 /*                                                                    */
06312 /*  A may be shorter or longer than B.                                */
06313 /*                                                                    */
06314 /*  Leading zeros are not removed after a calculation.  The result is */
06315 /*  either the same length as the longer of A and B (adding any       */
06316 /*  shift), or one Unit longer than that (if a Unit carry occurred).  */
06317 /*                                                                    */
06318 /*  A and B content are not altered unless C is also A or B.          */
06319 /*  C may be the same array as A or B, but only if no zero padding is */
06320 /*  requested (that is, C may be B only if bshift==0).                */
06321 /*  C is filled from the lsu; only those units necessary to complete  */
06322 /*  the calculation are referenced.                                   */
06323 /*                                                                    */
06324 /*  Arg1 is A first Unit (lsu)                                        */
06325 /*  Arg2 is A length in Units                                         */
06326 /*  Arg3 is B first Unit (lsu)                                        */
06327 /*  Arg4 is B length in Units                                         */
06328 /*  Arg5 is B shift in Units  (>=0; pads with 0 units if positive)    */
06329 /*  Arg6 is C first Unit (lsu)                                        */
06330 /*  Arg7 is M, the multiplier                                         */
06331 /*                                                                    */
06332 /*  returns the count of Units written to C, which will be non-zero   */
06333 /*  and negated if the result is negative.  That is, the sign of the  */
06334 /*  returned Int is the sign of the result (positive for zero) and    */
06335 /*  the absolute value of the Int is the count of Units.              */
06336 /*                                                                    */
06337 /*  It is the caller's responsibility to make sure that C size is     */
06338 /*  safe, allowing space if necessary for a one-Unit carry.           */
06339 /*                                                                    */
06340 /*  This routine is severely performance-critical; *any* change here  */
06341 /*  must be measured (timed) to assure no performance degradation.    */
06342 /*  In particular, trickery here tends to be counter-productive, as   */
06343 /*  increased complexity of code hurts register optimizations on      */
06344 /*  register-poor architectures.  Avoiding divisions is nearly        */
06345 /*  always a Good Idea, however.                                      */
06346 /*                                                                    */
06347 /* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark  */
06348 /* (IBM Warwick, UK) for some of the ideas used in this routine.      */
06349 /* ------------------------------------------------------------------ */
06350 static Int decUnitAddSub(const Unit *a, Int alength,
06351                          const Unit *b, Int blength, Int bshift,
06352                          Unit *c, Int m) {
06353   const Unit *alsu=a;              // A lsu [need to remember it]
06354   Unit *clsu=c;                    // C ditto
06355   Unit *minC;                      // low water mark for C
06356   Unit *maxC;                      // high water mark for C
06357   eInt carry=0;                    // carry integer (could be Long)
06358   Int  add;                        // work
06359   #if DECDPUN<=4                   // myriadal, millenary, etc.
06360   Int  est;                        // estimated quotient
06361   #endif
06362
06363   #if DECTRACE
06364   if (alength<1 || blength<1)
06365     printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m);
06366   #endif
06367
06368   maxC=c+alength;                  // A is usually the longer
06369   minC=c+blength;                  // .. and B the shorter
06370   if (bshift!=0) {                 // B is shifted; low As copy across
06371     minC+=bshift;
06372     // if in place [common], skip copy unless there's a gap [rare]
06373     if (a==c && bshift<=alength) {
06374       c+=bshift;
06375       a+=bshift;
06376       }
06377      else for (; c<clsu+bshift; a++, c++) {  // copy needed
06378       if (a<alsu+alength) *c=*a;
06379        else *c=0;
06380       }
06381     }
06382   if (minC>maxC) { // swap
06383     Unit *hold=minC;
06384     minC=maxC;
06385     maxC=hold;
06386     }
06387
06388   // For speed, do the addition as two loops; the first where both A
06389   // and B contribute, and the second (if necessary) where only one or
06390   // other of the numbers contribute.
06391   // Carry handling is the same (i.e., duplicated) in each case.
06392   for (; c<minC; c++) {
06393     carry+=*a;
06394     a++;
06395     carry+=((eInt)*b)*m;                // [special-casing m=1/-1
06396     b++;                                // here is not a win]
06397     // here carry is new Unit of digits; it could be +ve or -ve
06398     if ((ueInt)carry<=DECDPUNMAX) {     // fastpath 0-DECDPUNMAX
06399       *c=(Unit)carry;
06400       carry=0;
06401       continue;
06402       }
06403     #if DECDPUN==4                           // use divide-by-multiply
06404       if (carry>=0) {
06405         est=(((ueInt)carry>>11)*53687)>>18;
06406         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06407         carry=est;                           // likely quotient [89%]
06408         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06409         carry++;
06410         *c-=DECDPUNMAX+1;
06411         continue;
06412         }
06413       // negative case
06414       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06415       est=(((ueInt)carry>>11)*53687)>>18;
06416       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06417       carry=est-(DECDPUNMAX+1);              // correctly negative
06418       if (*c<DECDPUNMAX+1) continue;         // was OK
06419       carry++;
06420       *c-=DECDPUNMAX+1;
06421     #elif DECDPUN==3
06422       if (carry>=0) {
06423         est=(((ueInt)carry>>3)*16777)>>21;
06424         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06425         carry=est;                           // likely quotient [99%]
06426         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06427         carry++;
06428         *c-=DECDPUNMAX+1;
06429         continue;
06430         }
06431       // negative case
06432       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06433       est=(((ueInt)carry>>3)*16777)>>21;
06434       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06435       carry=est-(DECDPUNMAX+1);              // correctly negative
06436       if (*c<DECDPUNMAX+1) continue;         // was OK
06437       carry++;
06438       *c-=DECDPUNMAX+1;
06439     #elif DECDPUN<=2
06440       // Can use QUOT10 as carry <= 4 digits
06441       if (carry>=0) {
06442         est=QUOT10(carry, DECDPUN);
06443         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06444         carry=est;                           // quotient
06445         continue;
06446         }
06447       // negative case
06448       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06449       est=QUOT10(carry, DECDPUN);
06450       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06451       carry=est-(DECDPUNMAX+1);              // correctly negative
06452     #else
06453       // remainder operator is undefined if negative, so must test
06454       if ((ueInt)carry<(DECDPUNMAX+1)*2) {   // fastpath carry +1
06455         *c=(Unit)(carry-(DECDPUNMAX+1));     // [helps additions]
06456         carry=1;
06457         continue;
06458         }
06459       if (carry>=0) {
06460         *c=(Unit)(carry%(DECDPUNMAX+1));
06461         carry=carry/(DECDPUNMAX+1);
06462         continue;
06463         }
06464       // negative case
06465       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06466       *c=(Unit)(carry%(DECDPUNMAX+1));
06467       carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
06468     #endif
06469     } // c
06470
06471   // now may have one or other to complete
06472   // [pretest to avoid loop setup/shutdown]
06473   if (c<maxC) for (; c<maxC; c++) {
06474     if (a<alsu+alength) {               // still in A
06475       carry+=*a;
06476       a++;
06477       }
06478      else {                             // inside B
06479       carry+=((eInt)*b)*m;
06480       b++;
06481       }
06482     // here carry is new Unit of digits; it could be +ve or -ve and
06483     // magnitude up to DECDPUNMAX squared
06484     if ((ueInt)carry<=DECDPUNMAX) {     // fastpath 0-DECDPUNMAX
06485       *c=(Unit)carry;
06486       carry=0;
06487       continue;
06488       }
06489     // result for this unit is negative or >DECDPUNMAX
06490     #if DECDPUN==4                           // use divide-by-multiply
06491       if (carry>=0) {
06492         est=(((ueInt)carry>>11)*53687)>>18;
06493         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06494         carry=est;                           // likely quotient [79.7%]
06495         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06496         carry++;
06497         *c-=DECDPUNMAX+1;
06498         continue;
06499         }
06500       // negative case
06501       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06502       est=(((ueInt)carry>>11)*53687)>>18;
06503       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06504       carry=est-(DECDPUNMAX+1);              // correctly negative
06505       if (*c<DECDPUNMAX+1) continue;         // was OK
06506       carry++;
06507       *c-=DECDPUNMAX+1;
06508     #elif DECDPUN==3
06509       if (carry>=0) {
06510         est=(((ueInt)carry>>3)*16777)>>21;
06511         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06512         carry=est;                           // likely quotient [99%]
06513         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06514         carry++;
06515         *c-=DECDPUNMAX+1;
06516         continue;
06517         }
06518       // negative case
06519       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06520       est=(((ueInt)carry>>3)*16777)>>21;
06521       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06522       carry=est-(DECDPUNMAX+1);              // correctly negative
06523       if (*c<DECDPUNMAX+1) continue;         // was OK
06524       carry++;
06525       *c-=DECDPUNMAX+1;
06526     #elif DECDPUN<=2
06527       if (carry>=0) {
06528         est=QUOT10(carry, DECDPUN);
06529         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06530         carry=est;                           // quotient
06531         continue;
06532         }
06533       // negative case
06534       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06535       est=QUOT10(carry, DECDPUN);
06536       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06537       carry=est-(DECDPUNMAX+1);              // correctly negative
06538     #else
06539       if ((ueInt)carry<(DECDPUNMAX+1)*2){    // fastpath carry 1
06540         *c=(Unit)(carry-(DECDPUNMAX+1));
06541         carry=1;
06542         continue;
06543         }
06544       // remainder operator is undefined if negative, so must test
06545       if (carry>=0) {
06546         *c=(Unit)(carry%(DECDPUNMAX+1));
06547         carry=carry/(DECDPUNMAX+1);
06548         continue;
06549         }
06550       // negative case
06551       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06552       *c=(Unit)(carry%(DECDPUNMAX+1));
06553       carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
06554     #endif
06555     } // c
06556
06557   // OK, all A and B processed; might still have carry or borrow
06558   // return number of Units in the result, negated if a borrow
06559   if (carry==0) return c-clsu;     // no carry, so no more to do
06560   if (carry>0) {                   // positive carry
06561     *c=(Unit)carry;                // place as new unit
06562     c++;                           // ..
06563     return c-clsu;
06564     }
06565   // -ve carry: it's a borrow; complement needed
06566   add=1;                           // temporary carry...
06567   for (c=clsu; c<maxC; c++) {
06568     add=DECDPUNMAX+add-*c;
06569     if (add<=DECDPUNMAX) {
06570       *c=(Unit)add;
06571       add=0;
06572       }
06573      else {
06574       *c=0;
06575       add=1;
06576       }
06577     }
06578   // add an extra unit iff it would be non-zero
06579   #if DECTRACE
06580     printf("UAS borrow: add %ld, carry %ld\n", add, carry);
06581   #endif
06582   if ((add-carry-1)!=0) {
06583     *c=(Unit)(add-carry-1);
06584     c++;                      // interesting, include it
06585     }
06586   return clsu-c;              // -ve result indicates borrowed
06587   } // decUnitAddSub
06588
06589 /* ------------------------------------------------------------------ */
06590 /* decTrim -- trim trailing zeros or normalize                        */
06591 /*                                                                    */
06592 /*   dn is the number to trim or normalize                            */
06593 /*   set is the context to use to check for clamp                     */
06594 /*   all is 1 to remove all trailing zeros, 0 for just fraction ones  */
06595 /*   noclamp is 1 to unconditional (unclamped) trim                   */
06596 /*   dropped returns the number of discarded trailing zeros           */
06597 /*   returns dn                                                       */
06598 /*                                                                    */
06599 /* If clamp is set in the context then the number of zeros trimmed    */
06600 /* may be limited if the exponent is high.                            */
06601 /* All fields are updated as required.  This is a utility operation,  */
06602 /* so special values are unchanged and no error is possible.          */
06603 /* ------------------------------------------------------------------ */
06604 static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
06605                            Flag noclamp, Int *dropped) {
06606   Int   d, exp;                    // work
06607   uInt  cut;                       // ..
06608   Unit  *up;                       // -> current Unit
06609
06610   #if DECCHECK
06611   if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
06612   #endif
06613
06614   *dropped=0;                           // assume no zeros dropped
06615   if ((dn->bits & DECSPECIAL)           // fast exit if special ..
06616     || (*dn->lsu & 0x01)) return dn;    // .. or odd
06617   if (ISZERO(dn)) {                     // .. or 0
06618     dn->exponent=0;                     // (sign is preserved)
06619     return dn;
06620     }
06621
06622   // have a finite number which is even
06623   exp=dn->exponent;
06624   cut=1;                           // digit (1-DECDPUN) in Unit
06625   up=dn->lsu;                      // -> current Unit
06626   for (d=0; d<dn->digits-1; d++) { // [don't strip the final digit]
06627     // slice by powers
06628     #if DECDPUN<=4
06629       uInt quot=QUOT10(*up, cut);
06630       if ((*up-quot*powers[cut])!=0) break;  // found non-0 digit
06631     #else
06632       if (*up%powers[cut]!=0) break;         // found non-0 digit
06633     #endif
06634     // have a trailing 0
06635     if (!all) {                    // trimming
06636       // [if exp>0 then all trailing 0s are significant for trim]
06637       if (exp<=0) {                // if digit might be significant
06638         if (exp==0) break;         // then quit
06639         exp++;                     // next digit might be significant
06640         }
06641       }
06642     cut++;                         // next power
06643     if (cut>DECDPUN) {             // need new Unit
06644       up++;
06645       cut=1;
06646       }
06647     } // d
06648   if (d==0) return dn;             // none to drop
06649
06650   // may need to limit drop if clamping
06651   if (set->clamp && !noclamp) {
06652     Int maxd=set->emax-set->digits+1-dn->exponent;
06653     if (maxd<=0) return dn;        // nothing possible
06654     if (d>maxd) d=maxd;
06655     }
06656
06657   // effect the drop
06658   decShiftToLeast(dn->lsu, D2U(dn->digits), d);
06659   dn->exponent+=d;                 // maintain numerical value
06660   dn->digits-=d;                   // new length
06661   *dropped=d;                      // report the count
06662   return dn;
06663   } // decTrim
06664
06665 /* ------------------------------------------------------------------ */
06666 /* decReverse -- reverse a Unit array in place                        */
06667 /*                                                                    */
06668 /*   ulo    is the start of the array                                 */
06669 /*   uhi    is the end of the array (highest Unit to include)         */
06670 /*                                                                    */
06671 /* The units ulo through uhi are reversed in place (if the number     */
06672 /* of units is odd, the middle one is untouched).  Note that the      */
06673 /* digit(s) in each unit are unaffected.                              */
06674 /* ------------------------------------------------------------------ */
06675 static void decReverse(Unit *ulo, Unit *uhi) {
06676   Unit temp;
06677   for (; ulo<uhi; ulo++, uhi--) {
06678     temp=*ulo;
06679     *ulo=*uhi;
06680     *uhi=temp;
06681     }
06682   return;
06683   } // decReverse
06684
06685 /* ------------------------------------------------------------------ */
06686 /* decShiftToMost -- shift digits in array towards most significant   */
06687 /*                                                                    */
06688 /*   uar    is the array                                              */
06689 /*   digits is the count of digits in use in the array                */
06690 /*   shift  is the number of zeros to pad with (least significant);   */
06691 /*     it must be zero or positive                                    */
06692 /*                                                                    */
06693 /*   returns the new length of the integer in the array, in digits    */
06694 /*                                                                    */
06695 /* No overflow is permitted (that is, the uar array must be known to  */
06696 /* be large enough to hold the result, after shifting).               */
06697 /* ------------------------------------------------------------------ */
06698 static Int decShiftToMost(Unit *uar, Int digits, Int shift) {
06699   Unit  *target, *source, *first;  // work
06700   Int   cut;                       // odd 0's to add
06701   uInt  next;                      // work
06702
06703   if (shift==0) return digits;     // [fastpath] nothing to do
06704   if ((digits+shift)<=DECDPUN) {   // [fastpath] single-unit case
06705     *uar=(Unit)(*uar*powers[shift]);
06706     return digits+shift;
06707     }
06708
06709   next=0;                          // all paths
06710   source=uar+D2U(digits)-1;        // where msu comes from
06711   target=source+D2U(shift);        // where upper part of first cut goes
06712   cut=DECDPUN-MSUDIGITS(shift);    // where to slice
06713   if (cut==0) {                    // unit-boundary case
06714     for (; source>=uar; source--, target--) *target=*source;
06715     }
06716    else {
06717     first=uar+D2U(digits+shift)-1; // where msu of source will end up
06718     for (; source>=uar; source--, target--) {
06719       // split the source Unit and accumulate remainder for next
06720       #if DECDPUN<=4
06721         uInt quot=QUOT10(*source, cut);
06722         uInt rem=*source-quot*powers[cut];
06723         next+=quot;
06724       #else
06725         uInt rem=*source%powers[cut];
06726         next+=*source/powers[cut];
06727       #endif
06728       if (target<=first) *target=(Unit)next;   // write to target iff valid
06729       next=rem*powers[DECDPUN-cut];            // save remainder for next Unit
06730       }
06731     } // shift-move
06732
06733   // propagate any partial unit to one below and clear the rest
06734   for (; target>=uar; target--) {
06735     *target=(Unit)next;
06736     next=0;
06737     }
06738   return digits+shift;
06739   } // decShiftToMost
06740
06741 /* ------------------------------------------------------------------ */
06742 /* decShiftToLeast -- shift digits in array towards least significant */
06743 /*                                                                    */
06744 /*   uar   is the array                                               */
06745 /*   units is length of the array, in units                           */
06746 /*   shift is the number of digits to remove from the lsu end; it     */
06747 /*     must be zero or positive and <= than units*DECDPUN.            */
06748 /*                                                                    */
06749 /*   returns the new length of the integer in the array, in units     */
06750 /*                                                                    */
06751 /* Removed digits are discarded (lost).  Units not required to hold   */
06752 /* the final result are unchanged.                                    */
06753 /* ------------------------------------------------------------------ */
06754 static Int decShiftToLeast(Unit *uar, Int units, Int shift) {
06755   Unit  *target, *up;              // work
06756   Int   cut, count;                // work
06757   Int   quot, rem;                 // for division
06758
06759   if (shift==0) return units;      // [fastpath] nothing to do
06760   if (shift==units*DECDPUN) {      // [fastpath] little to do
06761     *uar=0;                        // all digits cleared gives zero
06762     return 1;                      // leaves just the one
06763     }
06764
06765   target=uar;                      // both paths
06766   cut=MSUDIGITS(shift);
06767   if (cut==DECDPUN) {              // unit-boundary case; easy
06768     up=uar+D2U(shift);
06769     for (; up<uar+units; target++, up++) *target=*up;
06770     return target-uar;
06771     }
06772
06773   // messier
06774   up=uar+D2U(shift-cut);           // source; correct to whole Units
06775   count=units*DECDPUN-shift;       // the maximum new length
06776   #if DECDPUN<=4
06777     quot=QUOT10(*up, cut);
06778   #else
06779     quot=*up/powers[cut];
06780   #endif
06781   for (; ; target++) {
06782     *target=(Unit)quot;
06783     count-=(DECDPUN-cut);
06784     if (count<=0) break;
06785     up++;
06786     quot=*up;
06787     #if DECDPUN<=4
06788       quot=QUOT10(quot, cut);
06789       rem=*up-quot*powers[cut];
06790     #else
06791       rem=quot%powers[cut];
06792       quot=quot/powers[cut];
06793     #endif
06794     *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
06795     count-=cut;
06796     if (count<=0) break;
06797     }
06798   return target-uar+1;
06799   } // decShiftToLeast
06800
06801 #if DECSUBSET
06802 /* ------------------------------------------------------------------ */
06803 /* decRoundOperand -- round an operand  [used for subset only]        */
06804 /*                                                                    */
06805 /*   dn is the number to round (dn->digits is > set->digits)          */
06806 /*   set is the relevant context                                      */
06807 /*   status is the status accumulator                                 */
06808 /*                                                                    */
06809 /*   returns an allocated decNumber with the rounded result.          */
06810 /*                                                                    */
06811 /* lostDigits and other status may be set by this.                    */
06812 /*                                                                    */
06813 /* Since the input is an operand, it must not be modified.            */
06814 /* Instead, return an allocated decNumber, rounded as required.       */
06815 /* It is the caller's responsibility to free the allocated storage.   */
06816 /*                                                                    */
06817 /* If no storage is available then the result cannot be used, so NULL */
06818 /* is returned.                                                       */
06819 /* ------------------------------------------------------------------ */
06820 static decNumber *decRoundOperand(const decNumber *dn, decContext *set,
06821                                   uInt *status) {
06822   decNumber *res;                       // result structure
06823   uInt newstatus=0;                     // status from round
06824   Int  residue=0;                       // rounding accumulator
06825
06826   // Allocate storage for the returned decNumber, big enough for the
06827   // length specified by the context
06828   res=(decNumber *)malloc(sizeof(decNumber)
06829                           +(D2U(set->digits)-1)*sizeof(Unit));
06830   if (res==NULL) {
06831     *status|=DEC_Insufficient_storage;
06832     return NULL;
06833     }
06834   decCopyFit(res, dn, set, &residue, &newstatus);
06835   decApplyRound(res, set, residue, &newstatus);
06836
06837   // If that set Inexact then "lost digits" is raised...
06838   if (newstatus & DEC_Inexact) newstatus|=DEC_Lost_digits;
06839   *status|=newstatus;
06840   return res;
06841   } // decRoundOperand
06842 #endif
06843
06844 /* ------------------------------------------------------------------ */
06845 /* decCopyFit -- copy a number, truncating the coefficient if needed  */
06846 /*                                                                    */
06847 /*   dest is the target decNumber                                     */
06848 /*   src  is the source decNumber                                     */
06849 /*   set is the context [used for length (digits) and rounding mode]  */
06850 /*   residue is the residue accumulator                               */
06851 /*   status contains the current status to be updated                 */
06852 /*                                                                    */
06853 /* (dest==src is allowed and will be a no-op if fits)                 */
06854 /* All fields are updated as required.                                */
06855 /* ------------------------------------------------------------------ */
06856 static void decCopyFit(decNumber *dest, const decNumber *src,
06857                        decContext *set, Int *residue, uInt *status) {
06858   dest->bits=src->bits;
06859   dest->exponent=src->exponent;
06860   decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
06861   } // decCopyFit
06862
06863 /* ------------------------------------------------------------------ */
06864 /* decSetCoeff -- set the coefficient of a number                     */
06865 /*                                                                    */
06866 /*   dn    is the number whose coefficient array is to be set.        */
06867 /*         It must have space for set->digits digits                  */
06868 /*   set   is the context [for size]                                  */
06869 /*   lsu   -> lsu of the source coefficient [may be dn->lsu]          */
06870 /*   len   is digits in the source coefficient [may be dn->digits]    */
06871 /*   residue is the residue accumulator.  This has values as in       */
06872 /*         decApplyRound, and will be unchanged unless the            */
06873 /*         target size is less than len.  In this case, the           */
06874 /*         coefficient is truncated and the residue is updated to     */
06875 /*         reflect the previous residue and the dropped digits.       */
06876 /*   status is the status accumulator, as usual                       */
06877 /*                                                                    */
06878 /* The coefficient may already be in the number, or it can be an      */
06879 /* external intermediate array.  If it is in the number, lsu must ==  */
06880 /* dn->lsu and len must == dn->digits.                                */
06881 /*                                                                    */
06882 /* Note that the coefficient length (len) may be < set->digits, and   */
06883 /* in this case this merely copies the coefficient (or is a no-op     */
06884 /* if dn->lsu==lsu).                                                  */
06885 /*                                                                    */
06886 /* Note also that (only internally, from decQuantizeOp and            */
06887 /* decSetSubnormal) the value of set->digits may be less than one,    */
06888 /* indicating a round to left.  This routine handles that case        */
06889 /* correctly; caller ensures space.                                   */
06890 /*                                                                    */
06891 /* dn->digits, dn->lsu (and as required), and dn->exponent are        */
06892 /* updated as necessary.   dn->bits (sign) is unchanged.              */
06893 /*                                                                    */
06894 /* DEC_Rounded status is set if any digits are discarded.             */
06895 /* DEC_Inexact status is set if any non-zero digits are discarded, or */
06896 /*                       incoming residue was non-0 (implies rounded) */
06897 /* ------------------------------------------------------------------ */
06898 // mapping array: maps 0-9 to canonical residues, so that a residue
06899 // can be adjusted in the range [-1, +1] and achieve correct rounding
06900 //                             0  1  2  3  4  5  6  7  8  9
06901 static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7};
06902 static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu,
06903                         Int len, Int *residue, uInt *status) {
06904   Int   discard;              // number of digits to discard
06905   uInt  cut;                  // cut point in Unit
06906   const Unit *up;             // work
06907   Unit  *target;              // ..
06908   Int   count;                // ..
06909   #if DECDPUN<=4
06910   uInt  temp;                 // ..
06911   #endif
06912
06913   discard=len-set->digits;    // digits to discard
06914   if (discard<=0) {           // no digits are being discarded
06915     if (dn->lsu!=lsu) {       // copy needed
06916       // copy the coefficient array to the result number; no shift needed
06917       count=len;              // avoids D2U
06918       up=lsu;
06919       for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
06920         *target=*up;
06921       dn->digits=len;         // set the new length
06922       }
06923     // dn->exponent and residue are unchanged, record any inexactitude
06924     if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded);
06925     return;
06926     }
06927
06928   // some digits must be discarded ...
06929   dn->exponent+=discard;      // maintain numerical value
06930   *status|=DEC_Rounded;       // accumulate Rounded status
06931   if (*residue>1) *residue=1; // previous residue now to right, so reduce
06932
06933   if (discard>len) {          // everything, +1, is being discarded
06934     // guard digit is 0
06935     // residue is all the number [NB could be all 0s]
06936     if (*residue<=0) {        // not already positive
06937       count=len;              // avoids D2U
06938       for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { // found non-0
06939         *residue=1;
06940         break;                // no need to check any others
06941         }
06942       }
06943     if (*residue!=0) *status|=DEC_Inexact; // record inexactitude
06944     *dn->lsu=0;               // coefficient will now be 0
06945     dn->digits=1;             // ..
06946     return;
06947     } // total discard
06948
06949   // partial discard [most common case]
06950   // here, at least the first (most significant) discarded digit exists
06951
06952   // spin up the number, noting residue during the spin, until get to
06953   // the Unit with the first discarded digit.  When reach it, extract
06954   // it and remember its position
06955   count=0;
06956   for (up=lsu;; up++) {
06957     count+=DECDPUN;
06958     if (count>=discard) break; // full ones all checked
06959     if (*up!=0) *residue=1;
06960     } // up
06961
06962   // here up -> Unit with first discarded digit
06963   cut=discard-(count-DECDPUN)-1;
06964   if (cut==DECDPUN-1) {       // unit-boundary case (fast)
06965     Unit half=(Unit)powers[DECDPUN]>>1;
06966     // set residue directly
06967     if (*up>=half) {
06968       if (*up>half) *residue=7;
06969       else *residue+=5;       // add sticky bit
06970       }
06971      else { // <half
06972       if (*up!=0) *residue=3; // [else is 0, leave as sticky bit]
06973       }
06974     if (set->digits<=0) {     // special for Quantize/Subnormal :-(
06975       *dn->lsu=0;             // .. result is 0
06976       dn->digits=1;           // ..
06977       }
06978      else {                   // shift to least
06979       count=set->digits;      // now digits to end up with
06980       dn->digits=count;       // set the new length
06981       up++;                   // move to next
06982       // on unit boundary, so shift-down copy loop is simple
06983       for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
06984         *target=*up;
06985       }
06986     } // unit-boundary case
06987
06988    else { // discard digit is in low digit(s), and not top digit
06989     uInt  discard1;                // first discarded digit
06990     uInt  quot, rem;               // for divisions
06991     if (cut==0) quot=*up;          // is at bottom of unit
06992      else /* cut>0 */ {            // it's not at bottom of unit
06993       #if DECDPUN<=4
06994         quot=QUOT10(*up, cut);
06995         rem=*up-quot*powers[cut];
06996       #else
06997         rem=*up%powers[cut];
06998         quot=*up/powers[cut];
06999       #endif
07000       if (rem!=0) *residue=1;
07001       }
07002     // discard digit is now at bottom of quot
07003     #if DECDPUN<=4
07004       temp=(quot*6554)>>16;        // fast /10
07005       // Vowels algorithm here not a win (9 instructions)
07006       discard1=quot-X10(temp);
07007       quot=temp;
07008     #else
07009       discard1=quot%10;
07010       quot=quot/10;
07011     #endif
07012     // here, discard1 is the guard digit, and residue is everything
07013     // else [use mapping array to accumulate residue safely]
07014     *residue+=resmap[discard1];
07015     cut++;                         // update cut
07016     // here: up -> Unit of the array with bottom digit
07017     //       cut is the division point for each Unit
07018     //       quot holds the uncut high-order digits for the current unit
07019     if (set->digits<=0) {          // special for Quantize/Subnormal :-(
07020       *dn->lsu=0;                  // .. result is 0
07021       dn->digits=1;                // ..
07022       }
07023      else {                        // shift to least needed
07024       count=set->digits;           // now digits to end up with
07025       dn->digits=count;            // set the new length
07026       // shift-copy the coefficient array to the result number
07027       for (target=dn->lsu; ; target++) {
07028         *target=(Unit)quot;
07029         count-=(DECDPUN-cut);
07030         if (count<=0) break;
07031         up++;
07032         quot=*up;
07033         #if DECDPUN<=4
07034           quot=QUOT10(quot, cut);
07035           rem=*up-quot*powers[cut];
07036         #else
07037           rem=quot%powers[cut];
07038           quot=quot/powers[cut];
07039         #endif
07040         *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
07041         count-=cut;
07042         if (count<=0) break;
07043         } // shift-copy loop
07044       } // shift to least
07045     } // not unit boundary
07046
07047   if (*residue!=0) *status|=DEC_Inexact; // record inexactitude
07048   return;
07049   } // decSetCoeff
07050
07051 /* ------------------------------------------------------------------ */
07052 /* decApplyRound -- apply pending rounding to a number                */
07053 /*                                                                    */
07054 /*   dn    is the number, with space for set->digits digits           */
07055 /*   set   is the context [for size and rounding mode]                */
07056 /*   residue indicates pending rounding, being any accumulated        */
07057 /*         guard and sticky information.  It may be:                  */
07058 /*         6-9: rounding digit is >5                                  */
07059 /*         5:   rounding digit is exactly half-way                    */
07060 /*         1-4: rounding digit is <5 and >0                           */
07061 /*         0:   the coefficient is exact                              */
07062 /*        -1:   as 1, but the hidden digits are subtractive, that     */
07063 /*              is, of the opposite sign to dn.  In this case the     */
07064 /*              coefficient must be non-0.  This case occurs when     */
07065 /*              subtracting a small number (which can be reduced to   */
07066 /*              a sticky bit); see decAddOp.                          */
07067 /*   status is the status accumulator, as usual                       */
07068 /*                                                                    */
07069 /* This routine applies rounding while keeping the length of the      */
07070 /* coefficient constant.  The exponent and status are unchanged       */
07071 /* except if:                                                         */
07072 /*                                                                    */
07073 /*   -- the coefficient was increased and is all nines (in which      */
07074 /*      case Overflow could occur, and is handled directly here so    */
07075 /*      the caller does not need to re-test for overflow)             */
07076 /*                                                                    */
07077 /*   -- the coefficient was decreased and becomes all nines (in which */
07078 /*      case Underflow could occur, and is also handled directly).    */
07079 /*                                                                    */
07080 /* All fields in dn are updated as required.                          */
07081 /*                                                                    */
07082 /* ------------------------------------------------------------------ */
07083 static void decApplyRound(decNumber *dn, decContext *set, Int residue,
07084                           uInt *status) {
07085   Int  bump;                  // 1 if coefficient needs to be incremented
07086                               // -1 if coefficient needs to be decremented
07087
07088   if (residue==0) return;     // nothing to apply
07089
07090   bump=0;                     // assume a smooth ride
07091
07092   // now decide whether, and how, to round, depending on mode
07093   switch (set->round) {
07094     case DEC_ROUND_05UP: {    // round zero or five up (for reround)
07095       // This is the same as DEC_ROUND_DOWN unless there is a
07096       // positive residue and the lsd of dn is 0 or 5, in which case
07097       // it is bumped; when residue is <0, the number is therefore
07098       // bumped down unless the final digit was 1 or 6 (in which
07099       // case it is bumped down and then up -- a no-op)
07100       Int lsd5=*dn->lsu%5;     // get lsd and quintate
07101       if (residue<0 && lsd5!=1) bump=-1;
07102        else if (residue>0 && lsd5==0) bump=1;
07103       // [bump==1 could be applied directly; use common path for clarity]
07104       break;} // r-05
07105
07106     case DEC_ROUND_DOWN: {
07107       // no change, except if negative residue
07108       if (residue<0) bump=-1;
07109       break;} // r-d
07110
07111     case DEC_ROUND_HALF_DOWN: {
07112       if (residue>5) bump=1;
07113       break;} // r-h-d
07114
07115     case DEC_ROUND_HALF_EVEN: {
07116       if (residue>5) bump=1;            // >0.5 goes up
07117        else if (residue==5) {           // exactly 0.5000...
07118         // 0.5 goes up iff [new] lsd is odd
07119         if (*dn->lsu & 0x01) bump=1;
07120         }
07121       break;} // r-h-e
07122
07123     case DEC_ROUND_HALF_UP: {
07124       if (residue>=5) bump=1;
07125       break;} // r-h-u
07126
07127     case DEC_ROUND_UP: {
07128       if (residue>0) bump=1;
07129       break;} // r-u
07130
07131     case DEC_ROUND_CEILING: {
07132       // same as _UP for positive numbers, and as _DOWN for negatives
07133       // [negative residue cannot occur on 0]
07134       if (decNumberIsNegative(dn)) {
07135         if (residue<0) bump=-1;
07136         }
07137        else {
07138         if (residue>0) bump=1;
07139         }
07140       break;} // r-c
07141
07142     case DEC_ROUND_FLOOR: {
07143       // same as _UP for negative numbers, and as _DOWN for positive
07144       // [negative residue cannot occur on 0]
07145       if (!decNumberIsNegative(dn)) {
07146         if (residue<0) bump=-1;
07147         }
07148        else {
07149         if (residue>0) bump=1;
07150         }
07151       break;} // r-f
07152
07153     default: {      // e.g., DEC_ROUND_MAX
07154       *status|=DEC_Invalid_context;
07155       #if DECTRACE || (DECCHECK && DECVERB)
07156       printf("Unknown rounding mode: %d\n", set->round);
07157       #endif
07158       break;}
07159     } // switch
07160
07161   // now bump the number, up or down, if need be
07162   if (bump==0) return;                       // no action required
07163
07164   // Simply use decUnitAddSub unless bumping up and the number is
07165   // all nines.  In this special case set to 100... explicitly
07166   // and adjust the exponent by one (as otherwise could overflow
07167   // the array)
07168   // Similarly handle all-nines result if bumping down.
07169   if (bump>0) {
07170     Unit *up;                                // work
07171     uInt count=dn->digits;                   // digits to be checked
07172     for (up=dn->lsu; ; up++) {
07173       if (count<=DECDPUN) {
07174         // this is the last Unit (the msu)
07175         if (*up!=powers[count]-1) break;     // not still 9s
07176         // here if it, too, is all nines
07177         *up=(Unit)powers[count-1];           // here 999 -> 100 etc.
07178         for (up=up-1; up>=dn->lsu; up--) *up=0; // others all to 0
07179         dn->exponent++;                      // and bump exponent
07180         // [which, very rarely, could cause Overflow...]
07181         if ((dn->exponent+dn->digits)>set->emax+1) {
07182           decSetOverflow(dn, set, status);
07183           }
07184         return;                              // done
07185         }
07186       // a full unit to check, with more to come
07187       if (*up!=DECDPUNMAX) break;            // not still 9s
07188       count-=DECDPUN;
07189       } // up
07190     } // bump>0
07191    else {                                    // -1
07192     // here checking for a pre-bump of 1000... (leading 1, all
07193     // other digits zero)
07194     Unit *up, *sup;                          // work
07195     uInt count=dn->digits;                   // digits to be checked
07196     for (up=dn->lsu; ; up++) {
07197       if (count<=DECDPUN) {
07198         // this is the last Unit (the msu)
07199         if (*up!=powers[count-1]) break;     // not 100..
07200         // here if have the 1000... case
07201         sup=up;                              // save msu pointer
07202         *up=(Unit)powers[count]-1;           // here 100 in msu -> 999
07203         // others all to all-nines, too
07204         for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1;
07205         dn->exponent--;                      // and bump exponent
07206
07207         // iff the number was at the subnormal boundary (exponent=etiny)
07208         // then the exponent is now out of range, so it will in fact get
07209         // clamped to etiny and the final 9 dropped.
07210         // printf(">> emin=%d exp=%d sdig=%d\n", set->emin,
07211         //        dn->exponent, set->digits);
07212         if (dn->exponent+1==set->emin-set->digits+1) {
07213           if (count==1 && dn->digits==1) *sup=0;  // here 9 -> 0[.9]
07214            else {
07215             *sup=(Unit)powers[count-1]-1;    // here 999.. in msu -> 99..
07216             dn->digits--;
07217             }
07218           dn->exponent++;
07219           *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
07220           }
07221         return;                              // done
07222         }
07223
07224       // a full unit to check, with more to come
07225       if (*up!=0) break;                     // not still 0s
07226       count-=DECDPUN;
07227       } // up
07228
07229     } // bump<0
07230
07231   // Actual bump needed.  Do it.
07232   decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
07233   } // decApplyRound
07234
07235 #if DECSUBSET
07236 /* ------------------------------------------------------------------ */
07237 /* decFinish -- finish processing a number                            */
07238 /*                                                                    */
07239 /*   dn is the number                                                 */
07240 /*   set is the context                                               */
07241 /*   residue is the rounding accumulator (as in decApplyRound)        */
07242 /*   status is the accumulator                                        */
07243 /*                                                                    */
07244 /* This finishes off the current number by:                           */
07245 /*    1. If not extended:                                             */
07246 /*       a. Converting a zero result to clean '0'                     */
07247 /*       b. Reducing positive exponents to 0, if would fit in digits  */
07248 /*    2. Checking for overflow and subnormals (always)                */
07249 /* Note this is just Finalize when no subset arithmetic.              */
07250 /* All fields are updated as required.                                */
07251 /* ------------------------------------------------------------------ */
07252 static void decFinish(decNumber *dn, decContext *set, Int *residue,
07253                       uInt *status) {
07254   if (!set->extended) {
07255     if ISZERO(dn) {                // value is zero
07256       dn->exponent=0;              // clean exponent ..
07257       dn->bits=0;                  // .. and sign
07258       return;                      // no error possible
07259       }
07260     if (dn->exponent>=0) {         // non-negative exponent
07261       // >0; reduce to integer if possible
07262       if (set->digits >= (dn->exponent+dn->digits)) {
07263         dn->digits=decShiftToMost(dn->lsu, dn->digits, dn->exponent);
07264         dn->exponent=0;
07265         }
07266       }
07267     } // !extended
07268
07269   decFinalize(dn, set, residue, status);
07270   } // decFinish
07271 #endif
07272
07273 /* ------------------------------------------------------------------ */
07274 /* decFinalize -- final check, clamp, and round of a number           */
07275 /*                                                                    */
07276 /*   dn is the number                                                 */
07277 /*   set is the context                                               */
07278 /*   residue is the rounding accumulator (as in decApplyRound)        */
07279 /*   status is the status accumulator                                 */
07280 /*                                                                    */
07281 /* This finishes off the current number by checking for subnormal     */
07282 /* results, applying any pending rounding, checking for overflow,     */
07283 /* and applying any clamping.                                         */
07284 /* Underflow and overflow conditions are raised as appropriate.       */
07285 /* All fields are updated as required.                                */
07286 /* ------------------------------------------------------------------ */
07287 static void decFinalize(decNumber *dn, decContext *set, Int *residue,
07288                         uInt *status) {
07289   Int shift;                            // shift needed if clamping
07290   Int tinyexp=set->emin-dn->digits+1;   // precalculate subnormal boundary
07291
07292   // Must be careful, here, when checking the exponent as the
07293   // adjusted exponent could overflow 31 bits [because it may already
07294   // be up to twice the expected].
07295
07296   // First test for subnormal.  This must be done before any final
07297   // round as the result could be rounded to Nmin or 0.
07298   if (dn->exponent<=tinyexp) {          // prefilter
07299     Int comp;
07300     decNumber nmin;
07301     // A very nasty case here is dn == Nmin and residue<0
07302     if (dn->exponent<tinyexp) {
07303       // Go handle subnormals; this will apply round if needed.
07304       decSetSubnormal(dn, set, residue, status);
07305       return;
07306       }
07307     // Equals case: only subnormal if dn=Nmin and negative residue
07308     decNumberZero(&nmin);
07309     nmin.lsu[0]=1;
07310     nmin.exponent=set->emin;
07311     comp=decCompare(dn, &nmin, 1);                // (signless compare)
07312     if (comp==BADINT) {                           // oops
07313       *status|=DEC_Insufficient_storage;          // abandon...
07314       return;
07315       }
07316     if (*residue<0 && comp==0) {                  // neg residue and dn==Nmin
07317       decApplyRound(dn, set, *residue, status);   // might force down
07318       decSetSubnormal(dn, set, residue, status);
07319       return;
07320       }
07321     }
07322
07323   // now apply any pending round (this could raise overflow).
07324   if (*residue!=0) decApplyRound(dn, set, *residue, status);
07325
07326   // Check for overflow [redundant in the 'rare' case] or clamp
07327   if (dn->exponent<=set->emax-set->digits+1) return;   // neither needed
07328
07329
07330   // here when might have an overflow or clamp to do
07331   if (dn->exponent>set->emax-dn->digits+1) {           // too big
07332     decSetOverflow(dn, set, status);
07333     return;
07334     }
07335   // here when the result is normal but in clamp range
07336   if (!set->clamp) return;
07337
07338   // here when need to apply the IEEE exponent clamp (fold-down)
07339   shift=dn->exponent-(set->emax-set->digits+1);
07340
07341   // shift coefficient (if non-zero)
07342   if (!ISZERO(dn)) {
07343     dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
07344     }
07345   dn->exponent-=shift;   // adjust the exponent to match
07346   *status|=DEC_Clamped;  // and record the dirty deed
07347   return;
07348   } // decFinalize
07349
07350 /* ------------------------------------------------------------------ */
07351 /* decSetOverflow -- set number to proper overflow value              */
07352 /*                                                                    */
07353 /*   dn is the number (used for sign [only] and result)               */
07354 /*   set is the context [used for the rounding mode, etc.]            */
07355 /*   status contains the current status to be updated                 */
07356 /*                                                                    */
07357 /* This sets the sign of a number and sets its value to either        */
07358 /* Infinity or the maximum finite value, depending on the sign of     */
07359 /* dn and the rounding mode, following IEEE 754 rules.                */
07360 /* ------------------------------------------------------------------ */
07361 static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) {
07362   Flag needmax=0;                  // result is maximum finite value
07363   uByte sign=dn->bits&DECNEG;      // clean and save sign bit
07364
07365   if (ISZERO(dn)) {                // zero does not overflow magnitude
07366     Int emax=set->emax;                      // limit value
07367     if (set->clamp) emax-=set->digits-1;     // lower if clamping
07368     if (dn->exponent>emax) {                 // clamp required
07369       dn->exponent=emax;
07370       *status|=DEC_Clamped;
07371       }
07372     return;
07373     }
07374
07375   decNumberZero(dn);
07376   switch (set->round) {
07377     case DEC_ROUND_DOWN: {
07378       needmax=1;                   // never Infinity
07379       break;} // r-d
07380     case DEC_ROUND_05UP: {
07381       needmax=1;                   // never Infinity
07382       break;} // r-05
07383     case DEC_ROUND_CEILING: {
07384       if (sign) needmax=1;         // Infinity if non-negative
07385       break;} // r-c
07386     case DEC_ROUND_FLOOR: {
07387       if (!sign) needmax=1;        // Infinity if negative
07388       break;} // r-f
07389     default: break;                // Infinity in all other cases
07390     }
07391   if (needmax) {
07392     decSetMaxValue(dn, set);
07393     dn->bits=sign;                 // set sign
07394     }
07395    else dn->bits=sign|DECINF;      // Value is +/-Infinity
07396   *status|=DEC_Overflow | DEC_Inexact | DEC_Rounded;
07397   } // decSetOverflow
07398
07399 /* ------------------------------------------------------------------ */
07400 /* decSetMaxValue -- set number to +Nmax (maximum normal value)       */
07401 /*                                                                    */
07402 /*   dn is the number to set                                          */
07403 /*   set is the context [used for digits and emax]                    */
07404 /*                                                                    */
07405 /* This sets the number to the maximum positive value.                */
07406 /* ------------------------------------------------------------------ */
07407 static void decSetMaxValue(decNumber *dn, decContext *set) {
07408   Unit *up;                        // work
07409   Int count=set->digits;           // nines to add
07410   dn->digits=count;
07411   // fill in all nines to set maximum value
07412   for (up=dn->lsu; ; up++) {
07413     if (count>DECDPUN) *up=DECDPUNMAX;  // unit full o'nines
07414      else {                             // this is the msu
07415       *up=(Unit)(powers[count]-1);
07416       break;
07417       }
07418     count-=DECDPUN;                // filled those digits
07419     } // up
07420   dn->bits=0;                      // + sign
07421   dn->exponent=set->emax-set->digits+1;
07422   } // decSetMaxValue
07423
07424 /* ------------------------------------------------------------------ */
07425 /* decSetSubnormal -- process value whose exponent is <Emin           */
07426 /*                                                                    */
07427 /*   dn is the number (used as input as well as output; it may have   */
07428 /*         an allowed subnormal value, which may need to be rounded)  */
07429 /*   set is the context [used for the rounding mode]                  */
07430 /*   residue is any pending residue                                   */
07431 /*   status contains the current status to be updated                 */
07432 /*                                                                    */
07433 /* If subset mode, set result to zero and set Underflow flags.        */
07434 /*                                                                    */
07435 /* Value may be zero with a low exponent; this does not set Subnormal */
07436 /* but the exponent will be clamped to Etiny.                         */
07437 /*                                                                    */
07438 /* Otherwise ensure exponent is not out of range, and round as        */
07439 /* necessary.  Underflow is set if the result is Inexact.             */
07440 /* ------------------------------------------------------------------ */
07441 static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
07442                             uInt *status) {
07443   decContext workset;         // work
07444   Int        etiny, adjust;   // ..
07445
07446   #if DECSUBSET
07447   // simple set to zero and 'hard underflow' for subset
07448   if (!set->extended) {
07449     decNumberZero(dn);
07450     // always full overflow
07451     *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
07452     return;
07453     }
07454   #endif
07455
07456   // Full arithmetic -- allow subnormals, rounded to minimum exponent
07457   // (Etiny) if needed
07458   etiny=set->emin-(set->digits-1);      // smallest allowed exponent
07459
07460   if ISZERO(dn) {                       // value is zero
07461     // residue can never be non-zero here
07462     #if DECCHECK
07463       if (*residue!=0) {
07464         printf("++ Subnormal 0 residue %ld\n", (LI)*residue);
07465         *status|=DEC_Invalid_operation;
07466         }
07467     #endif
07468     if (dn->exponent<etiny) {           // clamp required
07469       dn->exponent=etiny;
07470       *status|=DEC_Clamped;
07471       }
07472     return;
07473     }
07474
07475   *status|=DEC_Subnormal;               // have a non-zero subnormal
07476   adjust=etiny-dn->exponent;            // calculate digits to remove
07477   if (adjust<=0) {                      // not out of range; unrounded
07478     // residue can never be non-zero here, except in the Nmin-residue
07479     // case (which is a subnormal result), so can take fast-path here
07480     // it may already be inexact (from setting the coefficient)
07481     if (*status&DEC_Inexact) *status|=DEC_Underflow;
07482     return;
07483     }
07484
07485   // adjust>0, so need to rescale the result so exponent becomes Etiny
07486   // [this code is similar to that in rescale]
07487   workset=*set;                         // clone rounding, etc.
07488   workset.digits=dn->digits-adjust;     // set requested length
07489   workset.emin-=adjust;                 // and adjust emin to match
07490   // [note that the latter can be <1, here, similar to Rescale case]
07491   decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
07492   decApplyRound(dn, &workset, *residue, status);
07493
07494   // Use 754 default rule: Underflow is set iff Inexact
07495   // [independent of whether trapped]
07496   if (*status&DEC_Inexact) *status|=DEC_Underflow;
07497
07498   // if rounded up a 999s case, exponent will be off by one; adjust
07499   // back if so [it will fit, because it was shortened earlier]
07500   if (dn->exponent>etiny) {
07501     dn->digits=decShiftToMost(dn->lsu, dn->digits, 1);
07502     dn->exponent--;                     // (re)adjust the exponent.
07503     }
07504
07505   // if rounded to zero, it is by definition clamped...
07506   if (ISZERO(dn)) *status|=DEC_Clamped;
07507   } // decSetSubnormal
07508
07509 /* ------------------------------------------------------------------ */
07510 /* decCheckMath - check entry conditions for a math function          */
07511 /*                                                                    */
07512 /*   This checks the context and the operand                          */
07513 /*                                                                    */
07514 /*   rhs is the operand to check                                      */
07515 /*   set is the context to check                                      */
07516 /*   status is unchanged if both are good                             */
07517 /*                                                                    */
07518 /* returns non-zero if status is changed, 0 otherwise                 */
07519 /*                                                                    */
07520 /* Restrictions enforced:                                             */
07521 /*                                                                    */
07522 /*   digits, emax, and -emin in the context must be less than         */
07523 /*   DEC_MAX_MATH (999999), and A must be within these bounds if      */
07524 /*   non-zero.  Invalid_operation is set in the status if a           */
07525 /*   restriction is violated.                                         */
07526 /* ------------------------------------------------------------------ */
07527 static uInt decCheckMath(const decNumber *rhs, decContext *set,
07528                          uInt *status) {
07529   uInt save=*status;                         // record
07530   if (set->digits>DEC_MAX_MATH
07531    || set->emax>DEC_MAX_MATH
07532    || -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context;
07533    else if ((rhs->digits>DEC_MAX_MATH
07534      || rhs->exponent+rhs->digits>DEC_MAX_MATH+1
07535      || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH))
07536      && !ISZERO(rhs)) *status|=DEC_Invalid_operation;
07537   return (*status!=save);
07538   } // decCheckMath
07539
07540 /* ------------------------------------------------------------------ */
07541 /* decGetInt -- get integer from a number                             */
07542 /*                                                                    */
07543 /*   dn is the number [which will not be altered]                     */
07544 /*                                                                    */
07545 /*   returns one of:                                                  */
07546 /*     BADINT if there is a non-zero fraction                         */
07547 /*     the converted integer                                          */
07548 /*     BIGEVEN if the integer is even and magnitude > 2*10**9         */
07549 /*     BIGODD  if the integer is odd  and magnitude > 2*10**9         */
07550 /*                                                                    */
07551 /* This checks and gets a whole number from the input decNumber.      */
07552 /* The sign can be determined from dn by the caller when BIGEVEN or   */
07553 /* BIGODD is returned.                                                */
07554 /* ------------------------------------------------------------------ */
07555 static Int decGetInt(const decNumber *dn) {
07556   Int  theInt;                          // result accumulator
07557   const Unit *up;                       // work
07558   Int  got;                             // digits (real or not) processed
07559   Int  ilength=dn->digits+dn->exponent; // integral length
07560   Flag neg=decNumberIsNegative(dn);     // 1 if -ve
07561
07562   // The number must be an integer that fits in 10 digits
07563   // Assert, here, that 10 is enough for any rescale Etiny
07564   #if DEC_MAX_EMAX > 999999999
07565     #error GetInt may need updating [for Emax]
07566   #endif
07567   #if DEC_MIN_EMIN < -999999999
07568     #error GetInt may need updating [for Emin]
07569   #endif
07570   if (ISZERO(dn)) return 0;             // zeros are OK, with any exponent
07571
07572   up=dn->lsu;                           // ready for lsu
07573   theInt=0;                             // ready to accumulate
07574   if (dn->exponent>=0) {                // relatively easy
07575     // no fractional part [usual]; allow for positive exponent
07576     got=dn->exponent;
07577     }
07578    else { // -ve exponent; some fractional part to check and discard
07579     Int count=-dn->exponent;            // digits to discard
07580     // spin up whole units until reach the Unit with the unit digit
07581     for (; count>=DECDPUN; up++) {
07582       if (*up!=0) return BADINT;        // non-zero Unit to discard
07583       count-=DECDPUN;
07584       }
07585     if (count==0) got=0;                // [a multiple of DECDPUN]
07586      else {                             // [not multiple of DECDPUN]
07587       Int rem;                          // work
07588       // slice off fraction digits and check for non-zero
07589       #if DECDPUN<=4
07590         theInt=QUOT10(*up, count);
07591         rem=*up-theInt*powers[count];
07592       #else
07593         rem=*up%powers[count];          // slice off discards
07594         theInt=*up/powers[count];
07595       #endif
07596       if (rem!=0) return BADINT;        // non-zero fraction
07597       // it looks good
07598       got=DECDPUN-count;                // number of digits so far
07599       up++;                             // ready for next
07600       }
07601     }
07602   // now it's known there's no fractional part
07603
07604   // tricky code now, to accumulate up to 9.3 digits
07605   if (got==0) {theInt=*up; got+=DECDPUN; up++;} // ensure lsu is there
07606
07607   if (ilength<11) {
07608     Int save=theInt;
07609     // collect any remaining unit(s)
07610     for (; got<ilength; up++) {
07611       theInt+=*up*powers[got];
07612       got+=DECDPUN;
07613       }
07614     if (ilength==10) {                  // need to check for wrap
07615       if (theInt/(Int)powers[got-DECDPUN]!=(Int)*(up-1)) ilength=11;
07616          // [that test also disallows the BADINT result case]
07617        else if (neg && theInt>1999999997) ilength=11;
07618        else if (!neg && theInt>999999999) ilength=11;
07619       if (ilength==11) theInt=save;     // restore correct low bit
07620       }
07621     }
07622
07623   if (ilength>10) {                     // too big
07624     if (theInt&1) return BIGODD;        // bottom bit 1
07625     return BIGEVEN;                     // bottom bit 0
07626     }
07627
07628   if (neg) theInt=-theInt;              // apply sign
07629   return theInt;
07630   } // decGetInt
07631
07632 /* ------------------------------------------------------------------ */
07633 /* decDecap -- decapitate the coefficient of a number                 */
07634 /*                                                                    */
07635 /*   dn   is the number to be decapitated                             */
07636 /*   drop is the number of digits to be removed from the left of dn;  */
07637 /*     this must be <= dn->digits (if equal, the coefficient is       */
07638 /*     set to 0)                                                      */
07639 /*                                                                    */
07640 /* Returns dn; dn->digits will be <= the initial digits less drop     */
07641 /* (after removing drop digits there may be leading zero digits       */
07642 /* which will also be removed).  Only dn->lsu and dn->digits change.  */
07643 /* ------------------------------------------------------------------ */
07644 static decNumber *decDecap(decNumber *dn, Int drop) {
07645   Unit *msu;                            // -> target cut point
07646   Int cut;                              // work
07647   if (drop>=dn->digits) {               // losing the whole thing
07648     #if DECCHECK
07649     if (drop>dn->digits)
07650       printf("decDecap called with drop>digits [%ld>%ld]\n",
07651              (LI)drop, (LI)dn->digits);
07652     #endif
07653     dn->lsu[0]=0;
07654     dn->digits=1;
07655     return dn;
07656     }
07657   msu=dn->lsu+D2U(dn->digits-drop)-1;   // -> likely msu
07658   cut=MSUDIGITS(dn->digits-drop);       // digits to be in use in msu
07659   if (cut!=DECDPUN) *msu%=powers[cut];  // clear left digits
07660   // that may have left leading zero digits, so do a proper count...
07661   dn->digits=decGetDigits(dn->lsu, msu-dn->lsu+1);
07662   return dn;
07663   } // decDecap
07664
07665 /* ------------------------------------------------------------------ */
07666 /* decBiStr -- compare string with pairwise options                   */
07667 /*                                                                    */
07668 /*   targ is the string to compare                                    */
07669 /*   str1 is one of the strings to compare against (length may be 0)  */
07670 /*   str2 is the other; it must be the same length as str1            */
07671 /*                                                                    */
07672 /*   returns 1 if strings compare equal, (that is, it is the same     */
07673 /*   length as str1 and str2, and each character of targ is in either */
07674 /*   str1 or str2 in the corresponding position), or 0 otherwise      */
07675 /*                                                                    */
07676 /* This is used for generic caseless compare, including the awkward   */
07677 /* case of the Turkish dotted and dotless Is.  Use as (for example):  */
07678 /*   if (decBiStr(test, "mike", "MIKE")) ...                          */
07679 /* ------------------------------------------------------------------ */
07680 static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
07681   for (;;targ++, str1++, str2++) {
07682     if (*targ!=*str1 && *targ!=*str2) return 0;
07683     // *targ has a match in one (or both, if terminator)
07684     if (*targ=='\0') break;
07685     } // forever
07686   return 1;
07687   } // decBiStr
07688
07689 /* ------------------------------------------------------------------ */
07690 /* decNaNs -- handle NaN operand or operands                          */
07691 /*                                                                    */
07692 /*   res     is the result number                                     */
07693 /*   lhs     is the first operand                                     */
07694 /*   rhs     is the second operand, or NULL if none                   */
07695 /*   context is used to limit payload length                          */
07696 /*   status  contains the current status                              */
07697 /*   returns res in case convenient                                   */
07698 /*                                                                    */
07699 /* Called when one or both operands is a NaN, and propagates the      */
07700 /* appropriate result to res.  When an sNaN is found, it is changed   */
07701 /* to a qNaN and Invalid operation is set.                            */
07702 /* ------------------------------------------------------------------ */
07703 static decNumber * decNaNs(decNumber *res, const decNumber *lhs,
07704                            const decNumber *rhs, decContext *set,
07705                            uInt *status) {
07706   // This decision tree ends up with LHS being the source pointer,
07707   // and status updated if need be
07708   if (lhs->bits & DECSNAN)
07709     *status|=DEC_Invalid_operation | DEC_sNaN;
07710    else if (rhs==NULL);
07711    else if (rhs->bits & DECSNAN) {
07712     lhs=rhs;
07713     *status|=DEC_Invalid_operation | DEC_sNaN;
07714     }
07715    else if (lhs->bits & DECNAN);
07716    else lhs=rhs;
07717
07718   // propagate the payload
07719   if (lhs->digits<=set->digits) decNumberCopy(res, lhs); // easy
07720    else { // too long
07721     const Unit *ul;
07722     Unit *ur, *uresp1;
07723     // copy safe number of units, then decapitate
07724     res->bits=lhs->bits;                // need sign etc.
07725     uresp1=res->lsu+D2U(set->digits);
07726     for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul;
07727     res->digits=D2U(set->digits)*DECDPUN;
07728     // maybe still too long
07729     if (res->digits>set->digits) decDecap(res, res->digits-set->digits);
07730     }
07731
07732   res->bits&=~DECSNAN;        // convert any sNaN to NaN, while
07733   res->bits|=DECNAN;          // .. preserving sign
07734   res->exponent=0;            // clean exponent
07735                               // [coefficient was copied/decapitated]
07736   return res;
07737   } // decNaNs
07738
07739 /* ------------------------------------------------------------------ */
07740 /* decStatus -- apply non-zero status                                 */
07741 /*                                                                    */
07742 /*   dn     is the number to set if error                             */
07743 /*   status contains the current status (not yet in context)          */
07744 /*   set    is the context                                            */
07745 /*                                                                    */
07746 /* If the status is an error status, the number is set to a NaN,      */
07747 /* unless the error was an overflow, divide-by-zero, or underflow,    */
07748 /* in which case the number will have already been set.               */
07749 /*                                                                    */
07750 /* The context status is then updated with the new status.  Note that */
07751 /* this may raise a signal, so control may never return from this     */
07752 /* routine (hence resources must be recovered before it is called).   */
07753 /* ------------------------------------------------------------------ */
07754 static void decStatus(decNumber *dn, uInt status, decContext *set) {
07755   if (status & DEC_NaNs) {              // error status -> NaN
07756     // if cause was an sNaN, clear and propagate [NaN is already set up]
07757     if (status & DEC_sNaN) status&=~DEC_sNaN;
07758      else {
07759       decNumberZero(dn);                // other error: clean throughout
07760       dn->bits=DECNAN;                  // and make a quiet NaN
07761       }
07762     }
07763   decContextSetStatus(set, status);     // [may not return]
07764   return;
07765   } // decStatus
07766
07767 /* ------------------------------------------------------------------ */
07768 /* decGetDigits -- count digits in a Units array                      */
07769 /*                                                                    */
07770 /*   uar is the Unit array holding the number (this is often an       */
07771 /*          accumulator of some sort)                                 */
07772 /*   len is the length of the array in units [>=1]                    */
07773 /*                                                                    */
07774 /*   returns the number of (significant) digits in the array          */
07775 /*                                                                    */
07776 /* All leading zeros are excluded, except the last if the array has   */
07777 /* only zero Units.                                                   */
07778 /* ------------------------------------------------------------------ */
07779 // This may be called twice during some operations.
07780 static Int decGetDigits(Unit *uar, Int len) {
07781   Unit *up=uar+(len-1);            // -> msu
07782   Int  digits=(len-1)*DECDPUN+1;   // possible digits excluding msu
07783   #if DECDPUN>4
07784   uInt const *pow;                 // work
07785   #endif
07786                                    // (at least 1 in final msu)
07787   #if DECCHECK
07788   if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len);
07789   #endif
07790
07791   for (; up>=uar; up--) {
07792     if (*up==0) {                  // unit is all 0s
07793       if (digits==1) break;        // a zero has one digit
07794       digits-=DECDPUN;             // adjust for 0 unit
07795       continue;}
07796     // found the first (most significant) non-zero Unit
07797     #if DECDPUN>1                  // not done yet
07798     if (*up<10) break;             // is 1-9
07799     digits++;
07800     #if DECDPUN>2                  // not done yet
07801     if (*up<100) break;            // is 10-99
07802     digits++;
07803     #if DECDPUN>3                  // not done yet
07804     if (*up<1000) break;           // is 100-999
07805     digits++;
07806     #if DECDPUN>4                  // count the rest ...
07807     for (pow=&powers[4]; *up>=*pow; pow++) digits++;
07808     #endif
07809     #endif
07810     #endif
07811     #endif
07812     break;
07813     } // up
07814   return digits;
07815   } // decGetDigits
07816
07817 #if DECTRACE | DECCHECK
07818 /* ------------------------------------------------------------------ */
07819 /* decNumberShow -- display a number [debug aid]                      */
07820 /*   dn is the number to show                                         */
07821 /*                                                                    */
07822 /* Shows: sign, exponent, coefficient (msu first), digits             */
07823 /*    or: sign, special-value                                         */
07824 /* ------------------------------------------------------------------ */
07825 // this is public so other modules can use it
07826 void decNumberShow(const decNumber *dn) {
07827   const Unit *up;                  // work
07828   uInt u, d;                       // ..
07829   Int cut;                         // ..
07830   char isign='+';                  // main sign
07831   if (dn==NULL) {
07832     printf("NULL\n");
07833     return;}
07834   if (decNumberIsNegative(dn)) isign='-';
07835   printf(" >> %c ", isign);
07836   if (dn->bits&DECSPECIAL) {       // Is a special value
07837     if (decNumberIsInfinite(dn)) printf("Infinity");
07838      else {                                  // a NaN
07839       if (dn->bits&DECSNAN) printf("sNaN");  // signalling NaN
07840        else printf("NaN");
07841       }
07842     // if coefficient and exponent are 0, no more to do
07843     if (dn->exponent==0 && dn->digits==1 && *dn->lsu==0) {
07844       printf("\n");
07845       return;}
07846     // drop through to report other information
07847     printf(" ");
07848     }
07849
07850   // now carefully display the coefficient
07851   up=dn->lsu+D2U(dn->digits)-1;         // msu
07852   printf("%ld", (LI)*up);
07853   for (up=up-1; up>=dn->lsu; up--) {
07854     u=*up;
07855     printf(":");
07856     for (cut=DECDPUN-1; cut>=0; cut--) {
07857       d=u/powers[cut];
07858       u-=d*powers[cut];
07859       printf("%ld", (LI)d);
07860       } // cut
07861     } // up
07862   if (dn->exponent!=0) {
07863     char esign='+';
07864     if (dn->exponent<0) esign='-';
07865     printf(" E%c%ld", esign, (LI)abs(dn->exponent));
07866     }
07867   printf(" [%ld]\n", (LI)dn->digits);
07868   } // decNumberShow
07869 #endif
07870
07871 #if DECTRACE || DECCHECK
07872 /* ------------------------------------------------------------------ */
07873 /* decDumpAr -- display a unit array [debug/check aid]                */
07874 /*   name is a single-character tag name                              */
07875 /*   ar   is the array to display                                     */
07876 /*   len  is the length of the array in Units                         */
07877 /* ------------------------------------------------------------------ */
07878 static void decDumpAr(char name, const Unit *ar, Int len) {
07879   Int i;
07880   const char *spec;
07881   #if DECDPUN==9
07882     spec="%09d ";
07883   #elif DECDPUN==8
07884     spec="%08d ";
07885   #elif DECDPUN==7
07886     spec="%07d ";
07887   #elif DECDPUN==6
07888     spec="%06d ";
07889   #elif DECDPUN==5
07890     spec="%05d ";
07891   #elif DECDPUN==4
07892     spec="%04d ";
07893   #elif DECDPUN==3
07894     spec="%03d ";
07895   #elif DECDPUN==2
07896     spec="%02d ";
07897   #else
07898     spec="%d ";
07899   #endif
07900   printf("  :%c: ", name);
07901   for (i=len-1; i>=0; i--) {
07902     if (i==len-1) printf("%ld ", (LI)ar[i]);
07903      else printf(spec, ar[i]);
07904     }
07905   printf("\n");
07906   return;}
07907 #endif
07908
07909 #if DECCHECK
07910 /* ------------------------------------------------------------------ */
07911 /* decCheckOperands -- check operand(s) to a routine                  */
07912 /*   res is the result structure (not checked; it will be set to      */
07913 /*          quiet NaN if error found (and it is not NULL))            */
07914 /*   lhs is the first operand (may be DECUNRESU)                      */
07915 /*   rhs is the second (may be DECUNUSED)                             */
07916 /*   set is the context (may be DECUNCONT)                            */
07917 /*   returns 0 if both operands, and the context are clean, or 1      */
07918 /*     otherwise (in which case the context will show an error,       */
07919 /*     unless NULL).  Note that res is not cleaned; caller should     */
07920 /*     handle this so res=NULL case is safe.                          */
07921 /* The caller is expected to abandon immediately if 1 is returned.    */
07922 /* ------------------------------------------------------------------ */
07923 static Flag decCheckOperands(decNumber *res, const decNumber *lhs,
07924                              const decNumber *rhs, decContext *set) {
07925   Flag bad=0;
07926   if (set==NULL) {                 // oops; hopeless
07927     #if DECTRACE || DECVERB
07928     printf("Reference to context is NULL.\n");
07929     #endif
07930     bad=1;
07931     return 1;}
07932    else if (set!=DECUNCONT
07933      && (set->digits<1 || set->round>=DEC_ROUND_MAX)) {
07934     bad=1;
07935     #if DECTRACE || DECVERB
07936     printf("Bad context [digits=%ld round=%ld].\n",
07937            (LI)set->digits, (LI)set->round);
07938     #endif
07939     }
07940    else {
07941     if (res==NULL) {
07942       bad=1;
07943       #if DECTRACE
07944       // this one not DECVERB as standard tests include NULL
07945       printf("Reference to result is NULL.\n");
07946       #endif
07947       }
07948     if (!bad && lhs!=DECUNUSED) bad=(decCheckNumber(lhs));
07949     if (!bad && rhs!=DECUNUSED) bad=(decCheckNumber(rhs));
07950     }
07951   if (bad) {
07952     if (set!=DECUNCONT) decContextSetStatus(set, DEC_Invalid_operation);
07953     if (res!=DECUNRESU && res!=NULL) {
07954       decNumberZero(res);
07955       res->bits=DECNAN;       // qNaN
07956       }
07957     }
07958   return bad;
07959   } // decCheckOperands
07960
07961 /* ------------------------------------------------------------------ */
07962 /* decCheckNumber -- check a number                                   */
07963 /*   dn is the number to check                                        */
07964 /*   returns 0 if the number is clean, or 1 otherwise                 */
07965 /*                                                                    */
07966 /* The number is considered valid if it could be a result from some   */
07967 /* operation in some valid context.                                   */
07968 /* ------------------------------------------------------------------ */
07969 static Flag decCheckNumber(const decNumber *dn) {
07970   const Unit *up;             // work
07971   uInt maxuint;               // ..
07972   Int ae, d, digits;          // ..
07973   Int emin, emax;             // ..
07974
07975   if (dn==NULL) {             // hopeless
07976     #if DECTRACE
07977     // this one not DECVERB as standard tests include NULL
07978     printf("Reference to decNumber is NULL.\n");
07979     #endif
07980     return 1;}
07981
07982   // check special values
07983   if (dn->bits & DECSPECIAL) {
07984     if (dn->exponent!=0) {
07985       #if DECTRACE || DECVERB
07986       printf("Exponent %ld (not 0) for a special value [%02x].\n",
07987              (LI)dn->exponent, dn->bits);
07988       #endif
07989       return 1;}
07990
07991     // 2003.09.08: NaNs may now have coefficients, so next tests Inf only
07992     if (decNumberIsInfinite(dn)) {
07993       if (dn->digits!=1) {
07994         #if DECTRACE || DECVERB
07995         printf("Digits %ld (not 1) for an infinity.\n", (LI)dn->digits);
07996         #endif
07997         return 1;}
07998       if (*dn->lsu!=0) {
07999         #if DECTRACE || DECVERB
08000         printf("LSU %ld (not 0) for an infinity.\n", (LI)*dn->lsu);
08001         #endif
08002         decDumpAr('I', dn->lsu, D2U(dn->digits));
08003         return 1;}
08004       } // Inf
08005     // 2002.12.26: negative NaNs can now appear through proposed IEEE
08006     //             concrete formats (decimal64, etc.).
08007     return 0;
08008     }
08009
08010   // check the coefficient
08011   if (dn->digits<1 || dn->digits>DECNUMMAXP) {
08012     #if DECTRACE || DECVERB
08013     printf("Digits %ld in number.\n", (LI)dn->digits);
08014     #endif
08015     return 1;}
08016
08017   d=dn->digits;
08018
08019   for (up=dn->lsu; d>0; up++) {
08020     if (d>DECDPUN) maxuint=DECDPUNMAX;
08021      else {                   // reached the msu
08022       maxuint=powers[d]-1;
08023       if (dn->digits>1 && *up<powers[d-1]) {
08024         #if DECTRACE || DECVERB
08025         printf("Leading 0 in number.\n");
08026         decNumberShow(dn);
08027         #endif
08028         return 1;}
08029       }
08030     if (*up>maxuint) {
08031       #if DECTRACE || DECVERB
08032       printf("Bad Unit [%08lx] in %ld-digit number at offset %ld [maxuint %ld].\n",
08033               (LI)*up, (LI)dn->digits, (LI)(up-dn->lsu), (LI)maxuint);
08034       #endif
08035       return 1;}
08036     d-=DECDPUN;
08037     }
08038
08039   // check the exponent.  Note that input operands can have exponents
08040   // which are out of the set->emin/set->emax and set->digits range
08041   // (just as they can have more digits than set->digits).
08042   ae=dn->exponent+dn->digits-1;    // adjusted exponent
08043   emax=DECNUMMAXE;
08044   emin=DECNUMMINE;
08045   digits=DECNUMMAXP;
08046   if (ae<emin-(digits-1)) {
08047     #if DECTRACE || DECVERB
08048     printf("Adjusted exponent underflow [%ld].\n", (LI)ae);
08049     decNumberShow(dn);
08050     #endif
08051     return 1;}
08052   if (ae>+emax) {
08053     #if DECTRACE || DECVERB
08054     printf("Adjusted exponent overflow [%ld].\n", (LI)ae);
08055     decNumberShow(dn);
08056     #endif
08057     return 1;}
08058
08059   return 0;              // it's OK
08060   } // decCheckNumber
08061
08062 /* ------------------------------------------------------------------ */
08063 /* decCheckInexact -- check a normal finite inexact result has digits */
08064 /*   dn is the number to check                                        */
08065 /*   set is the context (for status and precision)                    */
08066 /*   sets Invalid operation, etc., if some digits are missing         */
08067 /* [this check is not made for DECSUBSET compilation or when          */
08068 /* subnormal is not set]                                              */
08069 /* ------------------------------------------------------------------ */
08070 static void decCheckInexact(const decNumber *dn, decContext *set) {
08071   #if !DECSUBSET && DECEXTFLAG
08072     if ((set->status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact
08073      && (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL)) {
08074       #if DECTRACE || DECVERB
08075       printf("Insufficient digits [%ld] on normal Inexact result.\n",
08076              (LI)dn->digits);
08077       decNumberShow(dn);
08078       #endif
08079       decContextSetStatus(set, DEC_Invalid_operation);
08080       }
08081   #else
08082     // next is a noop for quiet compiler
08083     if (dn!=NULL && dn->digits==0) set->status|=DEC_Invalid_operation;
08084   #endif
08085   return;
08086   } // decCheckInexact
08087 #endif
08088
08089 #if DECALLOC
08090 #undef malloc
08091 #undef free
08092 /* ------------------------------------------------------------------ */
08093 /* decMalloc -- accountable allocation routine                        */
08094 /*   n is the number of bytes to allocate                             */
08095 /*                                                                    */
08096 /* Semantics is the same as the stdlib malloc routine, but bytes      */
08097 /* allocated are accounted for globally, and corruption fences are    */
08098 /* added before and after the 'actual' storage.                       */
08099 /* ------------------------------------------------------------------ */
08100 /* This routine allocates storage with an extra twelve bytes; 8 are   */
08101 /* at the start and hold:                                             */
08102 /*   0-3 the original length requested                                */
08103 /*   4-7 buffer corruption detection fence (DECFENCE, x4)             */
08104 /* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */
08105 /* ------------------------------------------------------------------ */
08106 static void *decMalloc(size_t n) {
08107   uInt  size=n+12;                 // true size
08108   void  *alloc;                    // -> allocated storage
08109   uByte *b, *b0;                   // work
08110   uInt  uiwork;                    // for macros
08111
08112   alloc=malloc(size);              // -> allocated storage
08113   if (alloc==NULL) return NULL;    // out of strorage
08114   b0=(uByte *)alloc;               // as bytes
08115   decAllocBytes+=n;                // account for storage
08116   UBFROMUI(alloc, n);              // save n
08117   // printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n);
08118   for (b=b0+4; b<b0+8; b++) *b=DECFENCE;
08119   for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;
08120   return b0+8;                     // -> play area
08121   } // decMalloc
08122
08123 /* ------------------------------------------------------------------ */
08124 /* decFree -- accountable free routine                                */
08125 /*   alloc is the storage to free                                     */
08126 /*                                                                    */
08127 /* Semantics is the same as the stdlib malloc routine, except that    */
08128 /* the global storage accounting is updated and the fences are        */
08129 /* checked to ensure that no routine has written 'out of bounds'.     */
08130 /* ------------------------------------------------------------------ */
08131 /* This routine first checks that the fences have not been corrupted. */
08132 /* It then frees the storage using the 'truw' storage address (that   */
08133 /* is, offset by 8).                                                  */
08134 /* ------------------------------------------------------------------ */
08135 static void decFree(void *alloc) {
08136   uInt  n;                         // original length
08137   uByte *b, *b0;                   // work
08138   uInt  uiwork;                    // for macros
08139
08140   if (alloc==NULL) return;         // allowed; it's a nop
08141   b0=(uByte *)alloc;               // as bytes
08142   b0-=8;                           // -> true start of storage
08143   n=UBTOUI(b0);                    // lift length
08144   for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)
08145     printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b,
08146            b-b0-8, (LI)b0);
08147   for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE)
08148     printf("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n", *b,
08149            b-b0-8, (LI)b0, (LI)n);
08150   free(b0);                        // drop the storage
08151   decAllocBytes-=n;                // account for storage
08152   // printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n);
08153   } // decFree
08154
08155
08156 /* ================================================================== */
08157 /* Utility routines                                                   */
08158 /* ================================================================== */
08159
08160 /* ------------------------------------------------------------------ */
08161 /* decNumberCopy -- copy a number                                     */
08162 /*                                                                    */
08163 /*   dest is the target decNumber                                     */
08164 /*   src  is the source decNumber                                     */
08165 /*   returns dest                                                     */
08166 /*                                                                    */
08167 /* (dest==src is allowed and is a no-op)                              */
08168 /* All fields are updated as required.  This is a utility operation,  */
08169 /* so special values are unchanged and no error is possible.          */
08170 /* ------------------------------------------------------------------ */
08171
08172 /* ================================================================== */
08173 /*  decNumber * decNumberCopy(decNumber *, const decNumber *);        */
08174 /* ================================================================== */
08175
08176 /*  decNumber * decNumberCopy(decNumber *, const decNumber *);  */
08177 decNumber* decNumberCopy_(decNumber* dst, const decNumber* src)
08178 {
08179 decNumber d,s=(*src);
08180 return decNumberCopy(&d,&s);
08181 }
08182
08183
08184
08185
08186 #define malloc(a) decMalloc(a)
08187 #define free(a) decFree(a)
08188 #endif
Généré le Mon Jul 20 18:22:14 2009 pour Decimal par doxygen 1.5.1-p1


Decimal: Référence du fichier P:/wx_LIB/Dcml/decNumber.h

Référence du fichier P:/wx_LIB/Dcml/decNumber.h

#include "decContext.h"

Aller au code source de ce fichier.

Classes

struct | decNumber

Macros

#define | DECNUMBER
#define | DECNAME "decNumber"
#define | DECFULLNAME "Decimal Number Module"
#define | DECAUTHOR "Mike Cowlishaw"
#define | DECNEG 0x80
#define | DECINF 0x40
#define | DECNAN 0x20
#define | DECSNAN 0x10
#define | DECSPECIAL (DECINF|DECNAN|DECSNAN)
#define | DECDPUN 3
#define | DECNUMDIGITS 1
#define | decNumberUnit uint16_t
#define | DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)
#define | decNumberIsCanonical(dn) (1)
#define | decNumberIsFinite(dn) (((dn)->bits&DECSPECIAL)==0)
#define | decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
#define | decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
#define | decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
#define | decNumberIsQNaN(dn) (((dn)->bits&(DECNAN))!=0)
#define | decNumberIsSNaN(dn) (((dn)->bits&(DECSNAN))!=0)
#define | decNumberIsSpecial(dn) (((dn)->bits&DECSPECIAL)!=0)
#define | decNumberIsZero(dn)
#define | decNumberRadix(dn) (10)

Fonctions

decNumber * | decNumberFromInt32 (decNumber *, int32_t)
decNumber * | decNumberFromUInt32 (decNumber *, uint32_t)
decNumber * | decNumberFromString (decNumber *, const char *, decContext *)
char * | decNumberToString (const decNumber *, char *)
char * | decNumberToEngString (const decNumber *, char *)
uint32_t | decNumberToUInt32 (const decNumber *, decContext *)
int32_t | decNumberToInt32 (const decNumber *, decContext *)
uint8_t * | decNumberGetBCD (const decNumber *, uint8_t *)
decNumber * | decNumberSetBCD (decNumber *, const uint8_t *, uint32_t)
decNumber * | decNumberAbs (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberAdd (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberAnd (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberCompare (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberCompareSignal (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberCompareTotal (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberCompareTotalMag (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberDivide (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberDivideInteger (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberExp (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberFMA (decNumber *, const decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberInvert (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberLn (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberLogB (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberLog10 (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberMax (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberMaxMag (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberMin (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberMinMag (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberMinus (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberMultiply (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberNormalize (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberOr (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberPlus (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberPower (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberQuantize (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberReduce (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberRemainder (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberRemainderNear (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberRescale (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberRotate (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberSameQuantum (decNumber *, const decNumber *, const decNumber *)
decNumber * | decNumberScaleB (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberShift (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberSquareRoot (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberSubtract (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * | decNumberToIntegralExact (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberToIntegralValue (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberXor (decNumber *, const decNumber *, const decNumber *, decContext *)
enum decClass | decNumberClass (const decNumber *, decContext *)
const char * | decNumberClassToString (enum decClass)
decNumber * | decNumberCopy (decNumber *, const decNumber *)
decNumber * | decNumberCopyAbs (decNumber *, const decNumber *)
decNumber * | decNumberCopyNegate (decNumber *, const decNumber *)
decNumber * | decNumberCopySign (decNumber *, const decNumber *, const decNumber *)
decNumber * | decNumberNextMinus (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberNextPlus (decNumber *, const decNumber *, decContext *)
decNumber * | decNumberNextToward (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumber * decNumberTrim (decNumber *)
const char * | decNumberVersion (void)
decNumber * decNumberZero (decNumber *)
decNumber * | decNumberCopy_ (decNumber *dst, const decNumber *src)
int32_t | decNumberIsNormal (const decNumber *, decContext *)
int32_t | decNumberIsSubnormal (const decNumber *, decContext *)

Documentation des macros

#define DECAUTHOR "Mike Cowlishaw"

Définition à la ligne 26 du fichier decNumber.h.

#define DECDPUN 3

Définition à la ligne 45 du fichier decNumber.h.

Référencé par decAddOp(), decApplyRound(), decDecap(), decDivideOp(), decGetDigits(), decGetInt(), decMultiplyOp(), decNaNs(), decNumberAnd(), decNumberCopy(), decNumberGetBCD(), decNumberInvert(), decNumberOr(), decNumberRotate(), decNumberSetBCD(), decNumberToInt32(), decNumberToUInt32(), decNumberXor(), decSetCoeff(), decSetMaxValue(), decShiftToLeast(), decShiftToMost(), decToString(), decTrim(), decUnitAddSub(), et decUnitCompare().

#define DECFULLNAME "Decimal Number Module"

Définition à la ligne 25 du fichier decNumber.h.

#define DECINF 0x40

Définition à la ligne 34 du fichier decNumber.h.

Référencé par decAddOp(), decCompare(), decDivideOp(), decLnOp(), decMultiplyOp(), decNumberFromString(), decNumberLogB(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPower(), decQuantizeOp(), et decSetOverflow().

#define DECNAME "decNumber"

Définition à la ligne 24 du fichier decNumber.h.

#define DECNAN 0x20

Définition à la ligne 35 du fichier decNumber.h.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decMultiplyOp(), decNaNs(), decNumberFMA(), decNumberFromString(), decQuantizeOp(), et decStatus().

#define DECNEG 0x80

Définition à la ligne 33 du fichier decNumber.h.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decLnOp(), decMultiplyOp(), decNumberAbs(), decNumberCompareTotalMag(), decNumberCopyAbs(), decNumberCopyNegate(), decNumberCopySign(), decNumberFromInt32(), decNumberFromString(), decNumberLog10(), decNumberLogB(), decNumberMinus(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPower(), decNumberSquareRoot(), decNumberSubtract(), decNumberToInt32(), decNumberToUInt32(), et decSetOverflow().

#define DECNUMBER

Définition à la ligne 23 du fichier decNumber.h.

#define decNumberIsCanonical ( dn ) (1)

Définition à la ligne 171 du fichier decNumber.h.

#define decNumberIsFinite ( dn ) (((dn)->bits&DECSPECIAL)==0)

Définition à la ligne 172 du fichier decNumber.h.

#define decNumberIsInfinite ( dn ) (((dn)->bits&DECINF)!=0)

Définition à la ligne 173 du fichier decNumber.h.

Référencé par decAddOp(), decCompare(), decDivideOp(), decExpOp(), decLnOp(), decNumberLogB(), decNumberPower(), decNumberRotate(), decNumberSameQuantum(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToIntegralExact(), et decToString().

#define decNumberIsNaN ( dn ) (((dn)->bits&(DECNAN|DECSNAN))!=0)

Définition à la ligne 174 du fichier decNumber.h.

Référencé par decCompareOp(), decNumberLogB(), decNumberNextToward(), decNumberPower(), decNumberReduce(), decNumberRotate(), decNumberSameQuantum(), decNumberScaleB(), et decNumberShift().

#define decNumberIsNegative ( dn ) (((dn)->bits&DECNEG)!=0)

Définition à la ligne 175 du fichier decNumber.h.

Référencé par decApplyRound(), decCompare(), decCompareOp(), decExpOp(), decGetInt(), decLnOp(), decNumberAnd(), decNumberClass(), decNumberCompareTotalMag(), decNumberInvert(), decNumberOr(), decNumberPower(), decNumberSquareRoot(), decNumberXor(), decToString(), et operator<().

#define decNumberIsQNaN ( dn ) (((dn)->bits&(DECNAN))!=0)

Définition à la ligne 176 du fichier decNumber.h.

Référencé par decCompareOp(), et decNumberClass().

#define decNumberIsSNaN ( dn ) (((dn)->bits&(DECSNAN))!=0)

Définition à la ligne 177 du fichier decNumber.h.

Référencé par decCompareOp(), et decNumberClass().

#define decNumberIsSpecial ( dn ) (((dn)->bits&DECSPECIAL)!=0)

Définition à la ligne 178 du fichier decNumber.h.

Référencé par decNumberAnd(), decNumberClass(), decNumberFMA(), decNumberInvert(), decNumberIsNormal(), decNumberIsSubnormal(), decNumberOr(), et decNumberXor().

#define decNumberIsZero ( dn )

Valeur :

(*(dn)->lsu==0 \
                                    && (dn)->digits==1 \
                                    && (((dn)->bits&DECSPECIAL)==0))

Définition à la ligne 179 du fichier decNumber.h.

Référencé par decLnOp(), decNumberClass(), decNumberIsNormal(), decNumberIsSubnormal(), decNumberLogB(), decNumberPower(), operator<(), operator==(), et DecFloat_::SameQuantum().

#define decNumberRadix ( dn ) (10)

Définition à la ligne 182 du fichier decNumber.h.

#define decNumberUnit uint16_t

Définition à la ligne 61 du fichier decNumber.h.

#define DECNUMDIGITS 1

Définition à la ligne 53 du fichier decNumber.h.

#define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)

Définition à la ligne 66 du fichier decNumber.h.

#define DECSNAN 0x10

Définition à la ligne 36 du fichier decNumber.h.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decMultiplyOp(), decNaNs(), decNumberFromString(), decQuantizeOp(), et decToString().

#define DECSPECIAL (DECINF|DECNAN|DECSNAN)

Définition à la ligne 38 du fichier decNumber.h.

Référencé par decNumberLog10(), decNumberToInt32(), decNumberToUInt32(), decToString(), et decTrim().

Documentation des fonctions

decNumber* decNumberAbs | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 757 du fichier decNumber.c.

Références decNumber::bits, decAddOp(), DECNEG, decNumberZero(), decStatus(), decNumber::exponent, uByte, et uInt.

Référencé par abs().

00758                                           {
00759   decNumber dzero;                      // for 0
00760   uInt status=0;                        // accumulator
00761
00762   #if DECCHECK
00763   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
00764   #endif
00765
00766   decNumberZero(&dzero);                // set 0
00767   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
00768   decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
00769   if (status!=0) decStatus(res, status, set);
00770   #if DECCHECK
00771   decCheckInexact(res, set);
00772   #endif
00773   return res;
00774   } // decNumberAbs

decNumber* decNumberAdd | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 789 du fichier decNumber.c.

Références decAddOp(), decStatus(), et uInt.

Référencé par DecFloat_::operator+=().

00790                                                                 {
00791   uInt status=0;                        // accumulator
00792   decAddOp(res, lhs, rhs, set, 0, &status);
00793   if (status!=0) decStatus(res, status, set);
00794   #if DECCHECK
00795   decCheckInexact(res, set);
00796   #endif
00797   return res;
00798   } // decNumberAdd

decNumber* decNumberAnd | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 815 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decContext::digits, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

00816                                                                 {
00817   const Unit *ua, *ub;                  // -> operands
00818   const Unit *msua, *msub;              // -> operand msus
00819   Unit *uc,  *msuc;                     // -> result and its msu
00820   Int   msudigs;                        // digits in res msu
00821   #if DECCHECK
00822   if (decCheckOperands(res, lhs, rhs, set)) return res;
00823   #endif
00824
00825   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
00826    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
00827     decStatus(res, DEC_Invalid_operation, set);
00828     return res;
00829     }
00830
00831   // operands are valid
00832   ua=lhs->lsu;                          // bottom-up
00833   ub=rhs->lsu;                          // ..
00834   uc=res->lsu;                          // ..
00835   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
00836   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
00837   msuc=uc+D2U(set->digits)-1;           // -> msu of result
00838   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
00839   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
00840     Unit a, b;                          // extract units
00841     if (ua>msua) a=0;
00842      else a=*ua;
00843     if (ub>msub) b=0;
00844      else b=*ub;
00845     *uc=0;                              // can now write back
00846     if (a|b) {                          // maybe 1 bits to examine
00847       Int i, j;
00848       *uc=0;                            // can now write back
00849       // This loop could be unrolled and/or use BIN2BCD tables
00850       for (i=0; i<DECDPUN; i++) {
00851         if (a&b&1) *uc=*uc+(Unit)powers[i];  // effect AND
00852         j=a%10;
00853         a=a/10;
00854         j|=b%10;
00855         b=b/10;
00856         if (j>1) {
00857           decStatus(res, DEC_Invalid_operation, set);
00858           return res;
00859           }
00860         if (uc==msuc && i==msudigs-1) break; // just did final digit
00861         } // each digit
00862       } // both OK
00863     } // each unit
00864   // [here uc-1 is the msu of the result]
00865   res->digits=decGetDigits(res->lsu, uc-res->lsu);
00866   res->exponent=0;                      // integer
00867   res->bits=0;                          // sign=0
00868   return res;  // [no status to set]
00869   } // decNumberAnd

enum decClass decNumberClass | ( | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 3312 du fichier decNumber.c.

Références DEC_CLASS_NEG_INF, DEC_CLASS_NEG_NORMAL, DEC_CLASS_NEG_SUBNORMAL, DEC_CLASS_NEG_ZERO, DEC_CLASS_POS_INF, DEC_CLASS_POS_NORMAL, DEC_CLASS_POS_SUBNORMAL, DEC_CLASS_POS_ZERO, DEC_CLASS_QNAN, DEC_CLASS_SNAN, decNumberIsNegative, decNumberIsNormal(), decNumberIsQNaN, decNumberIsSNaN, decNumberIsSpecial, et decNumberIsZero.

03312                                                                    {
03313   if (decNumberIsSpecial(dn)) {
03314     if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN;
03315     if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN;
03316     // must be an infinity
03317     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF;
03318     return DEC_CLASS_POS_INF;
03319     }
03320   // is finite
03321   if (decNumberIsNormal(dn, set)) { // most common
03322     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL;
03323     return DEC_CLASS_POS_NORMAL;
03324     }
03325   // is subnormal or zero
03326   if (decNumberIsZero(dn)) {    // most common
03327     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO;
03328     return DEC_CLASS_POS_ZERO;
03329     }
03330   if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL;
03331   return DEC_CLASS_POS_SUBNORMAL;
03332   } // decNumberClass

const char* decNumberClassToString ( enum decClass )

Définition à la ligne 3340 du fichier decNumber.c.

Références DEC_CLASS_NEG_INF, DEC_CLASS_NEG_NORMAL, DEC_CLASS_NEG_SUBNORMAL, DEC_CLASS_NEG_ZERO, DEC_CLASS_POS_INF, DEC_CLASS_POS_NORMAL, DEC_CLASS_POS_SUBNORMAL, DEC_CLASS_POS_ZERO, DEC_CLASS_QNAN, DEC_CLASS_SNAN, DEC_ClassString_NI, DEC_ClassString_NN, DEC_ClassString_NS, DEC_ClassString_NZ, DEC_ClassString_PI, DEC_ClassString_PN, DEC_ClassString_PS, DEC_ClassString_PZ, DEC_ClassString_QN, DEC_ClassString_SN, et DEC_ClassString_UN.

03340                                                          {
03341   if (eclass==DEC_CLASS_POS_NORMAL)    return DEC_ClassString_PN;
03342   if (eclass==DEC_CLASS_NEG_NORMAL)    return DEC_ClassString_NN;
03343   if (eclass==DEC_CLASS_POS_ZERO)      return DEC_ClassString_PZ;
03344   if (eclass==DEC_CLASS_NEG_ZERO)      return DEC_ClassString_NZ;
03345   if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS;
03346   if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS;
03347   if (eclass==DEC_CLASS_POS_INF)       return DEC_ClassString_PI;
03348   if (eclass==DEC_CLASS_NEG_INF)       return DEC_ClassString_NI;
03349   if (eclass==DEC_CLASS_QNAN)          return DEC_ClassString_QN;
03350   if (eclass==DEC_CLASS_SNAN)          return DEC_ClassString_SN;
03351   return DEC_ClassString_UN;           // Unknown
03352   } // decNumberClassToString

decNumber* decNumberCompare | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 883 du fichier decNumber.c.

Références COMPARE, decCompareOp(), decStatus(), et uInt.

Référencé par decNumberPower(), operator<(), et operator==().

00884                                                                     {
00885   uInt status=0;                        // accumulator
00886   decCompareOp(res, lhs, rhs, set, COMPARE, &status);
00887   if (status!=0) decStatus(res, status, set);
00888   return res;
00889   } // decNumberCompare

decNumber* decNumberCompareSignal | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 903 du fichier decNumber.c.

Références COMPSIG, decCompareOp(), decStatus(), et uInt.

00904                                                                           {
00905   uInt status=0;                        // accumulator
00906   decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
00907   if (status!=0) decStatus(res, status, set);
00908   return res;
00909   } // decNumberCompareSignal

decNumber* decNumberCompareTotal | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 924 du fichier decNumber.c.

Références COMPTOTAL, decCompareOp(), decStatus(), et uInt.

00925                                                                          {
00926   uInt status=0;                        // accumulator
00927   decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
00928   if (status!=0) decStatus(res, status, set);
00929   return res;
00930   } // decNumberCompareTotal

decNumber* decNumberCompareTotalMag | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 945 du fichier decNumber.c.

Références decNumber::bits, COMPTOTAL, D2N, D2U, DEC_Insufficient_storage, DECBUFFER, decCompareOp(), DECNEG, decNumberCopy(), decNumberIsNegative, decStatus(), decNumber::digits, et uInt.

00946                                                                             {
00947   uInt status=0;                   // accumulator
00948   uInt needbytes;                  // for space calculations
00949   decNumber bufa[D2N(DECBUFFER+1)];// +1 in case DECBUFFER=0
00950   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
00951   decNumber bufb[D2N(DECBUFFER+1)];
00952   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
00953   decNumber *a, *b;                // temporary pointers
00954
00955   #if DECCHECK
00956   if (decCheckOperands(res, lhs, rhs, set)) return res;
00957   #endif
00958
00959   do {                                  // protect allocated storage
00960     // if either is negative, take a copy and absolute
00961     if (decNumberIsNegative(lhs)) {     // lhs<0
00962       a=bufa;
00963       needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit);
00964       if (needbytes>sizeof(bufa)) {     // need malloc space
00965         allocbufa=(decNumber *)malloc(needbytes);
00966         if (allocbufa==NULL) {          // hopeless -- abandon
00967           status|=DEC_Insufficient_storage;
00968           break;}
00969         a=allocbufa;                    // use the allocated space
00970         }
00971       decNumberCopy(a, lhs);            // copy content
00972       a->bits&=~DECNEG;                 // .. and clear the sign
00973       lhs=a;                            // use copy from here on
00974       }
00975     if (decNumberIsNegative(rhs)) {     // rhs<0
00976       b=bufb;
00977       needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
00978       if (needbytes>sizeof(bufb)) {     // need malloc space
00979         allocbufb=(decNumber *)malloc(needbytes);
00980         if (allocbufb==NULL) {          // hopeless -- abandon
00981           status|=DEC_Insufficient_storage;
00982           break;}
00983         b=allocbufb;                    // use the allocated space
00984         }
00985       decNumberCopy(b, rhs);            // copy content
00986       b->bits&=~DECNEG;                 // .. and clear the sign
00987       rhs=b;                            // use copy from here on
00988       }
00989     decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
00990     } while(0);                         // end protected
00991
00992   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
00993   if (allocbufb!=NULL) free(allocbufb); // ..
00994   if (status!=0) decStatus(res, status, set);
00995   return res;
00996   } // decNumberCompareTotalMag

decNumber* decNumberCopy | ( | decNumber * | ,
 |  | const decNumber * |
 | ) |  |

Définition à la ligne 3365 du fichier decNumber.c.

Références decNumber::bits, D2U, DECDPUN, decNumberZero(), decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decDivideOp(), decExpOp(), decLnOp(), decNaNs(), decNumberCompareTotalMag(), decNumberCopyAbs(), decNumberCopyNegate(), decNumberCopySign(), decNumberLog10(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToIntegralExact(), decQuantizeOp(), et DecFloat_::operator=().

03365                                                                  {
03366
03367   #if DECCHECK
03368   if (src==NULL) return decNumberZero(dest);
03369   #endif
03370
03371   if (dest==src) return dest;                // no copy required
03372
03373   // Use explicit assignments here as structure assignment could copy
03374   // more than just the lsu (for small DECDPUN).  This would not affect
03375   // the value of the results, but could disturb test harness spill
03376   // checking.
03377   dest->bits=src->bits;
03378   dest->exponent=src->exponent;
03379   dest->digits=src->digits;
03380   dest->lsu[0]=src->lsu[0];
03381   if (src->digits>DECDPUN) {                 // more Units to come
03382     const Unit *smsup, *s;                   // work
03383     Unit  *d;                                // ..
03384     // memcpy for the remaining Units would be safe as they cannot
03385     // overlap.  However, this explicit loop is faster in short cases.
03386     d=dest->lsu+1;                           // -> first destination
03387     smsup=src->lsu+D2U(src->digits);         // -> source msu+1
03388     for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
03389     }
03390   return dest;
03391   } // decNumberCopy

decNumber* decNumberCopy_ | ( | decNumber * | dst,
 |  | const decNumber * | src
 | ) |  |

Référencé par operator<(), et operator==().

decNumber* decNumberCopyAbs | ( | decNumber * | ,
 |  | const decNumber * |
 | ) |  |

Définition à la ligne 3405 du fichier decNumber.c.

Références decNumber::bits, DECNEG, et decNumberCopy().

Référencé par decNumberLogB().

03405                                                                    {
03406   #if DECCHECK
03407   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03408   #endif
03409   decNumberCopy(res, rhs);
03410   res->bits&=~DECNEG;                   // turn off sign
03411   return res;
03412   } // decNumberCopyAbs

decNumber* decNumberCopyNegate | ( | decNumber * | ,
 |  | const decNumber * |
 | ) |  |

Définition à la ligne 3426 du fichier decNumber.c.

Références decNumber::bits, DECNEG, et decNumberCopy().

03426                                                                       {
03427   #if DECCHECK
03428   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03429   #endif
03430   decNumberCopy(res, rhs);
03431   res->bits^=DECNEG;                    // invert the sign
03432   return res;
03433   } // decNumberCopyNegate

decNumber* decNumberCopySign | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * |
 | ) |  |

Définition à la ligne 3447 du fichier decNumber.c.

Références decNumber::bits, DECNEG, decNumberCopy(), et uByte.

Référencé par decNumberNextToward().

03448                                                     {
03449   uByte sign;                           // rhs sign
03450   #if DECCHECK
03451   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03452   #endif
03453   sign=rhs->bits & DECNEG;              // save sign bit
03454   decNumberCopy(res, lhs);
03455   res->bits&=~DECNEG;                   // clear the sign
03456   res->bits|=sign;                      // set from rhs
03457   return res;
03458   } // decNumberCopySign

decNumber* decNumberDivide | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1010 du fichier decNumber.c.

Références decDivideOp(), decStatus(), DIVIDE, et uInt.

Référencé par DecFloat_::operator/=().

01011                                                                    {
01012   uInt status=0;                        // accumulator
01013   decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
01014   if (status!=0) decStatus(res, status, set);
01015   #if DECCHECK
01016   decCheckInexact(res, set);
01017   #endif
01018   return res;
01019   } // decNumberDivide

decNumber* decNumberDivideInteger | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1033 du fichier decNumber.c.

Références decDivideOp(), decStatus(), DIVIDEINT, et uInt.

Référencé par DivideInteger().

01034                                                                           {
01035   uInt status=0;                        // accumulator
01036   decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
01037   if (status!=0) decStatus(res, status, set);
01038   return res;
01039   } // decNumberDivideInteger

decNumber* decNumberExp | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1066 du fichier decNumber.c.

Références decCheckMath(), decExpOp(), decStatus(), decContext::digits, decNumber::digits, et uInt.

01067                                           {
01068   uInt status=0;                        // accumulator
01069   #if DECSUBSET
01070   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01071   #endif
01072
01073   #if DECCHECK
01074   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01075   #endif
01076
01077   // Check restrictions; these restrictions ensure that if h=8 (see
01078   // decExpOp) then the result will either overflow or underflow to 0.
01079   // Other math functions restrict the input range, too, for inverses.
01080   // If not violated then carry out the operation.
01081   if (!decCheckMath(rhs, set, &status)) do { // protect allocation
01082     #if DECSUBSET
01083     if (!set->extended) {
01084       // reduce operand and set lostDigits status, as needed
01085       if (rhs->digits>set->digits) {
01086         allocrhs=decRoundOperand(rhs, set, &status);
01087         if (allocrhs==NULL) break;
01088         rhs=allocrhs;
01089         }
01090       }
01091     #endif
01092     decExpOp(res, rhs, set, &status);
01093     } while(0);                         // end protected
01094
01095   #if DECSUBSET
01096   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
01097   #endif
01098   // apply significant status
01099   if (status!=0) decStatus(res, status, set);
01100   #if DECCHECK
01101   decCheckInexact(res, set);
01102   #endif
01103   return res;
01104   } // decNumberExp

decNumber* decNumberFMA | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1122 du fichier decNumber.c.

Références D2N, D2U, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_EMAX, DEC_MIN_EMIN, DEC_sNaN, decAddOp(), DECBUFFER, decCheckMath(), decMultiplyOp(), DECNAN, decNumberIsSpecial, decNumberZero(), decStatus(), decNumber::digits, decContext::digits, decContext::emax, decContext::emin, et uInt.

01124                                           {
01125   uInt status=0;                   // accumulator
01126   decContext dcmul;                // context for the multiplication
01127   uInt needbytes;                  // for space calculations
01128   decNumber bufa[D2N(DECBUFFER*2+1)];
01129   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
01130   decNumber *acc;                  // accumulator pointer
01131   decNumber dzero;                 // work
01132
01133   #if DECCHECK
01134   if (decCheckOperands(res, lhs, rhs, set)) return res;
01135   if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;
01136   #endif
01137
01138   do {                                  // protect allocated storage
01139     #if DECSUBSET
01140     if (!set->extended) {               // [undefined if subset]
01141       status|=DEC_Invalid_operation;
01142       break;}
01143     #endif
01144     // Check math restrictions [these ensure no overflow or underflow]
01145     if ((!decNumberIsSpecial(lhs) && decCheckMath(lhs, set, &status))
01146      || (!decNumberIsSpecial(rhs) && decCheckMath(rhs, set, &status))
01147      || (!decNumberIsSpecial(fhs) && decCheckMath(fhs, set, &status))) break;
01148     // set up context for multiply
01149     dcmul=*set;
01150     dcmul.digits=lhs->digits+rhs->digits; // just enough
01151     // [The above may be an over-estimate for subset arithmetic, but that's OK]
01152     dcmul.emax=DEC_MAX_EMAX;            // effectively unbounded ..
01153     dcmul.emin=DEC_MIN_EMIN;            // [thanks to Math restrictions]
01154     // set up decNumber space to receive the result of the multiply
01155     acc=bufa;                           // may fit
01156     needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit);
01157     if (needbytes>sizeof(bufa)) {       // need malloc space
01158       allocbufa=(decNumber *)malloc(needbytes);
01159       if (allocbufa==NULL) {            // hopeless -- abandon
01160         status|=DEC_Insufficient_storage;
01161         break;}
01162       acc=allocbufa;                    // use the allocated space
01163       }
01164     // multiply with extended range and necessary precision
01165     //printf("emin=%ld\n", dcmul.emin);
01166     decMultiplyOp(acc, lhs, rhs, &dcmul, &status);
01167     // Only Invalid operation (from sNaN or Inf * 0) is possible in
01168     // status; if either is seen than ignore fhs (in case it is
01169     // another sNaN) and set acc to NaN unless we had an sNaN
01170     // [decMultiplyOp leaves that to caller]
01171     // Note sNaN has to go through addOp to shorten payload if
01172     // necessary
01173     if ((status&DEC_Invalid_operation)!=0) {
01174       if (!(status&DEC_sNaN)) {         // but be true invalid
01175         decNumberZero(res);             // acc not yet set
01176         res->bits=DECNAN;
01177         break;
01178         }
01179       decNumberZero(&dzero);            // make 0 (any non-NaN would do)
01180       fhs=&dzero;                       // use that
01181       }
01182     #if DECCHECK
01183      else { // multiply was OK
01184       if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
01185       }
01186     #endif
01187     // add the third operand and result -> res, and all is done
01188     decAddOp(res, acc, fhs, set, 0, &status);
01189     } while(0);                         // end protected
01190
01191   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
01192   if (status!=0) decStatus(res, status, set);
01193   #if DECCHECK
01194   decCheckInexact(res, set);
01195   #endif
01196   return res;
01197   } // decNumberFMA

decNumber* decNumberFromInt32 | ( | decNumber * | ,
 |  | int32_t |
 | ) |  |

decNumber* decNumberFromString | ( | decNumber * | ,
 |  | const char * | ,
 |  | decContext * |
 | ) |  |

decNumber* decNumberFromUInt32 | ( | decNumber * | ,
 |  | uint32_t |
 | ) |  |

uint8_t* decNumberGetBCD | ( | const decNumber * | ,
 |  | uint8_t * |
 | ) |  |

decNumber* decNumberInvert | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1213 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decContext::digits, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

01214                                              {
01215   const Unit *ua, *msua;                // -> operand and its msu
01216   Unit  *uc, *msuc;                     // -> result and its msu
01217   Int   msudigs;                        // digits in res msu
01218   #if DECCHECK
01219   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01220   #endif
01221
01222   if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
01223     decStatus(res, DEC_Invalid_operation, set);
01224     return res;
01225     }
01226   // operand is valid
01227   ua=rhs->lsu;                          // bottom-up
01228   uc=res->lsu;                          // ..
01229   msua=ua+D2U(rhs->digits)-1;           // -> msu of rhs
01230   msuc=uc+D2U(set->digits)-1;           // -> msu of result
01231   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
01232   for (; uc<=msuc; ua++, uc++) {        // Unit loop
01233     Unit a;                             // extract unit
01234     Int  i, j;                          // work
01235     if (ua>msua) a=0;
01236      else a=*ua;
01237     *uc=0;                              // can now write back
01238     // always need to examine all bits in rhs
01239     // This loop could be unrolled and/or use BIN2BCD tables
01240     for (i=0; i<DECDPUN; i++) {
01241       if ((~a)&1) *uc=*uc+(Unit)powers[i];   // effect INVERT
01242       j=a%10;
01243       a=a/10;
01244       if (j>1) {
01245         decStatus(res, DEC_Invalid_operation, set);
01246         return res;
01247         }
01248       if (uc==msuc && i==msudigs-1) break;   // just did final digit
01249       } // each digit
01250     } // each unit
01251   // [here uc-1 is the msu of the result]
01252   res->digits=decGetDigits(res->lsu, uc-res->lsu);
01253   res->exponent=0;                      // integer
01254   res->bits=0;                          // sign=0
01255   return res;  // [no status to set]
01256   } // decNumberInvert

int32_t decNumberIsNormal | ( | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 3529 du fichier decNumber.c.

Références decNumberIsSpecial, decNumberIsZero, decNumber::digits, decNumber::exponent, et Int.

Référencé par decNumberClass(), et decNumberNextToward().

03529                                                             {
03530   Int ae;                               // adjusted exponent
03531   #if DECCHECK
03532   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
03533   #endif
03534
03535   if (decNumberIsSpecial(dn)) return 0; // not finite
03536   if (decNumberIsZero(dn)) return 0;    // not non-zero
03537
03538   ae=dn->exponent+dn->digits-1;         // adjusted exponent
03539   if (ae<set->emin) return 0;           // is subnormal
03540   return 1;
03541   } // decNumberIsNormal

int32_t decNumberIsSubnormal | ( | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 3549 du fichier decNumber.c.

Références decNumberIsSpecial, decNumberIsZero, decNumber::digits, decNumber::exponent, et Int.

03549                                                                {
03550   Int ae;                               // adjusted exponent
03551   #if DECCHECK
03552   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
03553   #endif
03554
03555   if (decNumberIsSpecial(dn)) return 0; // not finite
03556   if (decNumberIsZero(dn)) return 0;    // not non-zero
03557
03558   ae=dn->exponent+dn->digits-1;         // adjusted exponent
03559   if (ae<set->emin) return 1;           // is subnormal
03560   return 0;
03561   } // decNumberIsSubnormal

decNumber* decNumberLn | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1286 du fichier decNumber.c.

Références DEC_Invalid_operation, decCheckMath(), decLnOp(), decStatus(), decContext::digits, decNumber::digits, ISZERO, et uInt.

01287                                          {
01288   uInt status=0;                   // accumulator
01289   #if DECSUBSET
01290   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01291   #endif
01292
01293   #if DECCHECK
01294   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01295   #endif
01296
01297   // Check restrictions; this is a math function; if not violated
01298   // then carry out the operation.
01299   if (!decCheckMath(rhs, set, &status)) do { // protect allocation
01300     #if DECSUBSET
01301     if (!set->extended) {
01302       // reduce operand and set lostDigits status, as needed
01303       if (rhs->digits>set->digits) {
01304         allocrhs=decRoundOperand(rhs, set, &status);
01305         if (allocrhs==NULL) break;
01306         rhs=allocrhs;
01307         }
01308       // special check in subset for rhs=0
01309       if (ISZERO(rhs)) {                // +/- zeros -> error
01310         status|=DEC_Invalid_operation;
01311         break;}
01312       } // extended=0
01313     #endif
01314     decLnOp(res, rhs, set, &status);
01315     } while(0);                         // end protected
01316
01317   #if DECSUBSET
01318   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
01319   #endif
01320   // apply significant status
01321   if (status!=0) decStatus(res, status, set);
01322   #if DECCHECK
01323   decCheckInexact(res, set);
01324   #endif
01325   return res;
01326   } // decNumberLn

decNumber* decNumberLog10 | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1408 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_MATH, DEC_NaNs, DEC_sNaN, DECBUFFER, decCheckMath(), decContextDefault(), decCopyFit(), decDivideOp(), decFinish, decLnOp(), DECNEG, decNumberCopy(), decNumberFromInt32(), decNumberZero(), DECSPECIAL, decStatus(), decContext::digits, decNumber::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, et uInt.

01409                                            {
01410   uInt status=0, ignore=0;         // status accumulators
01411   uInt needbytes;                  // for space calculations
01412   Int p;                           // working precision
01413   Int t;                           // digits in exponent of A
01414
01415   // buffers for a and b working decimals
01416   // (adjustment calculator, same size)
01417   decNumber bufa[D2N(DECBUFFER+2)];
01418   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
01419   decNumber *a=bufa;               // temporary a
01420   decNumber bufb[D2N(DECBUFFER+2)];
01421   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
01422   decNumber *b=bufb;               // temporary b
01423   decNumber bufw[D2N(10)];         // working 2-10 digit number
01424   decNumber *w=bufw;               // ..
01425   #if DECSUBSET
01426   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01427   #endif
01428
01429   decContext aset;                 // working context
01430
01431   #if DECCHECK
01432   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01433   #endif
01434
01435   // Check restrictions; this is a math function; if not violated
01436   // then carry out the operation.
01437   if (!decCheckMath(rhs, set, &status)) do { // protect malloc
01438     #if DECSUBSET
01439     if (!set->extended) {
01440       // reduce operand and set lostDigits status, as needed
01441       if (rhs->digits>set->digits) {
01442         allocrhs=decRoundOperand(rhs, set, &status);
01443         if (allocrhs==NULL) break;
01444         rhs=allocrhs;
01445         }
01446       // special check in subset for rhs=0
01447       if (ISZERO(rhs)) {                // +/- zeros -> error
01448         status|=DEC_Invalid_operation;
01449         break;}
01450       } // extended=0
01451     #endif
01452
01453     decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
01454
01455     // handle exact powers of 10; only check if +ve finite
01456     if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {
01457       Int residue=0;               // (no residue)
01458       uInt copystat=0;             // clean status
01459
01460       // round to a single digit...
01461       aset.digits=1;
01462       decCopyFit(w, rhs, &aset, &residue, &copystat); // copy & shorten
01463       // if exact and the digit is 1, rhs is a power of 10
01464       if (!(copystat&DEC_Inexact) && w->lsu[0]==1) {
01465         // the exponent, conveniently, is the power of 10; making
01466         // this the result needs a little care as it might not fit,
01467         // so first convert it into the working number, and then move
01468         // to res
01469         decNumberFromInt32(w, w->exponent);
01470         residue=0;
01471         decCopyFit(res, w, set, &residue, &status); // copy & round
01472         decFinish(res, set, &residue, &status);     // cleanup/set flags
01473         break;
01474         } // not a power of 10
01475       } // not a candidate for exact
01476
01477     // simplify the information-content calculation to use 'total
01478     // number of digits in a, including exponent' as compared to the
01479     // requested digits, as increasing this will only rarely cost an
01480     // iteration in ln(a) anyway
01481     t=6;                                // it can never be >6
01482
01483     // allocate space when needed...
01484     p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
01485     needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
01486     if (needbytes>sizeof(bufa)) {       // need malloc space
01487       allocbufa=(decNumber *)malloc(needbytes);
01488       if (allocbufa==NULL) {            // hopeless -- abandon
01489         status|=DEC_Insufficient_storage;
01490         break;}
01491       a=allocbufa;                      // use the allocated space
01492       }
01493     aset.digits=p;                      // as calculated
01494     aset.emax=DEC_MAX_MATH;             // usual bounds
01495     aset.emin=-DEC_MAX_MATH;            // ..
01496     aset.clamp=0;                       // and no concrete format
01497     decLnOp(a, rhs, &aset, &status);    // a=ln(rhs)
01498
01499     // skip the division if the result so far is infinite, NaN, or
01500     // zero, or there was an error; note NaN from sNaN needs copy
01501     if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
01502     if (a->bits&DECSPECIAL || ISZERO(a)) {
01503       decNumberCopy(res, a);            // [will fit]
01504       break;}
01505
01506     // for ln(10) an extra 3 digits of precision are needed
01507     p=set->digits+3;
01508     needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
01509     if (needbytes>sizeof(bufb)) {       // need malloc space
01510       allocbufb=(decNumber *)malloc(needbytes);
01511       if (allocbufb==NULL) {            // hopeless -- abandon
01512         status|=DEC_Insufficient_storage;
01513         break;}
01514       b=allocbufb;                      // use the allocated space
01515       }
01516     decNumberZero(w);                   // set up 10...
01517     #if DECDPUN==1
01518     w->lsu[1]=1; w->lsu[0]=0;           // ..
01519     #else
01520     w->lsu[0]=10;                       // ..
01521     #endif
01522     w->digits=2;                        // ..
01523
01524     aset.digits=p;
01525     decLnOp(b, w, &aset, &ignore);      // b=ln(10)
01526
01527     aset.digits=set->digits;            // for final divide
01528     decDivideOp(res, a, b, &aset, DIVIDE, &status); // into result
01529     } while(0);                         // [for break]
01530
01531   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
01532   if (allocbufb!=NULL) free(allocbufb); // ..
01533   #if DECSUBSET
01534   if (allocrhs !=NULL) free(allocrhs);  // ..
01535   #endif
01536   // apply significant status
01537   if (status!=0) decStatus(res, status, set);
01538   #if DECCHECK
01539   decCheckInexact(res, set);
01540   #endif
01541   return res;
01542   } // decNumberLog10

decNumber* decNumberLogB | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1352 du fichier decNumber.c.

Références DEC_Division_by_zero, DECINF, decNaNs(), DECNEG, decNumberCopyAbs(), decNumberFromInt32(), decNumberIsInfinite, decNumberIsNaN, decNumberIsZero, decNumberZero(), decStatus(), decNumber::digits, decNumber::exponent, Int, et uInt.

01353                                            {
01354   uInt status=0;                   // accumulator
01355
01356   #if DECCHECK
01357   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01358   #endif
01359
01360   // NaNs as usual; Infinities return +Infinity; 0->oops
01361   if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);
01362    else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs);
01363    else if (decNumberIsZero(rhs)) {
01364     decNumberZero(res);                 // prepare for Infinity
01365     res->bits=DECNEG|DECINF;            // -Infinity
01366     status|=DEC_Division_by_zero;       // as per 754
01367     }
01368    else { // finite non-zero
01369     Int ae=rhs->exponent+rhs->digits-1; // adjusted exponent
01370     decNumberFromInt32(res, ae);        // lay it out
01371     }
01372
01373   if (status!=0) decStatus(res, status, set);
01374   return res;
01375   } // decNumberLogB

decNumber* decNumberMax | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1556 du fichier decNumber.c.

Références COMPMAX, decCompareOp(), decStatus(), et uInt.

Référencé par max().

01557                                                                 {
01558   uInt status=0;                        // accumulator
01559   decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
01560   if (status!=0) decStatus(res, status, set);
01561   #if DECCHECK
01562   decCheckInexact(res, set);
01563   #endif
01564   return res;
01565   } // decNumberMax

decNumber* decNumberMaxMag | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1579 du fichier decNumber.c.

Références COMPMAXMAG, decCompareOp(), decStatus(), et uInt.

01580                                                                 {
01581   uInt status=0;                        // accumulator
01582   decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
01583   if (status!=0) decStatus(res, status, set);
01584   #if DECCHECK
01585   decCheckInexact(res, set);
01586   #endif
01587   return res;
01588   } // decNumberMaxMag

decNumber* decNumberMin | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1602 du fichier decNumber.c.

Références COMPMIN, decCompareOp(), decStatus(), et uInt.

Référencé par min().

01603                                                                 {
01604   uInt status=0;                        // accumulator
01605   decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
01606   if (status!=0) decStatus(res, status, set);
01607   #if DECCHECK
01608   decCheckInexact(res, set);
01609   #endif
01610   return res;
01611   } // decNumberMin

decNumber* decNumberMinMag | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1625 du fichier decNumber.c.

Références COMPMINMAG, decCompareOp(), decStatus(), et uInt.

01626                                                                 {
01627   uInt status=0;                        // accumulator
01628   decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
01629   if (status!=0) decStatus(res, status, set);
01630   #if DECCHECK
01631   decCheckInexact(res, set);
01632   #endif
01633   return res;
01634   } // decNumberMinMag

decNumber* decNumberMinus | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1650 du fichier decNumber.c.

Références decAddOp(), DECNEG, decNumberZero(), decStatus(), decNumber::exponent, et uInt.

Référencé par DecFloat_::operator-().

01651                                             {
01652   decNumber dzero;
01653   uInt status=0;                        // accumulator
01654
01655   #if DECCHECK
01656   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01657   #endif
01658
01659   decNumberZero(&dzero);                // make 0
01660   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
01661   decAddOp(res, &dzero, rhs, set, DECNEG, &status);
01662   if (status!=0) decStatus(res, status, set);
01663   #if DECCHECK
01664   decCheckInexact(res, set);
01665   #endif
01666   return res;
01667   } // decNumberMinus

decNumber* decNumberMultiply | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1924 du fichier decNumber.c.

Références decMultiplyOp(), decStatus(), et uInt.

Référencé par DecFloat_::operator *=().

01925                                                                      {
01926   uInt status=0;                   // accumulator
01927   decMultiplyOp(res, lhs, rhs, set, &status);
01928   if (status!=0) decStatus(res, status, set);
01929   #if DECCHECK
01930   decCheckInexact(res, set);
01931   #endif
01932   return res;
01933   } // decNumberMultiply

decNumber* decNumberNextMinus | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1680 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, DEC_MIN_EMIN, DEC_ROUND_FLOOR, DEC_sNaN, decAddOp(), DECINF, DECNEG, decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, decNumber::lsu, decContext::round, et uInt.

01681                                                 {
01682   decNumber dtiny;                           // constant
01683   decContext workset=*set;                   // work
01684   uInt status=0;                             // accumulator
01685   #if DECCHECK
01686   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01687   #endif
01688
01689   // +Infinity is the special case
01690   if ((rhs->bits&(DECINF|DECNEG))==DECINF) {
01691     decSetMaxValue(res, set);                // is +ve
01692     // there is no status to set
01693     return res;
01694     }
01695   decNumberZero(&dtiny);                     // start with 0
01696   dtiny.lsu[0]=1;                            // make number that is ..
01697   dtiny.exponent=DEC_MIN_EMIN-1;             // .. smaller than tiniest
01698   workset.round=DEC_ROUND_FLOOR;
01699   decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
01700   status&=DEC_Invalid_operation|DEC_sNaN;    // only sNaN Invalid please
01701   if (status!=0) decStatus(res, status, set);
01702   return res;
01703   } // decNumberNextMinus

decNumber* decNumberNextPlus | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1716 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, DEC_MIN_EMIN, DEC_ROUND_CEILING, DEC_sNaN, decAddOp(), DECINF, DECNEG, decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, decNumber::lsu, decContext::round, et uInt.

01717                                                {
01718   decNumber dtiny;                           // constant
01719   decContext workset=*set;                   // work
01720   uInt status=0;                             // accumulator
01721   #if DECCHECK
01722   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01723   #endif
01724
01725   // -Infinity is the special case
01726   if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
01727     decSetMaxValue(res, set);
01728     res->bits=DECNEG;                        // negative
01729     // there is no status to set
01730     return res;
01731     }
01732   decNumberZero(&dtiny);                     // start with 0
01733   dtiny.lsu[0]=1;                            // make number that is ..
01734   dtiny.exponent=DEC_MIN_EMIN-1;             // .. smaller than tiniest
01735   workset.round=DEC_ROUND_CEILING;
01736   decAddOp(res, rhs, &dtiny, &workset, 0, &status);
01737   status&=DEC_Invalid_operation|DEC_sNaN;    // only sNaN Invalid please
01738   if (status!=0) decStatus(res, status, set);
01739   return res;
01740   } // decNumberNextPlus

decNumber* decNumberNextToward | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1756 du fichier decNumber.c.

Références BADINT, decNumber::bits, DEC_Insufficient_storage, DEC_MIN_EMIN, DEC_ROUND_CEILING, DEC_ROUND_FLOOR, decAddOp(), decCompare(), DECINF, decNaNs(), DECNEG, decNumberCopySign(), decNumberIsNaN, decNumberIsNormal(), decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, Int, decNumber::lsu, decContext::round, uByte, et uInt.

01757                                                                        {
01758   decNumber dtiny;                           // constant
01759   decContext workset=*set;                   // work
01760   Int result;                                // ..
01761   uInt status=0;                             // accumulator
01762   #if DECCHECK
01763   if (decCheckOperands(res, lhs, rhs, set)) return res;
01764   #endif
01765
01766   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
01767     decNaNs(res, lhs, rhs, set, &status);
01768     }
01769    else { // Is numeric, so no chance of sNaN Invalid, etc.
01770     result=decCompare(lhs, rhs, 0);     // sign matters
01771     if (result==BADINT) status|=DEC_Insufficient_storage; // rare
01772      else { // valid compare
01773       if (result==0) decNumberCopySign(res, lhs, rhs); // easy
01774        else { // differ: need NextPlus or NextMinus
01775         uByte sub;                      // add or subtract
01776         if (result<0) {                 // lhs<rhs, do nextplus
01777           // -Infinity is the special case
01778           if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
01779             decSetMaxValue(res, set);
01780             res->bits=DECNEG;           // negative
01781             return res;                 // there is no status to set
01782             }
01783           workset.round=DEC_ROUND_CEILING;
01784           sub=0;                        // add, please
01785           } // plus
01786          else {                         // lhs>rhs, do nextminus
01787           // +Infinity is the special case
01788           if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
01789             decSetMaxValue(res, set);
01790             return res;                 // there is no status to set
01791             }
01792           workset.round=DEC_ROUND_FLOOR;
01793           sub=DECNEG;                   // subtract, please
01794           } // minus
01795         decNumberZero(&dtiny);          // start with 0
01796         dtiny.lsu[0]=1;                 // make number that is ..
01797         dtiny.exponent=DEC_MIN_EMIN-1;  // .. smaller than tiniest
01798         decAddOp(res, lhs, &dtiny, &workset, sub, &status); // + or -
01799         // turn off exceptions if the result is a normal number
01800         // (including Nmin), otherwise let all status through
01801         if (decNumberIsNormal(res, set)) status=0;
01802         } // unequal
01803       } // compare OK
01804     } // numeric
01805   if (status!=0) decStatus(res, status, set);
01806   return res;
01807   } // decNumberNextToward

decNumber* decNumberNormalize | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2326 du fichier decNumber.c.

Références decNumberReduce().

Référencé par DecFloat_::Normalize().

02327                                                 {
02328   return decNumberReduce(res, rhs, set);
02329   } // decNumberNormalize

decNumber* decNumberOr | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1824 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decContext::digits, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

01825                                                                {
01826   const Unit *ua, *ub;                  // -> operands
01827   const Unit *msua, *msub;              // -> operand msus
01828   Unit  *uc, *msuc;                     // -> result and its msu
01829   Int   msudigs;                        // digits in res msu
01830   #if DECCHECK
01831   if (decCheckOperands(res, lhs, rhs, set)) return res;
01832   #endif
01833
01834   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
01835    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
01836     decStatus(res, DEC_Invalid_operation, set);
01837     return res;
01838     }
01839   // operands are valid
01840   ua=lhs->lsu;                          // bottom-up
01841   ub=rhs->lsu;                          // ..
01842   uc=res->lsu;                          // ..
01843   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
01844   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
01845   msuc=uc+D2U(set->digits)-1;           // -> msu of result
01846   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
01847   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
01848     Unit a, b;                          // extract units
01849     if (ua>msua) a=0;
01850      else a=*ua;
01851     if (ub>msub) b=0;
01852      else b=*ub;
01853     *uc=0;                              // can now write back
01854     if (a|b) {                          // maybe 1 bits to examine
01855       Int i, j;
01856       // This loop could be unrolled and/or use BIN2BCD tables
01857       for (i=0; i<DECDPUN; i++) {
01858         if ((a|b)&1) *uc=*uc+(Unit)powers[i];     // effect OR
01859         j=a%10;
01860         a=a/10;
01861         j|=b%10;
01862         b=b/10;
01863         if (j>1) {
01864           decStatus(res, DEC_Invalid_operation, set);
01865           return res;
01866           }
01867         if (uc==msuc && i==msudigs-1) break;      // just did final digit
01868         } // each digit
01869       } // non-zero
01870     } // each unit
01871   // [here uc-1 is the msu of the result]
01872   res->digits=decGetDigits(res->lsu, uc-res->lsu);
01873   res->exponent=0;                      // integer
01874   res->bits=0;                          // sign=0
01875   return res;  // [no status to set]
01876   } // decNumberOr

decNumber* decNumberPlus | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1894 du fichier decNumber.c.

Références decAddOp(), decNumberZero(), decStatus(), decNumber::exponent, et uInt.

Référencé par DecFloat_::operator+().

01895                                            {
01896   decNumber dzero;
01897   uInt status=0;                        // accumulator
01898   #if DECCHECK
01899   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01900   #endif
01901
01902   decNumberZero(&dzero);                // make 0
01903   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
01904   decAddOp(res, &dzero, rhs, set, 0, &status);
01905   if (status!=0) decStatus(res, status, set);
01906   #if DECCHECK
01907   decCheckInexact(res, set);
01908   #endif
01909   return res;
01910   } // decNumberPlus

decNumber* decNumberPower | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 1961 du fichier decNumber.c.

Références BADINT, BIGEVEN, BIGODD, decNumber::bits, decContext::clamp, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_MATH, DEC_Overflow, DEC_ROUND_HALF_EVEN, DEC_Rounded, DEC_Subnormal, DEC_Underflow, DECBUFFER, decCheckMath(), decContextDefault(), decCopyFit(), decDivideOp(), decExpOp(), decFinalize(), decFinish, decGetInt(), DECINF, decLnOp(), decMultiplyOp(), decNaNs(), DECNEG, decNumberCompare(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decNumberIsNegative, decNumberIsZero, decNumberZero(), DECNUMMAXP, decShiftToMost(), decStatus(), decTrim(), decNumber::digits, decContext::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, MAXI, decContext::round, SPECIALARGS, uByte, et uInt.

Référencé par pow().

01962                                                                   {
01963   #if DECSUBSET
01964   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
01965   decNumber *allocrhs=NULL;        // .., rhs
01966   #endif
01967   decNumber *allocdac=NULL;        // -> allocated acc buffer, iff used
01968   decNumber *allocinv=NULL;        // -> allocated 1/x buffer, iff used
01969   Int   reqdigits=set->digits;     // requested DIGITS
01970   Int   n;                         // rhs in binary
01971   Flag  rhsint=0;                  // 1 if rhs is an integer
01972   Flag  useint=0;                  // 1 if can use integer calculation
01973   Flag  isoddint=0;                // 1 if rhs is an integer and odd
01974   Int   i;                         // work
01975   #if DECSUBSET
01976   Int   dropped;                   // ..
01977   #endif
01978   uInt  needbytes;                 // buffer size needed
01979   Flag  seenbit;                   // seen a bit while powering
01980   Int   residue=0;                 // rounding residue
01981   uInt  status=0;                  // accumulators
01982   uByte bits=0;                    // result sign if errors
01983   decContext aset;                 // working context
01984   decNumber dnOne;                 // work value 1...
01985   // local accumulator buffer [a decNumber, with digits+elength+1 digits]
01986   decNumber dacbuff[D2N(DECBUFFER+9)];
01987   decNumber *dac=dacbuff;          // -> result accumulator
01988   // same again for possible 1/lhs calculation
01989   decNumber invbuff[D2N(DECBUFFER+9)];
01990
01991   #if DECCHECK
01992   if (decCheckOperands(res, lhs, rhs, set)) return res;
01993   #endif
01994
01995   do {                             // protect allocated storage
01996     #if DECSUBSET
01997     if (!set->extended) { // reduce operands and set status, as needed
01998       if (lhs->digits>reqdigits) {
01999         alloclhs=decRoundOperand(lhs, set, &status);
02000         if (alloclhs==NULL) break;
02001         lhs=alloclhs;
02002         }
02003       if (rhs->digits>reqdigits) {
02004         allocrhs=decRoundOperand(rhs, set, &status);
02005         if (allocrhs==NULL) break;
02006         rhs=allocrhs;
02007         }
02008       }
02009     #endif
02010     // [following code does not require input rounding]
02011
02012     // handle NaNs and rhs Infinity (lhs infinity is harder)
02013     if (SPECIALARGS) {
02014       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { // NaNs
02015         decNaNs(res, lhs, rhs, set, &status);
02016         break;}
02017       if (decNumberIsInfinite(rhs)) {   // rhs Infinity
02018         Flag rhsneg=rhs->bits&DECNEG;   // save rhs sign
02019         if (decNumberIsNegative(lhs)    // lhs<0
02020          && !decNumberIsZero(lhs))      // ..
02021           status|=DEC_Invalid_operation;
02022          else {                         // lhs >=0
02023           decNumberZero(&dnOne);        // set up 1
02024           dnOne.lsu[0]=1;
02025           decNumberCompare(dac, lhs, &dnOne, set); // lhs ? 1
02026           decNumberZero(res);           // prepare for 0/1/Infinity
02027           if (decNumberIsNegative(dac)) {    // lhs<1
02028             if (rhsneg) res->bits|=DECINF;   // +Infinity [else is +0]
02029             }
02030            else if (dac->lsu[0]==0) {        // lhs=1
02031             // 1**Infinity is inexact, so return fully-padded 1.0000
02032             Int shift=set->digits-1;
02033             *res->lsu=1;                     // was 0, make int 1
02034             res->digits=decShiftToMost(res->lsu, 1, shift);
02035             res->exponent=-shift;            // make 1.0000...
02036             status|=DEC_Inexact|DEC_Rounded; // deemed inexact
02037             }
02038            else {                            // lhs>1
02039             if (!rhsneg) res->bits|=DECINF;  // +Infinity [else is +0]
02040             }
02041           } // lhs>=0
02042         break;}
02043       // [lhs infinity drops through]
02044       } // specials
02045
02046     // Original rhs may be an integer that fits and is in range
02047     n=decGetInt(rhs);
02048     if (n!=BADINT) {                    // it is an integer
02049       rhsint=1;                         // record the fact for 1**n
02050       isoddint=(Flag)n&1;               // [works even if big]
02051       if (n!=BIGEVEN && n!=BIGODD)      // can use integer path?
02052         useint=1;                       // looks good
02053       }
02054
02055     if (decNumberIsNegative(lhs)        // -x ..
02056       && isoddint) bits=DECNEG;         // .. to an odd power
02057
02058     // handle LHS infinity
02059     if (decNumberIsInfinite(lhs)) {     // [NaNs already handled]
02060       uByte rbits=rhs->bits;            // save
02061       decNumberZero(res);               // prepare
02062       if (n==0) *res->lsu=1;            // [-]Inf**0 => 1
02063        else {
02064         // -Inf**nonint -> error
02065         if (!rhsint && decNumberIsNegative(lhs)) {
02066           status|=DEC_Invalid_operation;     // -Inf**nonint is error
02067           break;}
02068         if (!(rbits & DECNEG)) bits|=DECINF; // was not a **-n
02069         // [otherwise will be 0 or -0]
02070         res->bits=bits;
02071         }
02072       break;}
02073
02074     // similarly handle LHS zero
02075     if (decNumberIsZero(lhs)) {
02076       if (n==0) {                            // 0**0 => Error
02077         #if DECSUBSET
02078         if (!set->extended) {                // [unless subset]
02079           decNumberZero(res);
02080           *res->lsu=1;                       // return 1
02081           break;}
02082         #endif
02083         status|=DEC_Invalid_operation;
02084         }
02085        else {                                // 0**x
02086         uByte rbits=rhs->bits;               // save
02087         if (rbits & DECNEG) {                // was a 0**(-n)
02088           #if DECSUBSET
02089           if (!set->extended) {              // [bad if subset]
02090             status|=DEC_Invalid_operation;
02091             break;}
02092           #endif
02093           bits|=DECINF;
02094           }
02095         decNumberZero(res);                  // prepare
02096         // [otherwise will be 0 or -0]
02097         res->bits=bits;
02098         }
02099       break;}
02100
02101     // here both lhs and rhs are finite; rhs==0 is handled in the
02102     // integer path.  Next handle the non-integer cases
02103     if (!useint) {                      // non-integral rhs
02104       // any -ve lhs is bad, as is either operand or context out of
02105       // bounds
02106       if (decNumberIsNegative(lhs)) {
02107         status|=DEC_Invalid_operation;
02108         break;}
02109       if (decCheckMath(lhs, set, &status)
02110        || decCheckMath(rhs, set, &status)) break; // variable status
02111
02112       decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
02113       aset.emax=DEC_MAX_MATH;           // usual bounds
02114       aset.emin=-DEC_MAX_MATH;          // ..
02115       aset.clamp=0;                     // and no concrete format
02116
02117       // calculate the result using exp(ln(lhs)*rhs), which can
02118       // all be done into the accumulator, dac.  The precision needed
02119       // is enough to contain the full information in the lhs (which
02120       // is the total digits, including exponent), or the requested
02121       // precision, if larger, + 4; 6 is used for the exponent
02122       // maximum length, and this is also used when it is shorter
02123       // than the requested digits as it greatly reduces the >0.5 ulp
02124       // cases at little cost (because Ln doubles digits each
02125       // iteration so a few extra digits rarely causes an extra
02126       // iteration)
02127       aset.digits=MAXI(lhs->digits, set->digits)+6+4;
02128       } // non-integer rhs
02129
02130      else { // rhs is in-range integer
02131       if (n==0) {                       // x**0 = 1
02132         // (0**0 was handled above)
02133         decNumberZero(res);             // result=1
02134         *res->lsu=1;                    // ..
02135         break;}
02136       // rhs is a non-zero integer
02137       if (n<0) n=-n;                    // use abs(n)
02138
02139       aset=*set;                        // clone the context
02140       aset.round=DEC_ROUND_HALF_EVEN;   // internally use balanced
02141       // calculate the working DIGITS
02142       aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
02143       #if DECSUBSET
02144       if (!set->extended) aset.digits--;     // use classic precision
02145       #endif
02146       // it's an error if this is more than can be handled
02147       if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}
02148       } // integer path
02149
02150     // aset.digits is the count of digits for the accumulator needed
02151     // if accumulator is too long for local storage, then allocate
02152     needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);
02153     // [needbytes also used below if 1/lhs needed]
02154     if (needbytes>sizeof(dacbuff)) {
02155       allocdac=(decNumber *)malloc(needbytes);
02156       if (allocdac==NULL) {   // hopeless -- abandon
02157         status|=DEC_Insufficient_storage;
02158         break;}
02159       dac=allocdac;           // use the allocated space
02160       }
02161     // here, aset is set up and accumulator is ready for use
02162
02163     if (!useint) {                           // non-integral rhs
02164       // x ** y; special-case x=1 here as it will otherwise always
02165       // reduce to integer 1; decLnOp has a fastpath which detects
02166       // the case of x=1
02167       decLnOp(dac, lhs, &aset, &status);     // dac=ln(lhs)
02168       // [no error possible, as lhs 0 already handled]
02169       if (ISZERO(dac)) {                     // x==1, 1.0, etc.
02170         // need to return fully-padded 1.0000 etc., but rhsint->1
02171         *dac->lsu=1;                         // was 0, make int 1
02172         if (!rhsint) {                       // add padding
02173           Int shift=set->digits-1;
02174           dac->digits=decShiftToMost(dac->lsu, 1, shift);
02175           dac->exponent=-shift;              // make 1.0000...
02176           status|=DEC_Inexact|DEC_Rounded;   // deemed inexact
02177           }
02178         }
02179        else {
02180         decMultiplyOp(dac, dac, rhs, &aset, &status);  // dac=dac*rhs
02181         decExpOp(dac, dac, &aset, &status);            // dac=exp(dac)
02182         }
02183       // and drop through for final rounding
02184       } // non-integer rhs
02185
02186      else {                             // carry on with integer
02187       decNumberZero(dac);               // acc=1
02188       *dac->lsu=1;                      // ..
02189
02190       // if a negative power the constant 1 is needed, and if not subset
02191       // invert the lhs now rather than inverting the result later
02192       if (decNumberIsNegative(rhs)) {   // was a **-n [hence digits>0]
02193         decNumber *inv=invbuff;         // asssume use fixed buffer
02194         decNumberCopy(&dnOne, dac);     // dnOne=1;  [needed now or later]
02195         #if DECSUBSET
02196         if (set->extended) {            // need to calculate 1/lhs
02197         #endif
02198           // divide lhs into 1, putting result in dac [dac=1/dac]
02199           decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);
02200           // now locate or allocate space for the inverted lhs
02201           if (needbytes>sizeof(invbuff)) {
02202             allocinv=(decNumber *)malloc(needbytes);
02203             if (allocinv==NULL) {       // hopeless -- abandon
02204               status|=DEC_Insufficient_storage;
02205               break;}
02206             inv=allocinv;               // use the allocated space
02207             }
02208           // [inv now points to big-enough buffer or allocated storage]
02209           decNumberCopy(inv, dac);      // copy the 1/lhs
02210           decNumberCopy(dac, &dnOne);   // restore acc=1
02211           lhs=inv;                      // .. and go forward with new lhs
02212         #if DECSUBSET
02213           }
02214         #endif
02215         }
02216
02217       // Raise-to-the-power loop...
02218       seenbit=0;                   // set once a 1-bit is encountered
02219       for (i=1;;i++){              // for each bit [top bit ignored]
02220         // abandon if had overflow or terminal underflow
02221         if (status & (DEC_Overflow|DEC_Underflow)) { // interesting?
02222           if (status&DEC_Overflow || ISZERO(dac)) break;
02223           }
02224         // [the following two lines revealed an optimizer bug in a C++
02225         // compiler, with symptom: 5**3 -> 25, when n=n+n was used]
02226         n=n<<1;                    // move next bit to testable position
02227         if (n<0) {                 // top bit is set
02228           seenbit=1;               // OK, significant bit seen
02229           decMultiplyOp(dac, dac, lhs, &aset, &status); // dac=dac*x
02230           }
02231         if (i==31) break;          // that was the last bit
02232         if (!seenbit) continue;    // no need to square 1
02233         decMultiplyOp(dac, dac, dac, &aset, &status); // dac=dac*dac [square]
02234         } /*i*/ // 32 bits
02235
02236       // complete internal overflow or underflow processing
02237       if (status & (DEC_Overflow|DEC_Underflow)) {
02238         #if DECSUBSET
02239         // If subset, and power was negative, reverse the kind of -erflow
02240         // [1/x not yet done]
02241         if (!set->extended && decNumberIsNegative(rhs)) {
02242           if (status & DEC_Overflow)
02243             status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;
02244            else { // trickier -- Underflow may or may not be set
02245             status&=~(DEC_Underflow | DEC_Subnormal); // [one or both]
02246             status|=DEC_Overflow;
02247             }
02248           }
02249         #endif
02250         dac->bits=(dac->bits & ~DECNEG) | bits; // force correct sign
02251         // round subnormals [to set.digits rather than aset.digits]
02252         // or set overflow result similarly as required
02253         decFinalize(dac, set, &residue, &status);
02254         decNumberCopy(res, dac);   // copy to result (is now OK length)
02255         break;
02256         }
02257
02258       #if DECSUBSET
02259       if (!set->extended &&                  // subset math
02260           decNumberIsNegative(rhs)) {        // was a **-n [hence digits>0]
02261         // so divide result into 1 [dac=1/dac]
02262         decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);
02263         }
02264       #endif
02265       } // rhs integer path
02266
02267     // reduce result to the requested length and copy to result
02268     decCopyFit(res, dac, set, &residue, &status);
02269     decFinish(res, set, &residue, &status);  // final cleanup
02270     #if DECSUBSET
02271     if (!set->extended) decTrim(res, set, 0, 1, &dropped); // trailing zeros
02272     #endif
02273     } while(0);                         // end protected
02274
02275   if (allocdac!=NULL) free(allocdac);   // drop any storage used
02276   if (allocinv!=NULL) free(allocinv);   // ..
02277   #if DECSUBSET
02278   if (alloclhs!=NULL) free(alloclhs);   // ..
02279   if (allocrhs!=NULL) free(allocrhs);   // ..
02280   #endif
02281   if (status!=0) decStatus(res, status, set);
02282   #if DECCHECK
02283   decCheckInexact(res, set);
02284   #endif
02285   return res;
02286   } // decNumberPower

decNumber* decNumberQuantize | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2306 du fichier decNumber.c.

Références decQuantizeOp(), decStatus(), et uInt.

Référencé par decNumberToIntegralExact(), et DecFloat_::Quantize().

02307                                                                      {
02308   uInt status=0;                        // accumulator
02309   decQuantizeOp(res, lhs, rhs, set, 1, &status);
02310   if (status!=0) decStatus(res, status, set);
02311   return res;
02312   } // decNumberQuantize

decNumber* decNumberReduce | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2331 du fichier decNumber.c.

Références decCopyFit(), decFinish, decNaNs(), decNumberIsNaN, decStatus(), decTrim(), decContext::digits, decNumber::digits, Int, et uInt.

Référencé par decNumberNormalize().

02332                                              {
02333   #if DECSUBSET
02334   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
02335   #endif
02336   uInt status=0;                   // as usual
02337   Int  residue=0;                  // as usual
02338   Int  dropped;                    // work
02339
02340   #if DECCHECK
02341   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
02342   #endif
02343
02344   do {                             // protect allocated storage
02345     #if DECSUBSET
02346     if (!set->extended) {
02347       // reduce operand and set lostDigits status, as needed
02348       if (rhs->digits>set->digits) {
02349         allocrhs=decRoundOperand(rhs, set, &status);
02350         if (allocrhs==NULL) break;
02351         rhs=allocrhs;
02352         }
02353       }
02354     #endif
02355     // [following code does not require input rounding]
02356
02357     // Infinities copy through; NaNs need usual treatment
02358     if (decNumberIsNaN(rhs)) {
02359       decNaNs(res, rhs, NULL, set, &status);
02360       break;
02361       }
02362
02363     // reduce result to the requested length and copy to result
02364     decCopyFit(res, rhs, set, &residue, &status); // copy & round
02365     decFinish(res, set, &residue, &status);       // cleanup/set flags
02366     decTrim(res, set, 1, 0, &dropped);            // normalize in place
02367                                                   // [may clamp]
02368     } while(0);                              // end protected
02369
02370   #if DECSUBSET
02371   if (allocrhs !=NULL) free(allocrhs);       // ..
02372   #endif
02373   if (status!=0) decStatus(res, status, set);// then report status
02374   return res;
02375   } // decNumberReduce

decNumber* decNumberRemainder | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2415 du fichier decNumber.c.

Références decDivideOp(), decStatus(), REMAINDER, et uInt.

Référencé par DecFloat_::operator%=().

02416                                                                       {
02417   uInt status=0;                        // accumulator
02418   decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
02419   if (status!=0) decStatus(res, status, set);
02420   #if DECCHECK
02421   decCheckInexact(res, set);
02422   #endif
02423   return res;
02424   } // decNumberRemainder

decNumber* decNumberRemainderNear | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2438 du fichier decNumber.c.

Références decDivideOp(), decStatus(), REMNEAR, et uInt.

Référencé par RemainderNear().

02439                                                                           {
02440   uInt status=0;                        // accumulator
02441   decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
02442   if (status!=0) decStatus(res, status, set);
02443   #if DECCHECK
02444   decCheckInexact(res, set);
02445   #endif
02446   return res;
02447   } // decNumberRemainderNear

decNumber* decNumberRescale | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2395 du fichier decNumber.c.

Références decQuantizeOp(), decStatus(), et uInt.

Référencé par DecFloat_::Rescale(), et DecFloat_::ToChar().

02396                                                                     {
02397   uInt status=0;                        // accumulator
02398   decQuantizeOp(res, lhs, rhs, set, 0, &status);
02399   if (status!=0) decStatus(res, status, set);
02400   return res;
02401   } // decNumberRescale

decNumber* decNumberRotate | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2474 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decReverse(), decShiftToLeast(), decStatus(), decContext::digits, decNumber::exponent, Int, MSUDIGITS, powers, et uInt.

02475                                                                   {
02476   uInt status=0;              // accumulator
02477   Int  rotate;                // rhs as an Int
02478
02479   #if DECCHECK
02480   if (decCheckOperands(res, lhs, rhs, set)) return res;
02481   #endif
02482
02483   // NaNs propagate as normal
02484   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02485     decNaNs(res, lhs, rhs, set, &status);
02486    // rhs must be an integer
02487    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02488     status=DEC_Invalid_operation;
02489    else { // both numeric, rhs is an integer
02490     rotate=decGetInt(rhs);                   // [cannot fail]
02491     if (rotate==BADINT                       // something bad ..
02492      || rotate==BIGODD || rotate==BIGEVEN    // .. very big ..
02493      || abs(rotate)>set->digits)             // .. or out of range
02494       status=DEC_Invalid_operation;
02495      else {                                  // rhs is OK
02496       decNumberCopy(res, lhs);
02497       // convert -ve rotate to equivalent positive rotation
02498       if (rotate<0) rotate=set->digits+rotate;
02499       if (rotate!=0 && rotate!=set->digits   // zero or full rotation
02500        && !decNumberIsInfinite(res)) {       // lhs was infinite
02501         // left-rotate to do; 0 < rotate < set->digits
02502         uInt units, shift;                   // work
02503         uInt msudigits;                      // digits in result msu
02504         Unit *msu=res->lsu+D2U(res->digits)-1;    // current msu
02505         Unit *msumax=res->lsu+D2U(set->digits)-1; // rotation msu
02506         for (msu++; msu<=msumax; msu++) *msu=0;   // ensure high units=0
02507         res->digits=set->digits;                  // now full-length
02508         msudigits=MSUDIGITS(res->digits);         // actual digits in msu
02509
02510         // rotation here is done in-place, in three steps
02511         // 1. shift all to least up to one unit to unit-align final
02512         //    lsd [any digits shifted out are rotated to the left,
02513         //    abutted to the original msd (which may require split)]
02514         //
02515         //    [if there are no whole units left to rotate, the
02516         //    rotation is now complete]
02517         //
02518         // 2. shift to least, from below the split point only, so that
02519         //    the final msd is in the right place in its Unit [any
02520         //    digits shifted out will fit exactly in the current msu,
02521         //    left aligned, no split required]
02522         //
02523         // 3. rotate all the units by reversing left part, right
02524         //    part, and then whole
02525         //
02526         // example: rotate right 8 digits (2 units + 2), DECDPUN=3.
02527         //
02528         //   start: 00a bcd efg hij klm npq
02529         //
02530         //      1a  000 0ab cde fgh|ijk lmn [pq saved]
02531         //      1b  00p qab cde fgh|ijk lmn
02532         //
02533         //      2a  00p qab cde fgh|00i jkl [mn saved]
02534         //      2b  mnp qab cde fgh|00i jkl
02535         //
02536         //      3a  fgh cde qab mnp|00i jkl
02537         //      3b  fgh cde qab mnp|jkl 00i
02538         //      3c  00i jkl mnp qab cde fgh
02539
02540         // Step 1: amount to shift is the partial right-rotate count
02541         rotate=set->digits-rotate;      // make it right-rotate
02542         units=rotate/DECDPUN;           // whole units to rotate
02543         shift=rotate%DECDPUN;           // left-over digits count
02544         if (shift>0) {                  // not an exact number of units
02545           uInt save=res->lsu[0]%powers[shift];    // save low digit(s)
02546           decShiftToLeast(res->lsu, D2U(res->digits), shift);
02547           if (shift>msudigits) {        // msumax-1 needs >0 digits
02548             uInt rem=save%powers[shift-msudigits];// split save
02549             *msumax=(Unit)(save/powers[shift-msudigits]); // and insert
02550             *(msumax-1)=*(msumax-1)
02551                        +(Unit)(rem*powers[DECDPUN-(shift-msudigits)]); // ..
02552             }
02553            else { // all fits in msumax
02554             *msumax=*msumax+(Unit)(save*powers[msudigits-shift]); // [maybe *1]
02555             }
02556           } // digits shift needed
02557
02558         // If whole units to rotate...
02559         if (units>0) {                  // some to do
02560           // Step 2: the units to touch are the whole ones in rotate,
02561           //   if any, and the shift is DECDPUN-msudigits (which may be
02562           //   0, again)
02563           shift=DECDPUN-msudigits;
02564           if (shift>0) {                // not an exact number of units
02565             uInt save=res->lsu[0]%powers[shift];  // save low digit(s)
02566             decShiftToLeast(res->lsu, units, shift);
02567             *msumax=*msumax+(Unit)(save*powers[msudigits]);
02568             } // partial shift needed
02569
02570           // Step 3: rotate the units array using triple reverse
02571           // (reversing is easy and fast)
02572           decReverse(res->lsu+units, msumax);     // left part
02573           decReverse(res->lsu, res->lsu+units-1); // right part
02574           decReverse(res->lsu, msumax);           // whole
02575           } // whole units to rotate
02576         // the rotation may have left an undetermined number of zeros
02577         // on the left, so true length needs to be calculated
02578         res->digits=decGetDigits(res->lsu, msumax-res->lsu+1);
02579         } // rotate needed
02580       } // rhs OK
02581     } // numerics
02582   if (status!=0) decStatus(res, status, set);
02583   return res;
02584   } // decNumberRotate

decNumber* decNumberSameQuantum | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * |
 | ) |  |

Définition à la ligne 2595 du fichier decNumber.c.

Références decNumberIsInfinite, decNumberIsNaN, decNumberZero(), decNumber::exponent, decNumber::lsu, et SPECIALARGS.

Référencé par DecFloat_::SameQuantum().

02596                                                        {
02597   Unit ret=0;                      // return value
02598
02599   #if DECCHECK
02600   if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;
02601   #endif
02602
02603   if (SPECIALARGS) {
02604     if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1;
02605      else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1;
02606      // [anything else with a special gives 0]
02607     }
02608    else if (lhs->exponent==rhs->exponent) ret=1;
02609
02610   decNumberZero(res);              // OK to overwrite an operand now
02611   *res->lsu=ret;
02612   return res;
02613   } // decNumberSameQuantum

decNumber* decNumberScaleB | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2630 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, DEC_Invalid_operation, decFinalize(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decStatus(), decContext::digits, decContext::emax, decNumber::exponent, Int, et uInt.

02631                                                                    {
02632   Int  reqexp;                // requested exponent change [B]
02633   uInt status=0;              // accumulator
02634   Int  residue;               // work
02635
02636   #if DECCHECK
02637   if (decCheckOperands(res, lhs, rhs, set)) return res;
02638   #endif
02639
02640   // Handle special values except lhs infinite
02641   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02642     decNaNs(res, lhs, rhs, set, &status);
02643     // rhs must be an integer
02644    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02645     status=DEC_Invalid_operation;
02646    else {
02647     // lhs is a number; rhs is a finite with q==0
02648     reqexp=decGetInt(rhs);                   // [cannot fail]
02649     if (reqexp==BADINT                       // something bad ..
02650      || reqexp==BIGODD || reqexp==BIGEVEN    // .. very big ..
02651      || abs(reqexp)>(2*(set->digits+set->emax))) // .. or out of range
02652       status=DEC_Invalid_operation;
02653      else {                                  // rhs is OK
02654       decNumberCopy(res, lhs);               // all done if infinite lhs
02655       if (!decNumberIsInfinite(res)) {       // prepare to scale
02656         res->exponent+=reqexp;               // adjust the exponent
02657         residue=0;
02658         decFinalize(res, set, &residue, &status); // .. and check
02659         } // finite LHS
02660       } // rhs OK
02661     } // rhs finite
02662   if (status!=0) decStatus(res, status, set);
02663   return res;
02664   } // decNumberScaleB

decNumber* decNumberSetBCD | ( | decNumber * | ,
 |  | const uint8_t * | ,
 |  | uint32_t |
 | ) |  |

decNumber* decNumberShift | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2687 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, D2U, DEC_Invalid_operation, decDecap(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decShiftToLeast(), decShiftToMost(), decStatus(), decContext::digits, decNumber::exponent, Int, et uInt.

02688                                                                   {
02689   uInt status=0;              // accumulator
02690   Int  shift;                 // rhs as an Int
02691
02692   #if DECCHECK
02693   if (decCheckOperands(res, lhs, rhs, set)) return res;
02694   #endif
02695
02696   // NaNs propagate as normal
02697   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02698     decNaNs(res, lhs, rhs, set, &status);
02699    // rhs must be an integer
02700    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02701     status=DEC_Invalid_operation;
02702    else { // both numeric, rhs is an integer
02703     shift=decGetInt(rhs);                    // [cannot fail]
02704     if (shift==BADINT                        // something bad ..
02705      || shift==BIGODD || shift==BIGEVEN      // .. very big ..
02706      || abs(shift)>set->digits)              // .. or out of range
02707       status=DEC_Invalid_operation;
02708      else {                                  // rhs is OK
02709       decNumberCopy(res, lhs);
02710       if (shift!=0 && !decNumberIsInfinite(res)) { // something to do
02711         if (shift>0) {                       // to left
02712           if (shift==set->digits) {          // removing all
02713             *res->lsu=0;                     // so place 0
02714             res->digits=1;                   // ..
02715             }
02716            else {                            //
02717             // first remove leading digits if necessary
02718             if (res->digits+shift>set->digits) {
02719               decDecap(res, res->digits+shift-set->digits);
02720               // that updated res->digits; may have gone to 1 (for a
02721               // single digit or for zero
02722               }
02723             if (res->digits>1 || *res->lsu)  // if non-zero..
02724               res->digits=decShiftToMost(res->lsu, res->digits, shift);
02725             } // partial left
02726           } // left
02727          else { // to right
02728           if (-shift>=res->digits) {         // discarding all
02729             *res->lsu=0;                     // so place 0
02730             res->digits=1;                   // ..
02731             }
02732            else {
02733             decShiftToLeast(res->lsu, D2U(res->digits), -shift);
02734             res->digits-=(-shift);
02735             }
02736           } // to right
02737         } // non-0 non-Inf shift
02738       } // rhs OK
02739     } // numerics
02740   if (status!=0) decStatus(res, status, set);
02741   return res;
02742   } // decNumberShift

decNumber* decNumberSquareRoot | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 2816 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, COMPARE, D2N, D2U, DEC_Clamped, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_EMAX, DEC_MIN_EMIN, DEC_Overflow, DEC_ROUND_DOWN, DEC_ROUND_HALF_EVEN, DEC_ROUND_UP, DEC_Rounded, DEC_Subnormal, DEC_Underflow, decAddOp(), DECBUFFER, decCompareOp(), decContextDefault(), decCopyFit(), decDivideOp(), decFinish, decMultiplyOp(), decNaNs(), DECNEG, decNumberCopy(), decNumberIsInfinite, decNumberIsNegative, decNumberZero(), decShiftToLeast(), decStatus(), decTrim(), decContext::digits, decNumber::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, MAXI, MINI, decContext::round, SPECIALARG, et uInt.

Référencé par sqrt().

02817                                                  {
02818   decContext workset, approxset;   // work contexts
02819   decNumber dzero;                 // used for constant zero
02820   Int  maxp;                       // largest working precision
02821   Int  workp;                      // working precision
02822   Int  residue=0;                  // rounding residue
02823   uInt status=0, ignore=0;         // status accumulators
02824   uInt rstatus;                    // ..
02825   Int  exp;                        // working exponent
02826   Int  ideal;                      // ideal (preferred) exponent
02827   Int  needbytes;                  // work
02828   Int  dropped;                    // ..
02829
02830   #if DECSUBSET
02831   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
02832   #endif
02833   // buffer for f [needs +1 in case DECBUFFER 0]
02834   decNumber buff[D2N(DECBUFFER+1)];
02835   // buffer for a [needs +2 to match likely maxp]
02836   decNumber bufa[D2N(DECBUFFER+2)];
02837   // buffer for temporary, b [must be same size as a]
02838   decNumber bufb[D2N(DECBUFFER+2)];
02839   decNumber *allocbuff=NULL;       // -> allocated buff, iff allocated
02840   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
02841   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
02842   decNumber *f=buff;               // reduced fraction
02843   decNumber *a=bufa;               // approximation to result
02844   decNumber *b=bufb;               // intermediate result
02845   // buffer for temporary variable, up to 3 digits
02846   decNumber buft[D2N(3)];
02847   decNumber *t=buft;               // up-to-3-digit constant or work
02848
02849   #if DECCHECK
02850   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
02851   #endif
02852
02853   do {                             // protect allocated storage
02854     #if DECSUBSET
02855     if (!set->extended) {
02856       // reduce operand and set lostDigits status, as needed
02857       if (rhs->digits>set->digits) {
02858         allocrhs=decRoundOperand(rhs, set, &status);
02859         if (allocrhs==NULL) break;
02860         // [Note: 'f' allocation below could reuse this buffer if
02861         // used, but as this is rare they are kept separate for clarity.]
02862         rhs=allocrhs;
02863         }
02864       }
02865     #endif
02866     // [following code does not require input rounding]
02867
02868     // handle infinities and NaNs
02869     if (SPECIALARG) {
02870       if (decNumberIsInfinite(rhs)) {         // an infinity
02871         if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
02872          else decNumberCopy(res, rhs);        // +Infinity
02873         }
02874        else decNaNs(res, rhs, NULL, set, &status); // a NaN
02875       break;
02876       }
02877
02878     // calculate the ideal (preferred) exponent [floor(exp/2)]
02879     // [It would be nicer to write: ideal=rhs->exponent>>1, but this
02880     // generates a compiler warning.  Generated code is the same.]
02881     ideal=(rhs->exponent&~1)/2;         // target
02882
02883     // handle zeros
02884     if (ISZERO(rhs)) {
02885       decNumberCopy(res, rhs);          // could be 0 or -0
02886       res->exponent=ideal;              // use the ideal [safe]
02887       // use decFinish to clamp any out-of-range exponent, etc.
02888       decFinish(res, set, &residue, &status);
02889       break;
02890       }
02891
02892     // any other -x is an oops
02893     if (decNumberIsNegative(rhs)) {
02894       status|=DEC_Invalid_operation;
02895       break;
02896       }
02897
02898     // space is needed for three working variables
02899     //   f -- the same precision as the RHS, reduced to 0.01->0.99...
02900     //   a -- Hull's approximation -- precision, when assigned, is
02901     //        currentprecision+1 or the input argument precision,
02902     //        whichever is larger (+2 for use as temporary)
02903     //   b -- intermediate temporary result (same size as a)
02904     // if any is too long for local storage, then allocate
02905     workp=MAXI(set->digits+1, rhs->digits);  // actual rounding precision
02906     workp=MAXI(workp, 7);                    // at least 7 for low cases
02907     maxp=workp+2;                            // largest working precision
02908
02909     needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
02910     if (needbytes>(Int)sizeof(buff)) {
02911       allocbuff=(decNumber *)malloc(needbytes);
02912       if (allocbuff==NULL) {  // hopeless -- abandon
02913         status|=DEC_Insufficient_storage;
02914         break;}
02915       f=allocbuff;            // use the allocated space
02916       }
02917     // a and b both need to be able to hold a maxp-length number
02918     needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
02919     if (needbytes>(Int)sizeof(bufa)) {            // [same applies to b]
02920       allocbufa=(decNumber *)malloc(needbytes);
02921       allocbufb=(decNumber *)malloc(needbytes);
02922       if (allocbufa==NULL || allocbufb==NULL) {   // hopeless
02923         status|=DEC_Insufficient_storage;
02924         break;}
02925       a=allocbufa;            // use the allocated spaces
02926       b=allocbufb;            // ..
02927       }
02928
02929     // copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1
02930     decNumberCopy(f, rhs);
02931     exp=f->exponent+f->digits;               // adjusted to Hull rules
02932     f->exponent=-(f->digits);                // to range
02933
02934     // set up working context
02935     decContextDefault(&workset, DEC_INIT_DECIMAL64);
02936     workset.emax=DEC_MAX_EMAX;
02937     workset.emin=DEC_MIN_EMIN;
02938
02939     // [Until further notice, no error is possible and status bits
02940     // (Rounded, etc.) should be ignored, not accumulated.]
02941
02942     // Calculate initial approximation, and allow for odd exponent
02943     workset.digits=workp;                    // p for initial calculation
02944     t->bits=0; t->digits=3;
02945     a->bits=0; a->digits=3;
02946     if ((exp & 1)==0) {                      // even exponent
02947       // Set t=0.259, a=0.819
02948       t->exponent=-3;
02949       a->exponent=-3;
02950       #if DECDPUN>=3
02951         t->lsu[0]=259;
02952         a->lsu[0]=819;
02953       #elif DECDPUN==2
02954         t->lsu[0]=59; t->lsu[1]=2;
02955         a->lsu[0]=19; a->lsu[1]=8;
02956       #else
02957         t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
02958         a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
02959       #endif
02960       }
02961      else {                                  // odd exponent
02962       // Set t=0.0819, a=2.59
02963       f->exponent--;                         // f=f/10
02964       exp++;                                 // e=e+1
02965       t->exponent=-4;
02966       a->exponent=-2;
02967       #if DECDPUN>=3
02968         t->lsu[0]=819;
02969         a->lsu[0]=259;
02970       #elif DECDPUN==2
02971         t->lsu[0]=19; t->lsu[1]=8;
02972         a->lsu[0]=59; a->lsu[1]=2;
02973       #else
02974         t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
02975         a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
02976       #endif
02977       }
02978
02979     decMultiplyOp(a, a, f, &workset, &ignore);    // a=a*f
02980     decAddOp(a, a, t, &workset, 0, &ignore);      // ..+t
02981     // [a is now the initial approximation for sqrt(f), calculated with
02982     // currentprecision, which is also a's precision.]
02983
02984     // the main calculation loop
02985     decNumberZero(&dzero);                   // make 0
02986     decNumberZero(t);                        // set t = 0.5
02987     t->lsu[0]=5;                             // ..
02988     t->exponent=-1;                          // ..
02989     workset.digits=3;                        // initial p
02990     for (; workset.digits<maxp;) {
02991       // set p to min(2*p - 2, maxp)  [hence 3; or: 4, 6, 10, ... , maxp]
02992       workset.digits=MINI(workset.digits*2-2, maxp);
02993       // a = 0.5 * (a + f/a)
02994       // [calculated at p then rounded to currentprecision]
02995       decDivideOp(b, f, a, &workset, DIVIDE, &ignore); // b=f/a
02996       decAddOp(b, b, a, &workset, 0, &ignore);         // b=b+a
02997       decMultiplyOp(a, b, t, &workset, &ignore);       // a=b*0.5
02998       } // loop
02999
03000     // Here, 0.1 <= a < 1 [Hull], and a has maxp digits
03001     // now reduce to length, etc.; this needs to be done with a
03002     // having the correct exponent so as to handle subnormals
03003     // correctly
03004     approxset=*set;                          // get emin, emax, etc.
03005     approxset.round=DEC_ROUND_HALF_EVEN;
03006     a->exponent+=exp/2;                      // set correct exponent
03007     rstatus=0;                               // clear status
03008     residue=0;                               // .. and accumulator
03009     decCopyFit(a, a, &approxset, &residue, &rstatus);  // reduce (if needed)
03010     decFinish(a, &approxset, &residue, &rstatus);      // clean and finalize
03011
03012     // Overflow was possible if the input exponent was out-of-range,
03013     // in which case quit
03014     if (rstatus&DEC_Overflow) {
03015       status=rstatus;                        // use the status as-is
03016       decNumberCopy(res, a);                 // copy to result
03017       break;
03018       }
03019
03020     // Preserve status except Inexact/Rounded
03021     status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));
03022
03023     // Carry out the Hull correction
03024     a->exponent-=exp/2;                      // back to 0.1->1
03025
03026     // a is now at final precision and within 1 ulp of the properly
03027     // rounded square root of f; to ensure proper rounding, compare
03028     // squares of (a - l/2 ulp) and (a + l/2 ulp) with f.
03029     // Here workset.digits=maxp and t=0.5, and a->digits determines
03030     // the ulp
03031     workset.digits--;                             // maxp-1 is OK now
03032     t->exponent=-a->digits-1;                     // make 0.5 ulp
03033     decAddOp(b, a, t, &workset, DECNEG, &ignore); // b = a - 0.5 ulp
03034     workset.round=DEC_ROUND_UP;
03035     decMultiplyOp(b, b, b, &workset, &ignore);    // b = mulru(b, b)
03036     decCompareOp(b, f, b, &workset, COMPARE, &ignore); // b ? f, reversed
03037     if (decNumberIsNegative(b)) {                 // f < b [i.e., b > f]
03038       // this is the more common adjustment, though both are rare
03039       t->exponent++;                              // make 1.0 ulp
03040       t->lsu[0]=1;                                // ..
03041       decAddOp(a, a, t, &workset, DECNEG, &ignore); // a = a - 1 ulp
03042       // assign to approx [round to length]
03043       approxset.emin-=exp/2;                      // adjust to match a
03044       approxset.emax-=exp/2;
03045       decAddOp(a, &dzero, a, &approxset, 0, &ignore);
03046       }
03047      else {
03048       decAddOp(b, a, t, &workset, 0, &ignore);    // b = a + 0.5 ulp
03049       workset.round=DEC_ROUND_DOWN;
03050       decMultiplyOp(b, b, b, &workset, &ignore);  // b = mulrd(b, b)
03051       decCompareOp(b, b, f, &workset, COMPARE, &ignore);   // b ? f
03052       if (decNumberIsNegative(b)) {               // b < f
03053         t->exponent++;                            // make 1.0 ulp
03054         t->lsu[0]=1;                              // ..
03055         decAddOp(a, a, t, &workset, 0, &ignore);  // a = a + 1 ulp
03056         // assign to approx [round to length]
03057         approxset.emin-=exp/2;                    // adjust to match a
03058         approxset.emax-=exp/2;
03059         decAddOp(a, &dzero, a, &approxset, 0, &ignore);
03060         }
03061       }
03062     // [no errors are possible in the above, and rounding/inexact during
03063     // estimation are irrelevant, so status was not accumulated]
03064
03065     // Here, 0.1 <= a < 1  (still), so adjust back
03066     a->exponent+=exp/2;                      // set correct exponent
03067
03068     // count droppable zeros [after any subnormal rounding] by
03069     // trimming a copy
03070     decNumberCopy(b, a);
03071     decTrim(b, set, 1, 1, &dropped);         // [drops trailing zeros]
03072
03073     // Set Inexact and Rounded.  The answer can only be exact if
03074     // it is short enough so that squaring it could fit in workp
03075     // digits, so this is the only (relatively rare) condition that
03076     // a careful check is needed
03077     if (b->digits*2-1 > workp) {             // cannot fit
03078       status|=DEC_Inexact|DEC_Rounded;
03079       }
03080      else {                                  // could be exact/unrounded
03081       uInt mstatus=0;                        // local status
03082       decMultiplyOp(b, b, b, &workset, &mstatus); // try the multiply
03083       if (mstatus&DEC_Overflow) {            // result just won't fit
03084         status|=DEC_Inexact|DEC_Rounded;
03085         }
03086        else {                                // plausible
03087         decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); // b ? rhs
03088         if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; // not equal
03089          else {                              // is Exact
03090           // here, dropped is the count of trailing zeros in 'a'
03091           // use closest exponent to ideal...
03092           Int todrop=ideal-a->exponent;      // most that can be dropped
03093           if (todrop<0) status|=DEC_Rounded; // ideally would add 0s
03094            else {                            // unrounded
03095             // there are some to drop, but emax may not allow all
03096             Int maxexp=set->emax-set->digits+1;
03097             Int maxdrop=maxexp-a->exponent;
03098             if (todrop>maxdrop && set->clamp) { // apply clamping
03099               todrop=maxdrop;
03100               status|=DEC_Clamped;
03101               }
03102             if (dropped<todrop) {            // clamp to those available
03103               todrop=dropped;
03104               status|=DEC_Clamped;
03105               }
03106             if (todrop>0) {                  // have some to drop
03107               decShiftToLeast(a->lsu, D2U(a->digits), todrop);
03108               a->exponent+=todrop;           // maintain numerical value
03109               a->digits-=todrop;             // new length
03110               }
03111             }
03112           }
03113         }
03114       }
03115
03116     // double-check Underflow, as perhaps the result could not have
03117     // been subnormal (initial argument too big), or it is now Exact
03118     if (status&DEC_Underflow) {
03119       Int ae=rhs->exponent+rhs->digits-1;    // adjusted exponent
03120       // check if truly subnormal
03121       #if DECEXTFLAG                         // DEC_Subnormal too
03122         if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow);
03123       #else
03124         if (ae>=set->emin*2) status&=~DEC_Underflow;
03125       #endif
03126       // check if truly inexact
03127       if (!(status&DEC_Inexact)) status&=~DEC_Underflow;
03128       }
03129
03130     decNumberCopy(res, a);                   // a is now the result
03131     } while(0);                              // end protected
03132
03133   if (allocbuff!=NULL) free(allocbuff);      // drop any storage used
03134   if (allocbufa!=NULL) free(allocbufa);      // ..
03135   if (allocbufb!=NULL) free(allocbufb);      // ..
03136   #if DECSUBSET
03137   if (allocrhs !=NULL) free(allocrhs);       // ..
03138   #endif
03139   if (status!=0) decStatus(res, status, set);// then report status
03140   #if DECCHECK
03141   decCheckInexact(res, set);
03142   #endif
03143   return res;
03144   } // decNumberSquareRoot

decNumber* decNumberSubtract | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 3158 du fichier decNumber.c.

Références decAddOp(), DECNEG, decStatus(), et uInt.

Référencé par DecFloat_::operator-=().

03159                                                                      {
03160   uInt status=0;                        // accumulator
03161
03162   decAddOp(res, lhs, rhs, set, DECNEG, &status);
03163   if (status!=0) decStatus(res, status, set);
03164   #if DECCHECK
03165   decCheckInexact(res, set);
03166   #endif
03167   return res;
03168   } // decNumberSubtract

char* decNumberToEngString | ( | const decNumber * | ,
 |  | char * |
 | ) |  |

Définition à la ligne 455 du fichier decNumber.c.

Références decToString().

Référencé par DecFloat_::ToChar(), et DecFloat_::ToStr().

00455                                                               {
00456   decToString(dn, string, 1);
00457   return string;
00458   } // DecNumberToEngString

int32_t decNumberToInt32 | ( | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 371 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, decContextSetStatus(), DECDPUN, DECNEG, DECSPECIAL, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, powers, uInt, Unit, et X10.

00371                                                            {
00372   #if DECCHECK
00373   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
00374   #endif
00375
00376   // special or too many digits, or bad exponent
00377   if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; // bad
00378    else { // is a finite integer with 10 or fewer digits
00379     Int d;                         // work
00380     const Unit *up;                // ..
00381     uInt hi=0, lo;                 // ..
00382     up=dn->lsu;                    // -> lsu
00383     lo=*up;                        // get 1 to 9 digits
00384     #if DECDPUN>1                  // split to higher
00385       hi=lo/10;
00386       lo=lo%10;
00387     #endif
00388     up++;
00389     // collect remaining Units, if any, into hi
00390     for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
00391     // now low has the lsd, hi the remainder
00392     if (hi>214748364 || (hi==214748364 && lo>7)) { // out of range?
00393       // most-negative is a reprieve
00394       if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000;
00395       // bad -- drop through
00396       }
00397      else { // in-range always
00398       Int i=X10(hi)+lo;
00399       if (dn->bits&DECNEG) return -i;
00400       return i;
00401       }
00402     } // integer
00403   decContextSetStatus(set, DEC_Invalid_operation); // [may not return]
00404   return 0;
00405   } // decNumberToInt32

decNumber* decNumberToIntegralExact | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 3191 du fichier decNumber.c.

Références decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberQuantize(), decNumberZero(), decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, SPECIALARG, decContext::status, decContext::traps, et uInt.

Référencé par decNumberToIntegralValue().

03192                                                       {
03193   decNumber dn;
03194   decContext workset;              // working context
03195   uInt status=0;                   // accumulator
03196
03197   #if DECCHECK
03198   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
03199   #endif
03200
03201   // handle infinities and NaNs
03202   if (SPECIALARG) {
03203     if (decNumberIsInfinite(rhs)) decNumberCopy(res, rhs); // an Infinity
03204      else decNaNs(res, rhs, NULL, set, &status); // a NaN
03205     }
03206    else { // finite
03207     // have a finite number; no error possible (res must be big enough)
03208     if (rhs->exponent>=0) return decNumberCopy(res, rhs);
03209     // that was easy, but if negative exponent there is work to do...
03210     workset=*set;                  // clone rounding, etc.
03211     workset.digits=rhs->digits;    // no length rounding
03212     workset.traps=0;               // no traps
03213     decNumberZero(&dn);            // make a number with exponent 0
03214     decNumberQuantize(res, rhs, &dn, &workset);
03215     status|=workset.status;
03216     }
03217   if (status!=0) decStatus(res, status, set);
03218   return res;
03219   } // decNumberToIntegralExact

decNumber* decNumberToIntegralValue | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 3221 du fichier decNumber.c.

Références DEC_Invalid_operation, decNumberToIntegralExact(), decContext::status, et decContext::traps.

Référencé par DecFloat_::ToIntegralValue().

03222                                                       {
03223   decContext workset=*set;         // working context
03224   workset.traps=0;                 // no traps
03225   decNumberToIntegralExact(res, rhs, &workset);
03226   // this never affects set, except for sNaNs; NaN will have been set
03227   // or propagated already, so no need to call decStatus
03228   set->status|=workset.status&DEC_Invalid_operation;
03229   return res;
03230   } // decNumberToIntegralValue

char* decNumberToString | ( | const decNumber * | ,
 |  | char * |
 | ) |  |

Définition à la ligne 450 du fichier decNumber.c.

Références decToString().

00450                                                            {
00451   decToString(dn, string, 0);
00452   return string;
00453   } // DecNumberToString

uint32_t decNumberToUInt32 | ( | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 407 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, decContextSetStatus(), DECDPUN, DECNEG, DECSPECIAL, decNumber::digits, decNumber::exponent, Int, ISZERO, decNumber::lsu, powers, uInt, Unit, et X10.

00407                                                              {
00408   #if DECCHECK
00409   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
00410   #endif
00411   // special or too many digits, or bad exponent, or negative (<0)
00412   if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0
00413     || (dn->bits&DECNEG && !ISZERO(dn)));                   // bad
00414    else { // is a finite integer with 10 or fewer digits
00415     Int d;                         // work
00416     const Unit *up;                // ..
00417     uInt hi=0, lo;                 // ..
00418     up=dn->lsu;                    // -> lsu
00419     lo=*up;                        // get 1 to 9 digits
00420     #if DECDPUN>1                  // split to higher
00421       hi=lo/10;
00422       lo=lo%10;
00423     #endif
00424     up++;
00425     // collect remaining Units, if any, into hi
00426     for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
00427
00428     // now low has the lsd, hi the remainder
00429     if (hi>429496729 || (hi==429496729 && lo>5)) ; // no reprieve possible
00430      else return X10(hi)+lo;
00431     } // integer
00432   decContextSetStatus(set, DEC_Invalid_operation); // [may not return]
00433   return 0;
00434   } // decNumberToUInt32

decNumber* decNumberTrim ( decNumber * )

Définition à la ligne 3573 du fichier decNumber.c.

Références DEC_INIT_BASE, decContextDefault(), decTrim(), et Int.

Référencé par DecFloat_::Trim().

03573                                          {
03574   Int  dropped;                    // work
03575   decContext set;                  // ..
03576   #if DECCHECK
03577   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
03578   #endif
03579   decContextDefault(&set, DEC_INIT_BASE);    // clamp=0
03580   return decTrim(dn, &set, 0, 1, &dropped);
03581   } // decNumberTrim

const char* decNumberVersion ( void )

Définition à la ligne 3588 du fichier decNumber.c.

Références DECVERSION.

03588                                     {
03589   return DECVERSION;
03590   } // decNumberVersion

decNumber* decNumberXor | ( | decNumber * | ,
 |  | const decNumber * | ,
 |  | const decNumber * | ,
 |  | decContext * |
 | ) |  |

Définition à la ligne 3247 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decContext::digits, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

03248                                                                 {
03249   const Unit *ua, *ub;                  // -> operands
03250   const Unit *msua, *msub;              // -> operand msus
03251   Unit  *uc, *msuc;                     // -> result and its msu
03252   Int   msudigs;                        // digits in res msu
03253   #if DECCHECK
03254   if (decCheckOperands(res, lhs, rhs, set)) return res;
03255   #endif
03256
03257   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
03258    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
03259     decStatus(res, DEC_Invalid_operation, set);
03260     return res;
03261     }
03262   // operands are valid
03263   ua=lhs->lsu;                          // bottom-up
03264   ub=rhs->lsu;                          // ..
03265   uc=res->lsu;                          // ..
03266   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
03267   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
03268   msuc=uc+D2U(set->digits)-1;           // -> msu of result
03269   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
03270   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
03271     Unit a, b;                          // extract units
03272     if (ua>msua) a=0;
03273      else a=*ua;
03274     if (ub>msub) b=0;
03275      else b=*ub;
03276     *uc=0;                              // can now write back
03277     if (a|b) {                          // maybe 1 bits to examine
03278       Int i, j;
03279       // This loop could be unrolled and/or use BIN2BCD tables
03280       for (i=0; i<DECDPUN; i++) {
03281         if ((a^b)&1) *uc=*uc+(Unit)powers[i];     // effect XOR
03282         j=a%10;
03283         a=a/10;
03284         j|=b%10;
03285         b=b/10;
03286         if (j>1) {
03287           decStatus(res, DEC_Invalid_operation, set);
03288           return res;
03289           }
03290         if (uc==msuc && i==msudigs-1) break;      // just did final digit
03291         } // each digit
03292       } // non-zero
03293     } // each unit
03294   // [here uc-1 is the msu of the result]
03295   res->digits=decGetDigits(res->lsu, uc-res->lsu);
03296   res->exponent=0;                      // integer
03297   res->bits=0;                          // sign=0
03298   return res;  // [no status to set]
03299   } // decNumberXor

decNumber* decNumberZero ( decNumber * )

Définition à la ligne 3601 du fichier decNumber.c.

Références decNumber::bits, decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decFinalize(), DecFloat_::DecFloat_(), decLnOp(), decMultiplyOp(), decNumberAbs(), decNumberCopy(), decNumberFMA(), decNumberFromString(), decNumberFromUInt32(), decNumberLog10(), decNumberLogB(), decNumberMinus(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPlus(), decNumberPower(), decNumberSameQuantum(), decNumberSquareRoot(), decNumberToIntegralExact(), decSetOverflow(), decSetSubnormal(), et decStatus().

03601                                          {
03602
03603   #if DECCHECK
03604   if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
03605   #endif
03606
03607   dn->bits=0;
03608   dn->exponent=0;
03609   dn->digits=1;
03610   dn->lsu[0]=0;
03611   return dn;
03612   } // decNumberZero


Decimal: Fichier source de P:/wx_LIB/Dcml/decNumber.h

P:/wx_LIB/Dcml/decNumber.h

Aller à la documentation de ce fichier.
00001 /* ------------------------------------------------------------------ */
00002 /* Decimal Number arithmetic module header                            */
00003 /* ------------------------------------------------------------------ */
00004 /* Copyright (c) IBM Corporation, 2000, 2008.  All rights reserved.   */
00005 /*                                                                    */
00006 /* This software is made available under the terms of the IBM         */
00007 /* alphaWorks License Agreement (distributed with this software as    */
00008 /* alphaWorks-License.txt).  Your use of this software indicates      */
00009 /* your acceptance of the terms and conditions of that Agreement.     */
00010 /*                                                                    */
00011 /* The description and User's Guide ("The decNumber C Library") for   */
00012 /* this software is called decNumber.pdf.  This document is           */
00013 /* available, together with arithmetic and format specifications,     */
00014 /* testcases, and Web links, on the General Decimal Arithmetic page.  */
00015 /*                                                                    */
00016 /* Please send comments, suggestions, and corrections to the author:  */
00017 /*   mfc@uk.ibm.com                                                   */
00018 /*   Mike Cowlishaw, IBM Fellow                                       */
00019 /*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
00020 /* ------------------------------------------------------------------ */
00021
00022 #if !defined(DECNUMBER)
00023   #define DECNUMBER
00024   #define DECNAME     "decNumber"                       /* Short name */
00025   #define DECFULLNAME "Decimal Number Module"         /* Verbose name */
00026   #define DECAUTHOR   "Mike Cowlishaw"                /* Who to blame */
00027
00028   #if !defined(DECCONTEXT)
00029     #include "decContext.h"
00030   #endif
00031
00032   /* Bit settings for decNumber.bits                                  */
00033   #define DECNEG    0x80      /* Sign; 1=negative, 0=positive or zero */
00034   #define DECINF    0x40      /* 1=Infinity                           */
00035   #define DECNAN    0x20      /* 1=NaN                                */
00036   #define DECSNAN   0x10      /* 1=sNaN                               */
00037   /* The remaining bits are reserved; they must be 0                  */
00038   #define DECSPECIAL (DECINF|DECNAN|DECSNAN) /* any special value     */
00039
00040   /* Define the decNumber data structure.  The size and shape of the  */
00041   /* units array in the structure is determined by the following      */
00042   /* constant.  This must not be changed without recompiling the      */
00043   /* decNumber library modules. */
00044
00045   #define DECDPUN 3           /* DECimal Digits Per UNit [must be >0  */
00046                               /* and <10; 3 or powers of 2 are best]. */
00047
00048   /* DECNUMDIGITS is the default number of digits that can be held in */
00049   /* the structure.  If undefined, 1 is assumed and it is assumed     */
00050   /* that the structure will be immediately followed by extra space,  */
00051   /* as required.  DECNUMDIGITS is always >0.                         */
00052   #if !defined(DECNUMDIGITS)
00053     #define DECNUMDIGITS 1
00054   #endif
00055
00056   /* The size (integer data type) of each unit is determined by the   */
00057   /* number of digits it will hold.                                   */
00058   #if   DECDPUN<=2
00059     #define decNumberUnit uint8_t
00060   #elif DECDPUN<=4
00061     #define decNumberUnit uint16_t
00062   #else
00063     #define decNumberUnit uint32_t
00064   #endif
00065   /* The number of units needed is ceil(DECNUMDIGITS/DECDPUN)         */
00066   #define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)
00067
00068   /* The data structure... */
00069   typedef struct {
00070     int32_t digits;      /* Count of digits in the coefficient; >0    */
00071     int32_t exponent;    /* Unadjusted exponent, unbiased, in         */
00072                          /* range: -1999999997 through 999999999      */
00073     uint8_t bits;        /* Indicator bits (see above)                */
00074                          /* Coefficient, from least significant unit  */
00075     decNumberUnit lsu[DECNUMUNITS];
00076     } decNumber;
00077
00078   /* Notes:                                                           */
00079   /* 1. If digits is > DECDPUN then there will one or more            */
00080   /*    decNumberUnits immediately following the first element of lsu.*/
00081   /*    These contain the remaining (more significant) digits of the  */
00082   /*    number, and may be in the lsu array, or may be guaranteed by  */
00083   /*    some other mechanism (such as being contained in another      */
00084   /*    structure, or being overlaid on dynamically allocated         */
00085   /*    storage).                                                     */
00086   /*                                                                  */
00087   /*    Each integer of the coefficient (except potentially the last) */
00088   /*    contains DECDPUN digits (e.g., a value in the range 0 through */
00089   /*    99999999 if DECDPUN is 8, or 0 through 999 if DECDPUN is 3).  */
00090   /*                                                                  */
00091   /* 2. A decNumber converted to a string may need up to digits+14    */
00092   /*    characters.  The worst cases (non-exponential and exponential */
00093   /*    formats) are -0.00000{9...}# and -9.{9...}E+999999999#        */
00094   /*    (where # is '\0')                                             */
00095
00096
00097   /* ---------------------------------------------------------------- */
00098   /* decNumber public functions and macros                            */
00099   /* ---------------------------------------------------------------- */
00100   /* Conversions                                                      */
00101   decNumber * decNumberFromInt32(decNumber *, int32_t);
00102   decNumber * decNumberFromUInt32(decNumber *, uint32_t);
00103   decNumber * decNumberFromString(decNumber *, const char *, decContext *);
00104   char      * decNumberToString(const decNumber *, char *);
00105   char      * decNumberToEngString(const decNumber *, char *);
00106   uint32_t    decNumberToUInt32(const decNumber *, decContext *);
00107   int32_t     decNumberToInt32(const decNumber *, decContext *);
00108   uint8_t   * decNumberGetBCD(const decNumber *, uint8_t *);
00109   decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
00110
00111   /* Operators and elementary functions                               */
00112   decNumber * decNumberAbs(decNumber *, const decNumber *, decContext *);
00113   decNumber * decNumberAdd(decNumber *, const decNumber *, const decNumber *, decContext *);
00114   decNumber * decNumberAnd(decNumber *, const decNumber *, const decNumber *, decContext *);
00115   decNumber * decNumberCompare(decNumber *, const decNumber *, const decNumber *, decContext *);
00116   decNumber * decNumberCompareSignal(decNumber *, const decNumber *, const decNumber *, decContext *);
00117   decNumber * decNumberCompareTotal(decNumber *, const decNumber *, const decNumber *, decContext *);
00118   decNumber * decNumberCompareTotalMag(decNumber *, const decNumber *, const decNumber *, decContext *);
00119   decNumber * decNumberDivide(decNumber *, const decNumber *, const decNumber *, decContext *);
00120   decNumber * decNumberDivideInteger(decNumber *, const decNumber *, const decNumber *, decContext *);
00121   decNumber * decNumberExp(decNumber *, const decNumber *, decContext *);
00122   decNumber * decNumberFMA(decNumber *, const decNumber *, const decNumber *, const decNumber *, decContext *);
00123   decNumber * decNumberInvert(decNumber *, const decNumber *, decContext *);
00124   decNumber * decNumberLn(decNumber *, const decNumber *, decContext *);
00125   decNumber * decNumberLogB(decNumber *, const decNumber *, decContext *);
00126   decNumber * decNumberLog10(decNumber *, const decNumber *, decContext *);
00127   decNumber * decNumberMax(decNumber *, const decNumber *, const decNumber *, decContext *);
00128   decNumber * decNumberMaxMag(decNumber *, const decNumber *, const decNumber *, decContext *);
00129   decNumber * decNumberMin(decNumber *, const decNumber *, const decNumber *, decContext *);
00130   decNumber * decNumberMinMag(decNumber *, const decNumber *, const decNumber *, decContext *);
00131   decNumber * decNumberMinus(decNumber *, const decNumber *, decContext *);
00132   decNumber * decNumberMultiply(decNumber *, const decNumber *, const decNumber *, decContext *);
00133   decNumber * decNumberNormalize(decNumber *, const decNumber *, decContext *);
00134   decNumber * decNumberOr(decNumber *, const decNumber *, const decNumber *, decContext *);
00135   decNumber * decNumberPlus(decNumber *, const decNumber *, decContext *);
00136   decNumber * decNumberPower(decNumber *, const decNumber *, const decNumber *, decContext *);
00137   decNumber * decNumberQuantize(decNumber *, const decNumber *, const decNumber *, decContext *);
00138   decNumber * decNumberReduce(decNumber *, const decNumber *, decContext *);
00139   decNumber * decNumberRemainder(decNumber *, const decNumber *, const decNumber *, decContext *);
00140   decNumber * decNumberRemainderNear(decNumber *, const decNumber *, const decNumber *, decContext *);
00141   decNumber * decNumberRescale(decNumber *, const decNumber *, const decNumber *, decContext *);
00142   decNumber * decNumberRotate(decNumber *, const decNumber *, const decNumber *, decContext *);
00143   decNumber * decNumberSameQuantum(decNumber *, const decNumber *, const decNumber *);
00144   decNumber * decNumberScaleB(decNumber *, const decNumber *, const decNumber *, decContext *);
00145   decNumber * decNumberShift(decNumber *, const decNumber *, const decNumber *, decContext *);
00146   decNumber * decNumberSquareRoot(decNumber *, const decNumber *, decContext *);
00147   decNumber * decNumberSubtract(decNumber *, const decNumber *, const decNumber *, decContext *);
00148   decNumber * decNumberToIntegralExact(decNumber *, const decNumber *, decContext *);
00149   decNumber * decNumberToIntegralValue(decNumber *, const decNumber *, decContext *);
00150   decNumber * decNumberXor(decNumber *, const decNumber *, const decNumber *, decContext *);
00151
00152   /* Utilities                                                        */
00153   enum decClass decNumberClass(const decNumber *, decContext *);
00154   const char * decNumberClassToString(enum decClass);
00155   decNumber  * decNumberCopy(decNumber *, const decNumber *);
00156   decNumber  * decNumberCopyAbs(decNumber *, const decNumber *);
00157   decNumber  * decNumberCopyNegate(decNumber *, const decNumber *);
00158   decNumber  * decNumberCopySign(decNumber *, const decNumber *, const decNumber *);
00159   decNumber  * decNumberNextMinus(decNumber *, const decNumber *, decContext *);
00160   decNumber  * decNumberNextPlus(decNumber *, const decNumber *, decContext *);
00161   decNumber  * decNumberNextToward(decNumber *, const decNumber *, const decNumber *, decContext *);
00162   decNumber  * decNumberTrim(decNumber *);
00163   const char * decNumberVersion(void);
00164   decNumber  * decNumberZero(decNumber *);
00165   decNumber  * decNumberCopy_(decNumber* dst, const decNumber* src);
00166   /* Functions for testing decNumbers (normality depends on context)  */
00167   int32_t decNumberIsNormal(const decNumber *, decContext *);
00168   int32_t decNumberIsSubnormal(const decNumber *, decContext *);
00169
00170   /* Macros for testing decNumber *dn                                 */
00171   #define decNumberIsCanonical(dn) (1)  /* All decNumbers are saintly */
00172   #define decNumberIsFinite(dn)    (((dn)->bits&DECSPECIAL)==0)
00173   #define decNumberIsInfinite(dn)  (((dn)->bits&DECINF)!=0)
00174   #define decNumberIsNaN(dn)       (((dn)->bits&(DECNAN|DECSNAN))!=0)
00175   #define decNumberIsNegative(dn)  (((dn)->bits&DECNEG)!=0)
00176   #define decNumberIsQNaN(dn)      (((dn)->bits&(DECNAN))!=0)
00177   #define decNumberIsSNaN(dn)      (((dn)->bits&(DECSNAN))!=0)
00178   #define decNumberIsSpecial(dn)   (((dn)->bits&DECSPECIAL)!=0)
00179   #define decNumberIsZero(dn)      (*(dn)->lsu==0 \
00180                                     && (dn)->digits==1 \
00181                                     && (((dn)->bits&DECSPECIAL)==0))
00182   #define decNumberRadix(dn)       (10)
00183
00184 #endif
Généré le Mon Jul 20 18:22:14 2009 pour Decimal par doxygen 1.5.1-p1


Decimal: Référence du fichier P:/wx_LIB/Dcml/decNumberLocal.h

Référence du fichier P:/wx_LIB/Dcml/decNumberLocal.h

#include <stdlib.h>
#include <string.h>

Aller au code source de ce fichier.

Classes

struct | bcdnum

Macros

#define | DECNUMBERLOC
#define | DECVERSION "decNumber 3.61"
#define | DECNLAUTHOR "Mike Cowlishaw"
#define | DECLITEND 1
#define | DECUSE64 1
#define | DECCHECK 0
#define | DECALLOC 0
#define | DECTRACE 0
#define | DECBUFFER 36
#define | Flag uint8_t
#define | Byte int8_t
#define | uByte uint8_t
#define | Short int16_t
#define | uShort uint16_t
#define | Int int32_t
#define | uInt uint32_t
#define | Unit decNumberUnit
#define | Long int64_t
#define | uLong uint64_t
#define | DECNOINT 0
#define | LONGMUL32HI(w, u, v)
#define | ROUNDUP(i, n) ((((i)+(n)-1)/n)*n)
#define | ROUNDUP4(i) (((i)+3)&~3)
#define | ROUNDDOWN(i, n) (((i)/n)*n)
#define | ROUNDDOWN4(i) ((i)&~3)
#define | UBTOUS(b) (memcpy((void *)&uswork, b, 2), uswork)
#define | UBTOUI(b) (memcpy((void *)&uiwork, b, 4), uiwork)
#define | UBFROMUS(b, i) (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork)
#define | UBFROMUI(b, i) (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork)
#define | X10(i) (((i)<<1)+((i)<<3))
#define | X100(i) (((i)<<2)+((i)<<5)+((i)<<6))
#define | MAXI(x, y) ((x)<(y)?(y):(x))
#define | MINI(x, y) ((x)>(y)?(y):(x))
#define | BILLION 1000000000
#define | CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')
#define | DECNUMMAXP 999999999
#define | DECNUMMAXE 999999999
#define | DECNUMMINE -999999999
#define | DECMAXD2U 49
#define | ISZERO(dn) decNumberIsZero(dn)
#define | D2U(d) ((d)<=DECMAXD2U?d2utable[d]:((d)+DECDPUN-1)/DECDPUN)
#define | SD2U(d) (((d)+DECDPUN-1)/DECDPUN)
#define | MSUDIGITS(d) ((d)-(D2U(d)-1)*DECDPUN)
#define | D2N(d) ((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
#define | TODIGIT(u, cut, c, pow)
#define | EXPISSPECIAL(exp) ((exp)>=DECFLOAT_MinSp)
#define | EXPISINF(exp) (exp==DECFLOAT_Inf)
#define | EXPISNAN(exp) (exp==DECFLOAT_qNaN || exp==DECFLOAT_sNaN)
#define | NUMISSPECIAL(num) (EXPISSPECIAL((num)->exponent))
#define | DECWORDS (DECBYTES/4)
#define | DECWWORDS (DECWBYTES/4)
#define | DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)])
#define | DFWORD(df, off) ((df)->words[DECWORDS-1-(off)])
#define | DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
#define | DFISSIGNED(df) (DFWORD(df, 0)&0x80000000)
#define | DFISSPECIAL(df) ((DFWORD(df, 0)&0x78000000)==0x78000000)
#define | DFISINF(df) ((DFWORD(df, 0)&0x7c000000)==0x78000000)
#define | DFISNAN(df) ((DFWORD(df, 0)&0x7c000000)==0x7c000000)
#define | DFISQNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7c000000)
#define | DFISSNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7e000000)

Définition de type

typedef long int | LI

Variables

const uByte | DECSTICKYTAB [10]
const uInt | DECPOWERS [10]
const uShort | DPD2BIN [1024]
const uShort | BIN2DPD [1000]
const uInt | DPD2BINK [1024]
const uInt | DPD2BINM [1024]
const uByte | DPD2BCD8 [4096]
const uByte | BIN2BCD8 [4000]
const uShort | BCD2DPD [2458]
const uByte | d2utable [DECMAXD2U+1]
const uInt | DECCOMBMSD [64]
const uInt | DECCOMBFROM [48]

Documentation des macros

#define BILLION 1000000000

Définition à la ligne 154 du fichier decNumberLocal.h.

#define Byte int8_t

Définition à la ligne 71 du fichier decNumberLocal.h.

#define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')

Définition à la ligne 156 du fichier decNumberLocal.h.

#define D2N ( d ) ((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))

Définition à la ligne 261 du fichier decNumberLocal.h.

Référencé par decExpOp(), decLnOp(), decNumberCompareTotalMag(), decNumberFMA(), decNumberLog10(), decNumberPower(), et decNumberSquareRoot().

#define D2U ( d ) ((d)<=DECMAXD2U?d2utable[d]:((d)+DECDPUN-1)/DECDPUN)

Définition à la ligne 247 du fichier decNumberLocal.h.

Référencé par decAddOp(), decCompare(), decCompareOp(), decDecap(), decDivideOp(), decExpOp(), decLnOp(), decMultiplyOp(), decNaNs(), decNumberAnd(), decNumberCompareTotalMag(), decNumberCopy(), decNumberFMA(), decNumberInvert(), decNumberLog10(), decNumberOr(), decNumberPower(), decNumberRotate(), decNumberSetBCD(), decNumberShift(), decNumberSquareRoot(), decNumberXor(), decShiftToLeast(), decShiftToMost(), decToString(), et decUnitCompare().

#define DECALLOC 0

Définition à la ligne 50 du fichier decNumberLocal.h.

#define DECBUFFER 36

Définition à la ligne 58 du fichier decNumberLocal.h.

Référencé par decAddOp(), decDivideOp(), decExpOp(), decLnOp(), decMultiplyOp(), decNumberCompareTotalMag(), decNumberFMA(), decNumberFromString(), decNumberLog10(), decNumberPower(), decNumberSquareRoot(), et decUnitCompare().

#define DECCHECK 0

Définition à la ligne 47 du fichier decNumberLocal.h.

Référencé par decExpOp(), et decLnOp().

#define DECLITEND 1

Définition à la ligne 37 du fichier decNumberLocal.h.

Référencé par decContextTestEndian().

#define DECMAXD2U 49

Définition à la ligne 232 du fichier decNumberLocal.h.

#define DECNLAUTHOR "Mike Cowlishaw"

Définition à la ligne 30 du fichier decNumberLocal.h.

#define DECNOINT 0

Définition à la ligne 85 du fichier decNumberLocal.h.

#define DECNUMBERLOC

Définition à la ligne 28 du fichier decNumberLocal.h.

#define DECNUMMAXE 999999999

Définition à la ligne 166 du fichier decNumberLocal.h.

Référencé par decMultiplyOp(), et decNumberFromString().

#define DECNUMMAXP 999999999

Définition à la ligne 165 du fichier decNumberLocal.h.

Référencé par decNumberPower().

#define DECNUMMINE -999999999

Définition à la ligne 167 du fichier decNumberLocal.h.

#define DECTRACE 0

Définition à la ligne 53 du fichier decNumberLocal.h.

#define DECUSE64 1

Définition à la ligne 42 du fichier decNumberLocal.h.

#define DECVERSION "decNumber 3.61"

Définition à la ligne 29 du fichier decNumberLocal.h.

Référencé par decNumberVersion().

#define DECWORDS (DECBYTES/4)

Définition à la ligne 311 du fichier decNumberLocal.h.

#define DECWWORDS (DECWBYTES/4)

Définition à la ligne 312 du fichier decNumberLocal.h.

#define DFBYTE | ( | df,
 |  | off | ) | ((df)->bytes[DECBYTES-1-(off)])

Définition à la ligne 314 du fichier decNumberLocal.h.

#define DFISINF ( df ) ((DFWORD(df, 0)&0x7c000000)==0x78000000)

Définition à la ligne 326 du fichier decNumberLocal.h.

#define DFISNAN ( df ) ((DFWORD(df, 0)&0x7c000000)==0x7c000000)

Définition à la ligne 327 du fichier decNumberLocal.h.

#define DFISQNAN ( df ) ((DFWORD(df, 0)&0x7e000000)==0x7c000000)

Définition à la ligne 328 du fichier decNumberLocal.h.

#define DFISSIGNED ( df ) (DFWORD(df, 0)&0x80000000)

Définition à la ligne 324 du fichier decNumberLocal.h.

#define DFISSNAN ( df ) ((DFWORD(df, 0)&0x7e000000)==0x7e000000)

Définition à la ligne 329 du fichier decNumberLocal.h.

#define DFISSPECIAL ( df ) ((DFWORD(df, 0)&0x78000000)==0x78000000)

Définition à la ligne 325 du fichier decNumberLocal.h.

#define DFWORD | ( | df,
 |  | off | ) | ((df)->words[DECWORDS-1-(off)])

Définition à la ligne 315 du fichier decNumberLocal.h.

#define DFWWORD | ( | dfw,
 |  | off | ) | ((dfw)->words[DECWWORDS-1-(off)])

Définition à la ligne 316 du fichier decNumberLocal.h.

#define EXPISINF ( exp ) (exp==DECFLOAT_Inf)

Définition à la ligne 303 du fichier decNumberLocal.h.

#define EXPISNAN ( exp ) (exp==DECFLOAT_qNaN || exp==DECFLOAT_sNaN)

Définition à la ligne 304 du fichier decNumberLocal.h.

#define EXPISSPECIAL ( exp ) ((exp)>=DECFLOAT_MinSp)

Définition à la ligne 302 du fichier decNumberLocal.h.

#define Flag uint8_t

Définition à la ligne 70 du fichier decNumberLocal.h.

Référencé par decAddOp(), decDivideOp(), decGetInt(), decNumberFromString(), decNumberPower(), decSetOverflow(), et decToString().

#define Int int32_t

Définition à la ligne 75 du fichier decNumberLocal.h.

Référencé par decAddOp(), decApplyRound(), decCompare(), decCompareOp(), decContextStatusToString(), decContextTestEndian(), decDecap(), decDivideOp(), decExpOp(), decFinalize(), decGetDigits(), decGetInt(), decLnOp(), decMultiplyOp(), decNumberAnd(), decNumberFromString(), decNumberInvert(), decNumberIsNormal(), decNumberIsSubnormal(), decNumberLog10(), decNumberLogB(), decNumberNextToward(), decNumberOr(), decNumberPower(), decNumberReduce(), decNumberRotate(), decNumberScaleB(), decNumberSetBCD(), decNumberShift(), decNumberSquareRoot(), decNumberToInt32(), decNumberToUInt32(), decNumberTrim(), decNumberXor(), decQuantizeOp(), decSetCoeff(), decSetMaxValue(), decSetOverflow(), decSetSubnormal(), decShiftToLeast(), decShiftToMost(), decToString(), decTrim(), decUnitAddSub(), et decUnitCompare().

#define ISZERO ( dn ) decNumberIsZero(dn)

Définition à la ligne 238 du fichier decNumberLocal.h.

Référencé par decAddOp(), decCheckMath(), decCompare(), decDivideOp(), decExpOp(), decFinalize(), decGetInt(), decLnOp(), decMultiplyOp(), decNumberLn(), decNumberLog10(), decNumberPower(), decNumberSquareRoot(), decNumberToUInt32(), decQuantizeOp(), decSetOverflow(), decSetSubnormal(), decToString(), et decTrim().

#define Long int64_t

Définition à la ligne 79 du fichier decNumberLocal.h.

#define LONGMUL32HI | ( | w,
 |  | u,
 |  | v | )

Valeur :

{             \
    uInt u0, u1, v0, v1, w0, w1, w2, t;      \
    u0=u & 0xffff; u1=u>>16;                 \
    v0=v & 0xffff; v1=v>>16;                 \
    w0=u0*v0;                                \
    t=u1*v0 + (w0>>16);                      \
    w1=t & 0xffff; w2=t>>16;                 \
    w1=u0*v1 + w1;                           \
    (w)=u1*v1 + w2 + (w1>>16);}

Définition à la ligne 110 du fichier decNumberLocal.h.

#define MAXI | ( | x,
 |  | y | ) | ((x)<(y)?(y):(x))

Définition à la ligne 150 du fichier decNumberLocal.h.

Référencé par decExpOp(), decLnOp(), decNumberPower(), et decNumberSquareRoot().

#define MINI | ( | x,
 |  | y | ) | ((x)>(y)?(y):(x))

Définition à la ligne 151 du fichier decNumberLocal.h.

Référencé par decExpOp(), et decNumberSquareRoot().

#define MSUDIGITS ( d ) ((d)-(D2U(d)-1)*DECDPUN)

Définition à la ligne 254 du fichier decNumberLocal.h.

Référencé par decDecap(), decNumberAnd(), decNumberInvert(), decNumberOr(), decNumberRotate(), decNumberSetBCD(), decNumberXor(), decShiftToLeast(), decShiftToMost(), et decToString().

#define NUMISSPECIAL ( num ) (EXPISSPECIAL((num)->exponent))

Définition à la ligne 305 du fichier decNumberLocal.h.

#define ROUNDDOWN | ( | i,
 |  | n | ) | (((i)/n)*n)

Définition à la ligne 125 du fichier decNumberLocal.h.

#define ROUNDDOWN4 ( i ) ((i)&~3)

Définition à la ligne 126 du fichier decNumberLocal.h.

#define ROUNDUP | ( | i,
 |  | n | ) | ((((i)+(n)-1)/n)*n)

Définition à la ligne 121 du fichier decNumberLocal.h.

#define ROUNDUP4 ( i ) (((i)+3)&~3)

Définition à la ligne 122 du fichier decNumberLocal.h.

#define SD2U ( d ) (((d)+DECDPUN-1)/DECDPUN)

Définition à la ligne 250 du fichier decNumberLocal.h.

Référencé par decAddOp(), decDivideOp(), decMultiplyOp(), decNumberFromString(), et decUnitCompare().

#define Short int16_t

Définition à la ligne 73 du fichier decNumberLocal.h.

#define TODIGIT | ( | u,
 |  | cut,
 |  | c,
 |  | pow | )

Valeur :

{       \
    *(c)='0';                             \
    pow=DECPOWERS[cut]*2;                 \
    if ((u)>pow) {                        \
      pow*=4;                             \
      if ((u)>=pow) {(u)-=pow; *(c)+=8;}  \
      pow/=2;                             \
      if ((u)>=pow) {(u)-=pow; *(c)+=4;}  \
      pow/=2;                             \
      }                                   \
    if ((u)>=pow) {(u)-=pow; *(c)+=2;}    \
    pow/=2;                               \
    if ((u)>=pow) {(u)-=pow; *(c)+=1;}    \
    }

Définition à la ligne 271 du fichier decNumberLocal.h.

Référencé par decToString().

#define UBFROMUI | ( | b,
 |  | i | ) | (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork)

Définition à la ligne 142 du fichier decNumberLocal.h.

#define UBFROMUS | ( | b,
 |  | i | ) | (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork)

Définition à la ligne 141 du fichier decNumberLocal.h.

#define UBTOUI ( b ) (memcpy((void *)&uiwork, b, 4), uiwork)

Définition à la ligne 136 du fichier decNumberLocal.h.

#define UBTOUS ( b ) (memcpy((void *)&uswork, b, 2), uswork)

Définition à la ligne 135 du fichier decNumberLocal.h.

#define uByte uint8_t

Définition à la ligne 72 du fichier decNumberLocal.h.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decMultiplyOp(), decNumberAbs(), decNumberCopySign(), decNumberFromString(), decNumberGetBCD(), decNumberNextToward(), decNumberPower(), decNumberSetBCD(), et decSetOverflow().

#define uInt uint32_t

Définition à la ligne 76 du fichier decNumberLocal.h.

Référencé par decApplyRound(), decCheckMath(), decContextTestEndian(), decDivideOp(), decExpOp(), decGetDigits(), decLnOp(), decMultiplyOp(), decNumberAbs(), decNumberAdd(), decNumberCompare(), decNumberCompareSignal(), decNumberCompareTotal(), decNumberCompareTotalMag(), decNumberDivide(), decNumberDivideInteger(), decNumberExp(), decNumberFMA(), decNumberFromInt32(), decNumberFromString(), decNumberGetBCD(), decNumberLn(), decNumberLog10(), decNumberLogB(), decNumberMax(), decNumberMaxMag(), decNumberMin(), decNumberMinMag(), decNumberMinus(), decNumberMultiply(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPlus(), decNumberPower(), decNumberQuantize(), decNumberReduce(), decNumberRemainder(), decNumberRemainderNear(), decNumberRescale(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberSubtract(), decNumberToInt32(), decNumberToIntegralExact(), decNumberToUInt32(), decSetCoeff(), decShiftToMost(), decToString(), et decTrim().

#define uLong uint64_t

Définition à la ligne 80 du fichier decNumberLocal.h.

Référencé par decMultiplyOp().

#define Unit decNumberUnit

Définition à la ligne 77 du fichier decNumberLocal.h.

Référencé par decNumberFromString(), decNumberFromUInt32(), decNumberToInt32(), et decNumberToUInt32().

#define uShort uint16_t

Définition à la ligne 74 du fichier decNumberLocal.h.

#define X10 ( i ) (((i)<<1)+((i)<<3))

Définition à la ligne 146 du fichier decNumberLocal.h.

Référencé par decLnOp(), decNumberFromString(), decNumberSetBCD(), decNumberToInt32(), et decNumberToUInt32().

#define X100 ( i ) (((i)<<2)+((i)<<5)+((i)<<6))

Définition à la ligne 147 du fichier decNumberLocal.h.

Documentation des définition de type

typedef long int LI

Définition à la ligne 84 du fichier decNumberLocal.h.

Documentation des variables

const uShort BCD2DPD[2458]

const uByte BIN2BCD8[4000]

const uShort BIN2DPD[1000]

const uByte d2utable[DECMAXD2U+1]

Définition à la ligne 176 du fichier decNumber.c.

const uInt DECCOMBFROM[48]

const uInt DECCOMBMSD[64]

const uInt DECPOWERS[10]

Définition à la ligne 46 du fichier decContext.c.

const uByte DECSTICKYTAB[10]

Définition à la ligne 41 du fichier decContext.c.

const uByte DPD2BCD8[4096]

const uShort DPD2BIN[1024]

const uInt DPD2BINK[1024]

const uInt DPD2BINM[1024]


Decimal: Fichier source de P:/wx_LIB/Dcml/decNumberLocal.h

P:/wx_LIB/Dcml/decNumberLocal.h

Aller à la documentation de ce fichier.
00001 /* ------------------------------------------------------------------ */
00002 /* decNumber package local type, tuning, and macro definitions        */
00003 /* ------------------------------------------------------------------ */
00004 /* Copyright (c) IBM Corporation, 2000, 2008.  All rights reserved.   */
00005 /*                                                                    */
00006 /* This software is made available under the terms of the IBM         */
00007 /* alphaWorks License Agreement (distributed with this software as    */
00008 /* alphaWorks-License.txt).  Your use of this software indicates      */
00009 /* your acceptance of the terms and conditions of that Agreement.     */
00010 /*                                                                    */
00011 /* The description and User's Guide ("The decNumber C Library") for   */
00012 /* this software is called decNumber.pdf.  This document is           */
00013 /* available, together with arithmetic and format specifications,     */
00014 /* testcases, and Web links, on the General Decimal Arithmetic page.  */
00015 /*                                                                    */
00016 /* Please send comments, suggestions, and corrections to the author:  */
00017 /*   mfc@uk.ibm.com                                                   */
00018 /*   Mike Cowlishaw, IBM Fellow                                       */
00019 /*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
00020 /* ------------------------------------------------------------------ */
00021 /* This header file is included by all modules in the decNumber       */
00022 /* library, and contains local type definitions, tuning parameters,   */
00023 /* etc.  It should not need to be used by application programs.       */
00024 /* decNumber.h or one of decDouble (etc.) must be included first.     */
00025 /* ------------------------------------------------------------------ */
00026
00027 #if !defined(DECNUMBERLOC)
00028   #define DECNUMBERLOC
00029   #define DECVERSION    "decNumber 3.61" /* Package Version [16 max.] */
00030   #define DECNLAUTHOR   "Mike Cowlishaw"              /* Who to blame */
00031
00032   #include <stdlib.h>         /* for abs                              */
00033   #include <string.h>         /* for memset, strcpy                   */
00034
00035   /* Conditional code flag -- set this to match hardware platform     */
00036   #if !defined(DECLITEND)
00037   #define DECLITEND 1         /* 1=little-endian, 0=big-endian        */
00038   #endif
00039
00040   /* Conditional code flag -- set this to 1 for best performance      */
00041   #if !defined(DECUSE64)
00042   #define DECUSE64  1         /* 1=use int64s, 0=int32 & smaller only */
00043   #endif
00044
00045   /* Conditional check flags -- set these to 0 for best performance   */
00046   #if !defined(DECCHECK)
00047   #define DECCHECK  0         /* 1 to enable robust checking          */
00048   #endif
00049   #if !defined(DECALLOC)
00050   #define DECALLOC  0         /* 1 to enable memory accounting        */
00051   #endif
00052   #if !defined(DECTRACE)
00053   #define DECTRACE  0         /* 1 to trace certain internals, etc.   */
00054   #endif
00055
00056   /* Tuning parameter for decNumber (arbitrary precision) module      */
00057   #if !defined(DECBUFFER)
00058   #define DECBUFFER 36        /* Size basis for local buffers.  This  */
00059                               /* should be a common maximum precision */
00060                               /* rounded up to a multiple of 4; must  */
00061                               /* be zero or positive.                 */
00062   #endif
00063
00064   /* ---------------------------------------------------------------- */
00065   /* Definitions for all modules (general-purpose)                    */
00066   /* ---------------------------------------------------------------- */
00067
00068   /* Local names for common types -- for safety, decNumber modules do */
00069   /* not use int or long directly.                                    */
00070   #define Flag   uint8_t
00071   #define Byte   int8_t
00072   #define uByte  uint8_t
00073   #define Short  int16_t
00074   #define uShort uint16_t
00075   #define Int    int32_t
00076   #define uInt   uint32_t
00077   #define Unit   decNumberUnit
00078   #if DECUSE64
00079   #define Long   int64_t
00080   #define uLong  uint64_t
00081   #endif
00082
00083   /* Development-use definitions                                      */
00084   typedef long int LI;        /* for printf arguments only            */
00085   #define DECNOINT  0         /* 1 to check no internal use of 'int'  */
00086                               /*   or stdint types                    */
00087   #if DECNOINT
00088     /* if these interfere with your C includes, do not set DECNOINT   */
00089     #define int     ?         /* enable to ensure that plain C 'int'  */
00090     #define long    ??        /* .. or 'long' types are not used      */
00091   #endif
00092
00093   /* Shared lookup tables                                             */
00094   extern const uByte  DECSTICKYTAB[10]; /* re-round digits if sticky  */
00095   extern const uInt   DECPOWERS[10];    /* powers of ten table        */
00096   /* The following are included from decDPD.h                         */
00097   extern const uShort DPD2BIN[1024];    /* DPD -> 0-999               */
00098   extern const uShort BIN2DPD[1000];    /* 0-999 -> DPD               */
00099   extern const uInt   DPD2BINK[1024];   /* DPD -> 0-999000            */
00100   extern const uInt   DPD2BINM[1024];   /* DPD -> 0-999000000         */
00101   extern const uByte  DPD2BCD8[4096];   /* DPD -> ddd + len           */
00102   extern const uByte  BIN2BCD8[4000];   /* 0-999 -> ddd + len         */
00103   extern const uShort BCD2DPD[2458];    /* 0-0x999 -> DPD (0x999=2457)*/
00104
00105   /* LONGMUL32HI -- set w=(u*v)>>32, where w, u, and v are uInts      */
00106   /* (that is, sets w to be the high-order word of the 64-bit result; */
00107   /* the low-order word is simply u*v.)                               */
00108   /* This version is derived from Knuth via Hacker's Delight;         */
00109   /* it seems to optimize better than some others tried               */
00110   #define LONGMUL32HI(w, u, v) {             \
00111     uInt u0, u1, v0, v1, w0, w1, w2, t;      \
00112     u0=u & 0xffff; u1=u>>16;                 \
00113     v0=v & 0xffff; v1=v>>16;                 \
00114     w0=u0*v0;                                \
00115     t=u1*v0 + (w0>>16);                      \
00116     w1=t & 0xffff; w2=t>>16;                 \
00117     w1=u0*v1 + w1;                           \
00118     (w)=u1*v1 + w2 + (w1>>16);}
00119
00120   /* ROUNDUP -- round an integer up to a multiple of n                */
00121   #define ROUNDUP(i, n) ((((i)+(n)-1)/n)*n)
00122   #define ROUNDUP4(i)   (((i)+3)&~3)    /* special for n=4            */
00123
00124   /* ROUNDDOWN -- round an integer down to a multiple of n            */
00125   #define ROUNDDOWN(i, n) (((i)/n)*n)
00126   #define ROUNDDOWN4(i)   ((i)&~3)      /* special for n=4            */
00127
00128   /* References to multi-byte sequences under different sizes; these  */
00129   /* require locally declared variables, but do not violate strict    */
00130   /* aliasing or alignment (as did the UINTAT simple cast to uInt).   */
00131   /* Variables needed are uswork, uiwork, etc. [so do not use at same */
00132   /* level in an expression, e.g., UBTOUI(x)==UBTOUI(y) may fail].    */
00133
00134   /* Return a uInt, etc., from bytes starting at a char* or uByte*    */
00135   #define UBTOUS(b)  (memcpy((void *)&uswork, b, 2), uswork)
00136   #define UBTOUI(b)  (memcpy((void *)&uiwork, b, 4), uiwork)
00137
00138   /* Store a uInt, etc., into bytes starting at a char* or uByte*.    */
00139   /* Returns i, evaluated, for convenience; has to use uiwork because */
00140   /* i may be an expression.                                          */
00141   #define UBFROMUS(b, i)  (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork)
00142   #define UBFROMUI(b, i)  (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork)
00143
00144   /* X10 and X100 -- multiply integer i by 10 or 100                  */
00145   /* [shifts are usually faster than multiply; could be conditional]  */
00146   #define X10(i)  (((i)<<1)+((i)<<3))
00147   #define X100(i) (((i)<<2)+((i)<<5)+((i)<<6))
00148
00149   /* MAXI and MINI -- general max & min (not in ANSI) for integers    */
00150   #define MAXI(x,y) ((x)<(y)?(y):(x))
00151   #define MINI(x,y) ((x)>(y)?(y):(x))
00152
00153   /* Useful constants                                                 */
00154   #define BILLION      1000000000            /* 10**9                 */
00155   /* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC       */
00156   #define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')
00157
00158
00159   /* ---------------------------------------------------------------- */
00160   /* Definitions for arbitary-precision modules (only valid after     */
00161   /* decNumber.h has been included)                                   */
00162   /* ---------------------------------------------------------------- */
00163
00164   /* Limits and constants                                             */
00165   #define DECNUMMAXP 999999999  /* maximum precision code can handle  */
00166   #define DECNUMMAXE 999999999  /* maximum adjusted exponent ditto    */
00167   #define DECNUMMINE -999999999 /* minimum adjusted exponent ditto    */
00168   #if (DECNUMMAXP != DEC_MAX_DIGITS)
00169     #error Maximum digits mismatch
00170   #endif
00171   #if (DECNUMMAXE != DEC_MAX_EMAX)
00172     #error Maximum exponent mismatch
00173   #endif
00174   #if (DECNUMMINE != DEC_MIN_EMIN)
00175     #error Minimum exponent mismatch
00176   #endif
00177
00178   /* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN       */
00179   /* digits, and D2UTABLE -- the initializer for the D2U table        */
00180   #if   DECDPUN==1
00181     #define DECDPUNMAX 9
00182     #define D2UTABLE {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,  \
00183                       18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, \
00184                       33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, \
00185                       48,49}
00186   #elif DECDPUN==2
00187     #define DECDPUNMAX 99
00188     #define D2UTABLE {0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,  \
00189                       11,11,12,12,13,13,14,14,15,15,16,16,17,17,18, \
00190                       18,19,19,20,20,21,21,22,22,23,23,24,24,25}
00191   #elif DECDPUN==3
00192     #define DECDPUNMAX 999
00193     #define D2UTABLE {0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,  \
00194                       8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13, \
00195                       13,14,14,14,15,15,15,16,16,16,17}
00196   #elif DECDPUN==4
00197     #define DECDPUNMAX 9999
00198     #define D2UTABLE {0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,  \
00199                       6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11, \
00200                       11,11,11,12,12,12,12,13}
00201   #elif DECDPUN==5
00202     #define DECDPUNMAX 99999
00203     #define D2UTABLE {0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,  \
00204                       5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,  \
00205                       9,9,10,10,10,10}
00206   #elif DECDPUN==6
00207     #define DECDPUNMAX 999999
00208     #define D2UTABLE {0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,  \
00209                       4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,  \
00210                       8,8,8,8,8,9}
00211   #elif DECDPUN==7
00212     #define DECDPUNMAX 9999999
00213     #define D2UTABLE {0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,  \
00214                       4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,  \
00215                       7,7,7,7,7,7}
00216   #elif DECDPUN==8
00217     #define DECDPUNMAX 99999999
00218     #define D2UTABLE {0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,  \
00219                       3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,  \
00220                       6,6,6,6,6,7}
00221   #elif DECDPUN==9
00222     #define DECDPUNMAX 999999999
00223     #define D2UTABLE {0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,  \
00224                       3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,  \
00225                       5,5,6,6,6,6}
00226   #elif defined(DECDPUN)
00227     #error DECDPUN must be in the range 1-9
00228   #endif
00229
00230   /* ----- Shared data (in decNumber.c) ----- */
00231   /* Public lookup table used by the D2U macro (see below)            */
00232   #define DECMAXD2U 49
00233   extern const uByte d2utable[DECMAXD2U+1];
00234
00235   /* ----- Macros ----- */
00236   /* ISZERO -- return true if decNumber dn is a zero                  */
00237   /* [performance-critical in some situations]                        */
00238   #define ISZERO(dn) decNumberIsZero(dn)     /* now just a local name */
00239
00240   /* D2U -- return the number of Units needed to hold d digits        */
00241   /* (runtime version, with table lookaside for small d)              */
00242   #if DECDPUN==8
00243     #define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+7)>>3))
00244   #elif DECDPUN==4
00245     #define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+3)>>2))
00246   #else
00247     #define D2U(d) ((d)<=DECMAXD2U?d2utable[d]:((d)+DECDPUN-1)/DECDPUN)
00248   #endif
00249   /* SD2U -- static D2U macro (for compile-time calculation)          */
00250   #define SD2U(d) (((d)+DECDPUN-1)/DECDPUN)
00251
00252   /* MSUDIGITS -- returns digits in msu, from digits, calculated      */
00253   /* using D2U                                                        */
00254   #define MSUDIGITS(d) ((d)-(D2U(d)-1)*DECDPUN)
00255
00256   /* D2N -- return the number of decNumber structs that would be      */
00257   /* needed to contain that number of digits (and the initial         */
00258   /* decNumber struct) safely.  Note that one Unit is included in the */
00259   /* initial structure.  Used for allocating space that is aligned on */
00260   /* a decNumber struct boundary. */
00261   #define D2N(d) \
00262     ((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
00263
00264   /* TODIGIT -- macro to remove the leading digit from the unsigned   */
00265   /* integer u at column cut (counting from the right, LSD=0) and     */
00266   /* place it as an ASCII character into the character pointed to by  */
00267   /* c.  Note that cut must be <= 9, and the maximum value for u is   */
00268   /* 2,000,000,000 (as is needed for negative exponents of            */
00269   /* subnormals).  The unsigned integer pow is used as a temporary    */
00270   /* variable. */
00271   #define TODIGIT(u, cut, c, pow) {       \
00272     *(c)='0';                             \
00273     pow=DECPOWERS[cut]*2;                 \
00274     if ((u)>pow) {                        \
00275       pow*=4;                             \
00276       if ((u)>=pow) {(u)-=pow; *(c)+=8;}  \
00277       pow/=2;                             \
00278       if ((u)>=pow) {(u)-=pow; *(c)+=4;}  \
00279       pow/=2;                             \
00280       }                                   \
00281     if ((u)>=pow) {(u)-=pow; *(c)+=2;}    \
00282     pow/=2;                               \
00283     if ((u)>=pow) {(u)-=pow; *(c)+=1;}    \
00284     }
00285
00286   /* ---------------------------------------------------------------- */
00287   /* Definitions for fixed-precision modules (only valid after        */
00288   /* decSingle.h, decDouble.h, or decQuad.h has been included)        */
00289   /* ---------------------------------------------------------------- */
00290
00291   /* bcdnum -- a structure describing a format-independent finite     */
00292   /* number, whose coefficient is a string of bcd8 uBytes             */
00293   typedef struct {
00294     uByte   *msd;             /* -> most significant digit            */
00295     uByte   *lsd;             /* -> least ditto                       */
00296     uInt     sign;            /* 0=positive, DECFLOAT_Sign=negative   */
00297     Int      exponent;        /* Unadjusted signed exponent (q), or   */
00298                               /* DECFLOAT_NaN etc. for a special      */
00299     } bcdnum;
00300
00301   /* Test if exponent or bcdnum exponent must be a special, etc.      */
00302   #define EXPISSPECIAL(exp) ((exp)>=DECFLOAT_MinSp)
00303   #define EXPISINF(exp) (exp==DECFLOAT_Inf)
00304   #define EXPISNAN(exp) (exp==DECFLOAT_qNaN || exp==DECFLOAT_sNaN)
00305   #define NUMISSPECIAL(num) (EXPISSPECIAL((num)->exponent))
00306
00307   /* Refer to a 32-bit word or byte in a decFloat (df) by big-endian  */
00308   /* (array) notation (the 0 word or byte contains the sign bit),     */
00309   /* automatically adjusting for endianness; similarly address a word */
00310   /* in the next-wider format (decFloatWider, or dfw)                 */
00311   #define DECWORDS  (DECBYTES/4)
00312   #define DECWWORDS (DECWBYTES/4)
00313   #if DECLITEND
00314     #define DFBYTE(df, off)   ((df)->bytes[DECBYTES-1-(off)])
00315     #define DFWORD(df, off)   ((df)->words[DECWORDS-1-(off)])
00316     #define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
00317   #else
00318     #define DFBYTE(df, off)   ((df)->bytes[off])
00319     #define DFWORD(df, off)   ((df)->words[off])
00320     #define DFWWORD(dfw, off) ((dfw)->words[off])
00321   #endif
00322
00323   /* Tests for sign or specials, directly on DECFLOATs                */
00324   #define DFISSIGNED(df)   (DFWORD(df, 0)&0x80000000)
00325   #define DFISSPECIAL(df) ((DFWORD(df, 0)&0x78000000)==0x78000000)
00326   #define DFISINF(df)     ((DFWORD(df, 0)&0x7c000000)==0x78000000)
00327   #define DFISNAN(df)     ((DFWORD(df, 0)&0x7c000000)==0x7c000000)
00328   #define DFISQNAN(df)    ((DFWORD(df, 0)&0x7e000000)==0x7c000000)
00329   #define DFISSNAN(df)    ((DFWORD(df, 0)&0x7e000000)==0x7e000000)
00330
00331   /* Shared lookup tables                                             */
00332   extern const uInt   DECCOMBMSD[64];   /* Combination field -> MSD   */
00333   extern const uInt   DECCOMBFROM[48];  /* exp+msd -> Combination     */
00334
00335   /* Private generic (utility) routine                                */
00336   #if DECCHECK || DECTRACE
00337     extern void decShowNum(const bcdnum *, const char *);
00338   #endif
00339
00340   /* Format-dependent macros and constants                            */
00341   #if defined(DECPMAX)
00342
00343     /* Useful constants                                               */
00344     #define DECPMAX9  (ROUNDUP(DECPMAX, 9)/9)  /* 'Pmax' in 10**9s    */
00345     /* Top words for a zero                                           */
00346     #define SINGLEZERO   0x22500000
00347     #define DOUBLEZERO   0x22380000
00348     #define QUADZERO     0x22080000
00349     /* [ZEROWORD is defined to be one of these in the DFISZERO macro] */
00350
00351     /* Format-dependent common tests:                                 */
00352     /*   DFISZERO   -- test for (any) zero                            */
00353     /*   DFISCCZERO -- test for coefficient continuation being zero   */
00354     /*   DFISCC01   -- test for coefficient contains only 0s and 1s   */
00355     /*   DFISINT    -- test for finite and exponent q=0               */
00356     /*   DFISUINT01 -- test for sign=0, finite, exponent q=0, and     */
00357     /*                 MSD=0 or 1                                     */
00358     /*   ZEROWORD is also defined here.                               */
00359     /* In DFISZERO the first test checks the least-significant word   */
00360     /* (most likely to be non-zero); the penultimate tests MSD and    */
00361     /* DPDs in the signword, and the final test excludes specials and */
00362     /* MSD>7.  DFISINT similarly has to allow for the two forms of    */
00363     /* MSD codes.  DFISUINT01 only has to allow for one form of MSD   */
00364     /* code.                                                          */
00365     #if DECPMAX==7
00366       #define ZEROWORD SINGLEZERO
00367       /* [test macros not needed except for Zero]                     */
00368       #define DFISZERO(df)  ((DFWORD(df, 0)&0x1c0fffff)==0         \
00369                           && (DFWORD(df, 0)&0x60000000)!=0x60000000)
00370     #elif DECPMAX==16
00371       #define ZEROWORD DOUBLEZERO
00372       #define DFISZERO(df)  ((DFWORD(df, 1)==0                     \
00373                           && (DFWORD(df, 0)&0x1c03ffff)==0         \
00374                           && (DFWORD(df, 0)&0x60000000)!=0x60000000))
00375       #define DFISINT(df) ((DFWORD(df, 0)&0x63fc0000)==0x22380000  \
00376                          ||(DFWORD(df, 0)&0x7bfc0000)==0x6a380000)
00377       #define DFISUINT01(df) ((DFWORD(df, 0)&0xfbfc0000)==0x22380000)
00378       #define DFISCCZERO(df) (DFWORD(df, 1)==0                     \
00379                           && (DFWORD(df, 0)&0x0003ffff)==0)
00380       #define DFISCC01(df)  ((DFWORD(df, 0)&~0xfffc9124)==0        \
00381                           && (DFWORD(df, 1)&~0x49124491)==0)
00382     #elif DECPMAX==34
00383       #define ZEROWORD QUADZERO
00384       #define DFISZERO(df)  ((DFWORD(df, 3)==0                     \
00385                           &&  DFWORD(df, 2)==0                     \
00386                           &&  DFWORD(df, 1)==0                     \
00387                           && (DFWORD(df, 0)&0x1c003fff)==0         \
00388                           && (DFWORD(df, 0)&0x60000000)!=0x60000000))
00389       #define DFISINT(df) ((DFWORD(df, 0)&0x63ffc000)==0x22080000  \
00390                          ||(DFWORD(df, 0)&0x7bffc000)==0x6a080000)
00391       #define DFISUINT01(df) ((DFWORD(df, 0)&0xfbffc000)==0x22080000)
00392       #define DFISCCZERO(df) (DFWORD(df, 3)==0                     \
00393                           &&  DFWORD(df, 2)==0                     \
00394                           &&  DFWORD(df, 1)==0                     \
00395                           && (DFWORD(df, 0)&0x00003fff)==0)
00396
00397       #define DFISCC01(df)   ((DFWORD(df, 0)&~0xffffc912)==0       \
00398                           &&  (DFWORD(df, 1)&~0x44912449)==0       \
00399                           &&  (DFWORD(df, 2)&~0x12449124)==0       \
00400                           &&  (DFWORD(df, 3)&~0x49124491)==0)
00401     #endif
00402
00403     /* Macros to test if a certain 10 bits of a uInt or pair of uInts */
00404     /* are a canonical declet [higher or lower bits are ignored].     */
00405     /* declet is at offset 0 (from the right) in a uInt:              */
00406     #define CANONDPD(dpd) (((dpd)&0x300)==0 || ((dpd)&0x6e)!=0x6e)
00407     /* declet is at offset k (a multiple of 2) in a uInt:             */
00408     #define CANONDPDOFF(dpd, k) (((dpd)&(0x300<<(k)))==0            \
00409       || ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
00410     /* declet is at offset k (a multiple of 2) in a pair of uInts:    */
00411     /* [the top 2 bits will always be in the more-significant uInt]   */
00412     #define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0     \
00413       || ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k)))                  \
00414       || ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
00415
00416     /* Macro to test whether a full-length (length DECPMAX) BCD8      */
00417     /* coefficient, starting at uByte u, is all zeros                 */
00418     /* Test just the LSWord first, then the remainder as a sequence   */
00419     /* of tests in order to avoid same-level use of UBTOUI            */
00420     #if DECPMAX==7
00421       #define ISCOEFFZERO(u) (                                      \
00422            UBTOUI((u)+DECPMAX-4)==0                                 \
00423         && UBTOUS((u)+DECPMAX-6)==0                                 \
00424         && *(u)==0)
00425     #elif DECPMAX==16
00426       #define ISCOEFFZERO(u) (                                      \
00427            UBTOUI((u)+DECPMAX-4)==0                                 \
00428         && UBTOUI((u)+DECPMAX-8)==0                                 \
00429         && UBTOUI((u)+DECPMAX-12)==0                                \
00430         && UBTOUI(u)==0)
00431     #elif DECPMAX==34
00432       #define ISCOEFFZERO(u) (                                      \
00433            UBTOUI((u)+DECPMAX-4)==0                                 \
00434         && UBTOUI((u)+DECPMAX-8)==0                                 \
00435         && UBTOUI((u)+DECPMAX-12)==0                                \
00436         && UBTOUI((u)+DECPMAX-16)==0                                \
00437         && UBTOUI((u)+DECPMAX-20)==0                                \
00438         && UBTOUI((u)+DECPMAX-24)==0                                \
00439         && UBTOUI((u)+DECPMAX-28)==0                                \
00440         && UBTOUI((u)+DECPMAX-32)==0                                \
00441         && UBTOUS(u)==0)
00442     #endif
00443
00444     /* Macros and masks for the exponent continuation field and MSD   */
00445     /* Get the exponent continuation from a decFloat *df as an Int    */
00446     #define GETECON(df) ((Int)((DFWORD((df), 0)&0x03ffffff)>>(32-6-DECECONL)))
00447     /* Ditto, from the next-wider format                              */
00448     #define GETWECON(df) ((Int)((DFWWORD((df), 0)&0x03ffffff)>>(32-6-DECWECONL)))
00449     /* Get the biased exponent similarly                              */
00450     #define GETEXP(df)  ((Int)(DECCOMBEXP[DFWORD((df), 0)>>26]+GETECON(df)))
00451     /* Get the unbiased exponent similarly                            */
00452     #define GETEXPUN(df) ((Int)GETEXP(df)-DECBIAS)
00453     /* Get the MSD similarly (as uInt)                                */
00454     #define GETMSD(df)   (DECCOMBMSD[DFWORD((df), 0)>>26])
00455
00456     /* Compile-time computes of the exponent continuation field masks */
00457     /* full exponent continuation field:                              */
00458     #define ECONMASK ((0x03ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
00459     /* same, not including its first digit (the qNaN/sNaN selector):  */
00460     #define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
00461
00462     /* Macros to decode the coefficient in a finite decFloat *df into */
00463     /* a BCD string (uByte *bcdin) of length DECPMAX uBytes.          */
00464
00465     /* In-line sequence to convert least significant 10 bits of uInt  */
00466     /* dpd to three BCD8 digits starting at uByte u.  Note that an    */
00467     /* extra byte is written to the right of the three digits because */
00468     /* four bytes are moved at a time for speed; the alternative      */
00469     /* macro moves exactly three bytes (usually slower).              */
00470     #define dpd2bcd8(u, dpd)  memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 4)
00471     #define dpd2bcd83(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 3)
00472
00473     /* Decode the declets.  After extracting each one, it is decoded  */
00474     /* to BCD8 using a table lookup (also used for variable-length    */
00475     /* decode).  Each DPD decode is 3 bytes BCD8 plus a one-byte      */
00476     /* length which is not used, here).  Fixed-length 4-byte moves    */
00477     /* are fast, however, almost everywhere, and so are used except   */
00478     /* for the final three bytes (to avoid overrun).  The code below  */
00479     /* is 36 instructions for Doubles and about 70 for Quads, even    */
00480     /* on IA32.                                                       */
00481
00482     /* Two macros are defined for each format:                        */
00483     /*   GETCOEFF extracts the coefficient of the current format      */
00484     /*   GETWCOEFF extracts the coefficient of the next-wider format. */
00485     /* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */
00486
00487     #if DECPMAX==7
00488     #define GETCOEFF(df, bcd) {                          \
00489       uInt sourhi=DFWORD(df, 0);                         \
00490       *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
00491       dpd2bcd8(bcd+1, sourhi>>10);                       \
00492       dpd2bcd83(bcd+4, sourhi);}
00493     #define GETWCOEFF(df, bcd) {                         \
00494       uInt sourhi=DFWWORD(df, 0);                        \
00495       uInt sourlo=DFWWORD(df, 1);                        \
00496       *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
00497       dpd2bcd8(bcd+1, sourhi>>8);                        \
00498       dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30));       \
00499       dpd2bcd8(bcd+7, sourlo>>20);                       \
00500       dpd2bcd8(bcd+10, sourlo>>10);                      \
00501       dpd2bcd83(bcd+13, sourlo);}
00502
00503     #elif DECPMAX==16
00504     #define GETCOEFF(df, bcd) {                          \
00505       uInt sourhi=DFWORD(df, 0);                         \
00506       uInt sourlo=DFWORD(df, 1);                         \
00507       *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
00508       dpd2bcd8(bcd+1, sourhi>>8);                        \
00509       dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30));       \
00510       dpd2bcd8(bcd+7, sourlo>>20);                       \
00511       dpd2bcd8(bcd+10, sourlo>>10);                      \
00512       dpd2bcd83(bcd+13, sourlo);}
00513     #define GETWCOEFF(df, bcd) {                         \
00514       uInt sourhi=DFWWORD(df, 0);                        \
00515       uInt sourmh=DFWWORD(df, 1);                        \
00516       uInt sourml=DFWWORD(df, 2);                        \
00517       uInt sourlo=DFWWORD(df, 3);                        \
00518       *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
00519       dpd2bcd8(bcd+1, sourhi>>4);                        \
00520       dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26));     \
00521       dpd2bcd8(bcd+7, sourmh>>16);                       \
00522       dpd2bcd8(bcd+10, sourmh>>6);                       \
00523       dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28));    \
00524       dpd2bcd8(bcd+16, sourml>>18);                      \
00525       dpd2bcd8(bcd+19, sourml>>8);                       \
00526       dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30));    \
00527       dpd2bcd8(bcd+25, sourlo>>20);                      \
00528       dpd2bcd8(bcd+28, sourlo>>10);                      \
00529       dpd2bcd83(bcd+31, sourlo);}
00530
00531     #elif DECPMAX==34
00532     #define GETCOEFF(df, bcd) {                          \
00533       uInt sourhi=DFWORD(df, 0);                         \
00534       uInt sourmh=DFWORD(df, 1);                         \
00535       uInt sourml=DFWORD(df, 2);                         \
00536       uInt sourlo=DFWORD(df, 3);                         \
00537       *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
00538       dpd2bcd8(bcd+1, sourhi>>4);                        \
00539       dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26));     \
00540       dpd2bcd8(bcd+7, sourmh>>16);                       \
00541       dpd2bcd8(bcd+10, sourmh>>6);                       \
00542       dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28));    \
00543       dpd2bcd8(bcd+16, sourml>>18);                      \
00544       dpd2bcd8(bcd+19, sourml>>8);                       \
00545       dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30));    \
00546       dpd2bcd8(bcd+25, sourlo>>20);                      \
00547       dpd2bcd8(bcd+28, sourlo>>10);                      \
00548       dpd2bcd83(bcd+31, sourlo);}
00549
00550       #define GETWCOEFF(df, bcd) {??} /* [should never be used]       */
00551     #endif
00552
00553     /* Macros to decode the coefficient in a finite decFloat *df into */
00554     /* a base-billion uInt array, with the least-significant          */
00555     /* 0-999999999 'digit' at offset 0.                               */
00556
00557     /* Decode the declets.  After extracting each one, it is decoded  */
00558     /* to binary using a table lookup.  Three tables are used; one    */
00559     /* the usual DPD to binary, the other two pre-multiplied by 1000  */
00560     /* and 1000000 to avoid multiplication during decode.  These      */
00561     /* tables can also be used for multiplying up the MSD as the DPD  */
00562     /* code for 0 through 9 is the identity.                          */
00563     #define DPD2BIN0 DPD2BIN         /* for prettier code             */
00564
00565     #if DECPMAX==7
00566     #define GETCOEFFBILL(df, buf) {                           \
00567       uInt sourhi=DFWORD(df, 0);                              \
00568       (buf)[0]=DPD2BIN0[sourhi&0x3ff]                         \
00569               +DPD2BINK[(sourhi>>10)&0x3ff]                   \
00570               +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
00571
00572     #elif DECPMAX==16
00573     #define GETCOEFFBILL(df, buf) {                           \
00574       uInt sourhi, sourlo;                                    \
00575       sourlo=DFWORD(df, 1);                                   \
00576       (buf)[0]=DPD2BIN0[sourlo&0x3ff]                         \
00577               +DPD2BINK[(sourlo>>10)&0x3ff]                   \
00578               +DPD2BINM[(sourlo>>20)&0x3ff];                  \
00579       sourhi=DFWORD(df, 0);                                   \
00580       (buf)[1]=DPD2BIN0[((sourhi<<2) | (sourlo>>30))&0x3ff]   \
00581               +DPD2BINK[(sourhi>>8)&0x3ff]                    \
00582               +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
00583
00584     #elif DECPMAX==34
00585     #define GETCOEFFBILL(df, buf) {                           \
00586       uInt sourhi, sourmh, sourml, sourlo;                    \
00587       sourlo=DFWORD(df, 3);                                   \
00588       (buf)[0]=DPD2BIN0[sourlo&0x3ff]                         \
00589               +DPD2BINK[(sourlo>>10)&0x3ff]                   \
00590               +DPD2BINM[(sourlo>>20)&0x3ff];                  \
00591       sourml=DFWORD(df, 2);                                   \
00592       (buf)[1]=DPD2BIN0[((sourml<<2) | (sourlo>>30))&0x3ff]   \
00593               +DPD2BINK[(sourml>>8)&0x3ff]                    \
00594               +DPD2BINM[(sourml>>18)&0x3ff];                  \
00595       sourmh=DFWORD(df, 1);                                   \
00596       (buf)[2]=DPD2BIN0[((sourmh<<4) | (sourml>>28))&0x3ff]   \
00597               +DPD2BINK[(sourmh>>6)&0x3ff]                    \
00598               +DPD2BINM[(sourmh>>16)&0x3ff];                  \
00599       sourhi=DFWORD(df, 0);                                   \
00600       (buf)[3]=DPD2BIN0[((sourhi<<6) | (sourmh>>26))&0x3ff]   \
00601               +DPD2BINK[(sourhi>>4)&0x3ff]                    \
00602               +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
00603
00604     #endif
00605
00606     /* Macros to decode the coefficient in a finite decFloat *df into */
00607     /* a base-thousand uInt array (of size DECLETS+1, to allow for    */
00608     /* the MSD), with the least-significant 0-999 'digit' at offset 0.*/
00609
00610     /* Decode the declets.  After extracting each one, it is decoded  */
00611     /* to binary using a table lookup.                                */
00612     #if DECPMAX==7
00613     #define GETCOEFFTHOU(df, buf) {                           \
00614       uInt sourhi=DFWORD(df, 0);                              \
00615       (buf)[0]=DPD2BIN[sourhi&0x3ff];                         \
00616       (buf)[1]=DPD2BIN[(sourhi>>10)&0x3ff];                   \
00617       (buf)[2]=DECCOMBMSD[sourhi>>26];}
00618
00619     #elif DECPMAX==16
00620     #define GETCOEFFTHOU(df, buf) {                           \
00621       uInt sourhi, sourlo;                                    \
00622       sourlo=DFWORD(df, 1);                                   \
00623       (buf)[0]=DPD2BIN[sourlo&0x3ff];                         \
00624       (buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff];                   \
00625       (buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff];                   \
00626       sourhi=DFWORD(df, 0);                                   \
00627       (buf)[3]=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff];   \
00628       (buf)[4]=DPD2BIN[(sourhi>>8)&0x3ff];                    \
00629       (buf)[5]=DECCOMBMSD[sourhi>>26];}
00630
00631     #elif DECPMAX==34
00632     #define GETCOEFFTHOU(df, buf) {                           \
00633       uInt sourhi, sourmh, sourml, sourlo;                    \
00634       sourlo=DFWORD(df, 3);                                   \
00635       (buf)[0]=DPD2BIN[sourlo&0x3ff];                         \
00636       (buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff];                   \
00637       (buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff];                   \
00638       sourml=DFWORD(df, 2);                                   \
00639       (buf)[3]=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff];   \
00640       (buf)[4]=DPD2BIN[(sourml>>8)&0x3ff];                    \
00641       (buf)[5]=DPD2BIN[(sourml>>18)&0x3ff];                   \
00642       sourmh=DFWORD(df, 1);                                   \
00643       (buf)[6]=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff];   \
00644       (buf)[7]=DPD2BIN[(sourmh>>6)&0x3ff];                    \
00645       (buf)[8]=DPD2BIN[(sourmh>>16)&0x3ff];                   \
00646       sourhi=DFWORD(df, 0);                                   \
00647       (buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff];   \
00648       (buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff];                   \
00649       (buf)[11]=DECCOMBMSD[sourhi>>26];}
00650     #endif
00651
00652
00653     /* Macros to decode the coefficient in a finite decFloat *df and  */
00654     /* add to a base-thousand uInt array (as for GETCOEFFTHOU).       */
00655     /* After the addition then most significant 'digit' in the array  */
00656     /* might have a value larger then 10 (with a maximum of 19).      */
00657     #if DECPMAX==7
00658     #define ADDCOEFFTHOU(df, buf) {                           \
00659       uInt sourhi=DFWORD(df, 0);                              \
00660       (buf)[0]+=DPD2BIN[sourhi&0x3ff];                        \
00661       if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
00662       (buf)[1]+=DPD2BIN[(sourhi>>10)&0x3ff];                  \
00663       if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
00664       (buf)[2]+=DECCOMBMSD[sourhi>>26];}
00665
00666     #elif DECPMAX==16
00667     #define ADDCOEFFTHOU(df, buf) {                           \
00668       uInt sourhi, sourlo;                                    \
00669       sourlo=DFWORD(df, 1);                                   \
00670       (buf)[0]+=DPD2BIN[sourlo&0x3ff];                        \
00671       if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
00672       (buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff];                  \
00673       if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
00674       (buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff];                  \
00675       if (buf[2]>999) {buf[2]-=1000; buf[3]++;}               \
00676       sourhi=DFWORD(df, 0);                                   \
00677       (buf)[3]+=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff];  \
00678       if (buf[3]>999) {buf[3]-=1000; buf[4]++;}               \
00679       (buf)[4]+=DPD2BIN[(sourhi>>8)&0x3ff];                   \
00680       if (buf[4]>999) {buf[4]-=1000; buf[5]++;}               \
00681       (buf)[5]+=DECCOMBMSD[sourhi>>26];}
00682
00683     #elif DECPMAX==34
00684     #define ADDCOEFFTHOU(df, buf) {                           \
00685       uInt sourhi, sourmh, sourml, sourlo;                    \
00686       sourlo=DFWORD(df, 3);                                   \
00687       (buf)[0]+=DPD2BIN[sourlo&0x3ff];                        \
00688       if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
00689       (buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff];                  \
00690       if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
00691       (buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff];                  \
00692       if (buf[2]>999) {buf[2]-=1000; buf[3]++;}               \
00693       sourml=DFWORD(df, 2);                                   \
00694       (buf)[3]+=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff];  \
00695       if (buf[3]>999) {buf[3]-=1000; buf[4]++;}               \
00696       (buf)[4]+=DPD2BIN[(sourml>>8)&0x3ff];                   \
00697       if (buf[4]>999) {buf[4]-=1000; buf[5]++;}               \
00698       (buf)[5]+=DPD2BIN[(sourml>>18)&0x3ff];                  \
00699       if (buf[5]>999) {buf[5]-=1000; buf[6]++;}               \
00700       sourmh=DFWORD(df, 1);                                   \
00701       (buf)[6]+=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff];  \
00702       if (buf[6]>999) {buf[6]-=1000; buf[7]++;}               \
00703       (buf)[7]+=DPD2BIN[(sourmh>>6)&0x3ff];                   \
00704       if (buf[7]>999) {buf[7]-=1000; buf[8]++;}               \
00705       (buf)[8]+=DPD2BIN[(sourmh>>16)&0x3ff];                  \
00706       if (buf[8]>999) {buf[8]-=1000; buf[9]++;}               \
00707       sourhi=DFWORD(df, 0);                                   \
00708       (buf)[9]+=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff];  \
00709       if (buf[9]>999) {buf[9]-=1000; buf[10]++;}              \
00710       (buf)[10]+=DPD2BIN[(sourhi>>4)&0x3ff];                  \
00711       if (buf[10]>999) {buf[10]-=1000; buf[11]++;}            \
00712       (buf)[11]+=DECCOMBMSD[sourhi>>26];}
00713     #endif
00714
00715
00716     /* Set a decFloat to the maximum positive finite number (Nmax)    */
00717     #if DECPMAX==7
00718     #define DFSETNMAX(df)            \
00719       {DFWORD(df, 0)=0x77f3fcff;}
00720     #elif DECPMAX==16
00721     #define DFSETNMAX(df)            \
00722       {DFWORD(df, 0)=0x77fcff3f;     \
00723        DFWORD(df, 1)=0xcff3fcff;}
00724     #elif DECPMAX==34
00725     #define DFSETNMAX(df)            \
00726       {DFWORD(df, 0)=0x77ffcff3;     \
00727        DFWORD(df, 1)=0xfcff3fcf;     \
00728        DFWORD(df, 2)=0xf3fcff3f;     \
00729        DFWORD(df, 3)=0xcff3fcff;}
00730     #endif
00731
00732   /* [end of format-dependent macros and constants]                   */
00733   #endif
00734
00735 #else
00736 //  #error decNumberLocal included more than once
00737 #endif
Généré le Mon Jul 20 18:22:14 2009 pour Decimal par doxygen 1.5.1-p1


Decimal: Liste des membres

  • Liste des classes
  • Membres de classe

bcdnum Liste des membres

Liste complète des membres de bcdnum, y compris les membres hérités :

exponent | bcdnum
lsd | bcdnum
msd | bcdnum
sign | bcdnum


Decimal: Liste des membres

  • Liste des classes
  • Membres de classe

decContext Liste des membres

Liste complète des membres de decContext, y compris les membres hérités :

clamp | decContext
digits | decContext
emax | decContext
emin | decContext
round | decContext
status | decContext
traps | decContext


Decimal: Liste des membres

  • Liste des classes
  • Membres de classe

DecFloat_ Liste des membres

Liste complète des membres de DecFloat_, y compris les membres hérités :

abs(const DecFloat_ &a) | DecFloat_ | [friend]
d | DecFloat_ | [private]
DecFloat_() | DecFloat_ | [inline]
DecFloat_(const char *_X_) | DecFloat_ | [inline]
DecFloat_(const string &_X_) | DecFloat_ | [inline]
DivideInteger(const DecFloat_ &x, const DecFloat_ &y) | DecFloat_ | [friend]
max(const DecFloat_ &x, const DecFloat_ &y) | DecFloat_ | [friend]
min(const DecFloat_ &x, const DecFloat_ &y) | DecFloat_ | [friend]
Normalize() | DecFloat_ | [inline]
operator *=(const DecFloat_ &a) | DecFloat_ | [inline]
operator%=(const DecFloat_ &a) | DecFloat_ | [inline]
operator+() | DecFloat_ | [inline]
operator+=(const DecFloat_ &a) | DecFloat_ | [inline]
operator-() | DecFloat_ | [inline]
operator-=(const DecFloat_ &a) | DecFloat_ | [inline]
operator/=(const DecFloat_ &a) | DecFloat_ | [inline]
operator<(const DecFloat_ &q1, const DecFloat_ &q2) | DecFloat_ | [friend]
operator=(const DecFloat_ &_X_) | DecFloat_ | [inline]
operator=(int _X_) | DecFloat_ | [inline]
operator=(double _X_) | DecFloat_ | [inline]
operator=(const char *_X_) | DecFloat_ | [inline]
operator=(const string _X_) | DecFloat_ | [inline]
operator==(const DecFloat_ &q1, const DecFloat_ &q2) | DecFloat_ | [friend]
operator>>(istream &f, DecFloat_ &b) | DecFloat_ | [friend]
pow(const DecFloat_ &x, const DecFloat_ &y) | DecFloat_ | [friend]
Quantize(const DecFloat_ &a) | DecFloat_ | [inline]
RemainderNear(const DecFloat_ &x, const DecFloat_ &y) | DecFloat_ | [friend]
Rescale(int a) | DecFloat_ | [inline]
SameQuantum(const DecFloat_ &a) | DecFloat_ | [inline]
sqrt(const DecFloat_ &x) | DecFloat_ | [friend]
ToChar(int dec) const | DecFloat_ | [inline]
ToChar() const | DecFloat_ | [inline]
ToIntegralValue() | DecFloat_ | [inline]
ToStr() const | DecFloat_ | [inline]
ToStr(int dec) const | DecFloat_ | [inline]
Trim() | DecFloat_ | [inline]
~DecFloat_() | DecFloat_ | [inline]


Decimal: Liste des membres

  • Liste des classes
  • Membres de classe

DecFloatContext Liste des membres

Liste complète des membres de DecFloatContext, y compris les membres hérités :

Clear_Conversion_syntax_status() | DecFloatContext | [inline]
ClearStatus() | DecFloatContext | [inline]
Conversion_syntax_status() | DecFloatContext | [inline]
DecFloatContext(int kind=DEC_INIT_BASE) | DecFloatContext | [inline]
get() | DecFloatContext | [inline]
Precision(int digits) | DecFloatContext | [inline]
Precision() | DecFloatContext | [inline]
set | DecFloatContext | [private]
setClamp(int x) | DecFloatContext | [inline]
setMaxExponent(int e) | DecFloatContext | [inline]
setMinExponent(int e) | DecFloatContext | [inline]
setRoundMode(rounding m) | DecFloatContext | [inline]
status() | DecFloatContext | [inline]
StatusToString() | DecFloatContext | [inline]


Decimal: Liste des membres

  • Liste des classes
  • Membres de classe

decNumber Liste des membres

Liste complète des membres de decNumber, y compris les membres hérités :

bits | decNumber
digits | decNumber
exponent | decNumber
lsu | decNumber


Decimal: Membres de classe

  • Liste des classes
  • Membres de classe
  • Tout
  • Fonctions
  • Variables
  • Fonctions associées
  • a
  • b
  • c
  • d
  • e
  • g
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • ~

Liste de tous les membres de classe avec liens vers les classes auxquelles ils appartiennent :

- a -

  • abs : DecFloat_

- b -

  • bits : decNumber

- c -

  • clamp : decContext
  • Clear_Conversion_syntax_status() : DecFloatContext
  • ClearStatus() : DecFloatContext
  • Conversion_syntax_status() : DecFloatContext

- d -

  • d : DecFloat_
  • DecFloat_() : DecFloat_
  • DecFloatContext() : DecFloatContext
  • digits : decContext , decNumber
  • DivideInteger : DecFloat_

- e -

  • emax : decContext
  • emin : decContext
  • exponent : decNumber , bcdnum

- g -

  • get() : DecFloatContext

- l -

  • lsd : bcdnum
  • lsu : decNumber

- m -

  • max : DecFloat_
  • min : DecFloat_
  • msd : bcdnum

- n -

  • Normalize() : DecFloat_

- o -

  • operator *=() : DecFloat_
  • operator%=() : DecFloat_
  • operator+() : DecFloat_
  • operator+=() : DecFloat_
  • operator-() : DecFloat_
  • operator-=() : DecFloat_
  • operator/=() : DecFloat_
  • operator< : DecFloat_
  • operator=() : DecFloat_
  • operator== : DecFloat_
  • operator>> : DecFloat_

- p -

  • pow : DecFloat_
  • Precision() : DecFloatContext

- q -

  • Quantize() : DecFloat_

- r -

  • RemainderNear : DecFloat_
  • Rescale() : DecFloat_
  • round : decContext

- s -

  • SameQuantum() : DecFloat_
  • set : DecFloatContext
  • setClamp() : DecFloatContext
  • setMaxExponent() : DecFloatContext
  • setMinExponent() : DecFloatContext
  • setRoundMode() : DecFloatContext
  • sign : bcdnum
  • sqrt : DecFloat_
  • status : decContext , DecFloatContext
  • StatusToString() : DecFloatContext

- t -

  • ToChar() : DecFloat_
  • ToIntegralValue() : DecFloat_
  • ToStr() : DecFloat_
  • traps : decContext
  • Trim() : DecFloat_

- ~ -

  • ~DecFloat_() : DecFloat_


Decimal: Membres de classe - Fonctions

  • Liste des classes
  • Membres de classe
  • Tout
  • Fonctions
  • Variables
  • Fonctions associées
  • c
  • d
  • g
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • ~

- c -

  • Clear_Conversion_syntax_status() : DecFloatContext
  • ClearStatus() : DecFloatContext
  • Conversion_syntax_status() : DecFloatContext

- d -

  • DecFloat_() : DecFloat_
  • DecFloatContext() : DecFloatContext

- g -

  • get() : DecFloatContext

- n -

  • Normalize() : DecFloat_

- o -

  • operator *=() : DecFloat_
  • operator%=() : DecFloat_
  • operator+() : DecFloat_
  • operator+=() : DecFloat_
  • operator-() : DecFloat_
  • operator-=() : DecFloat_
  • operator/=() : DecFloat_
  • operator=() : DecFloat_

- p -

  • Precision() : DecFloatContext

- q -

  • Quantize() : DecFloat_

- r -

  • Rescale() : DecFloat_

- s -

  • SameQuantum() : DecFloat_
  • setClamp() : DecFloatContext
  • setMaxExponent() : DecFloatContext
  • setMinExponent() : DecFloatContext
  • setRoundMode() : DecFloatContext
  • status() : DecFloatContext
  • StatusToString() : DecFloatContext

- t -

  • ToChar() : DecFloat_
  • ToIntegralValue() : DecFloat_
  • ToStr() : DecFloat_
  • Trim() : DecFloat_

- ~ -

  • ~DecFloat_() : DecFloat_


Decimal: Membres de classe - Fonctions associées

  • Liste des classes
  • Membres de classe
  • Tout
  • Fonctions
  • Variables
  • Fonctions associées

  • abs : DecFloat_
  • DivideInteger : DecFloat_
  • max : DecFloat_
  • min : DecFloat_
  • operator< : DecFloat_
  • operator== : DecFloat_
  • operator>> : DecFloat_
  • pow : DecFloat_
  • RemainderNear : DecFloat_
  • sqrt : DecFloat_


Decimal: Membres de classe - Variables

  • Liste des classes
  • Membres de classe
  • Tout
  • Fonctions
  • Variables
  • Fonctions associées

  • bits : decNumber
  • clamp : decContext
  • d : DecFloat_
  • digits : decNumber , decContext
  • emax : decContext
  • emin : decContext
  • exponent : decNumber , bcdnum
  • lsd : bcdnum
  • lsu : decNumber
  • msd : bcdnum
  • round : decContext
  • set : DecFloatContext
  • sign : bcdnum
  • status : decContext
  • traps : decContext


Decimal: Membres de classe

  • Tout
  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- _ -

  • _EnFr_ : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- l -

  • LI : decNumberLocal.h
  • LITEND : decContext.c
  • LN10 : decNumber.c
  • LN2 : decNumber.c
  • LNnn : decNumber.c
  • Long : decNumberLocal.h
  • LONGMUL32HI : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- m -

  • max() : DecFloat.hpp
  • MAXI : decNumberLocal.h
  • mfcone : decContext.c
  • mfctop : decContext.c
  • min() : DecFloat.hpp
  • MINI : decNumberLocal.h
  • MSUDIGITS : decNumberLocal.h
  • multies : decNumber.c


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- n -

  • NEEDTWO : decNumber.c
  • NUMISSPECIAL : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- o -

  • operator *() : DecFloat.hpp
  • operator!=() : DecFloat.hpp
  • operator%() : DecFloat.hpp
  • operator+() : DecFloat.hpp
  • operator-() : DecFloat.hpp
  • operator/() : DecFloat.hpp
  • operator<() : DecFloat.hpp
  • operator<<() : DecFloat.hpp
  • operator<=() : DecFloat.hpp
  • operator==() : DecFloat.hpp
  • operator>() : DecFloat.hpp
  • operator>=() : DecFloat.hpp
  • operator>>() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- a -

  • abs() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- b -

  • BADINT : decNumber.c
  • BCD2DPD : decNumberLocal.h
  • BIGEVEN : decNumber.c
  • BIGODD : decNumber.c
  • BILLION : decNumberLocal.h
  • BIN2BCD8 : decNumberLocal.h
  • BIN2DPD : decNumberLocal.h
  • Byte : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- c -

  • CHARMASK : decNumberLocal.h
  • COMPARE : decNumber.c
  • COMPMAX : decNumber.c
  • COMPMAXMAG : decNumber.c
  • COMPMIN : decNumber.c
  • COMPMINMAG : decNumber.c
  • COMPNAN : decNumber.c
  • COMPSIG : decNumber.c
  • COMPTOTAL : decNumber.c
  • Context : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- d -

  • D2N : decNumberLocal.h
  • D2U : decNumberLocal.h
  • d2utable : decNumberLocal.h , decNumber.c
  • DCML : DecFloat.hpp
  • DEC_Clamped : decContext.h
  • DEC_CLASS_NEG_INF : decContext.h
  • DEC_CLASS_NEG_NORMAL : decContext.h
  • DEC_CLASS_NEG_SUBNORMAL : decContext.h
  • DEC_CLASS_NEG_ZERO : decContext.h
  • DEC_CLASS_POS_INF : decContext.h
  • DEC_CLASS_POS_NORMAL : decContext.h
  • DEC_CLASS_POS_SUBNORMAL : decContext.h
  • DEC_CLASS_POS_ZERO : decContext.h
  • DEC_CLASS_QNAN : decContext.h
  • DEC_CLASS_SNAN : decContext.h
  • DEC_ClassString_NI : decContext.h
  • DEC_ClassString_NN : decContext.h
  • DEC_ClassString_NS : decContext.h
  • DEC_ClassString_NZ : decContext.h
  • DEC_ClassString_PI : decContext.h
  • DEC_ClassString_PN : decContext.h
  • DEC_ClassString_PS : decContext.h
  • DEC_ClassString_PZ : decContext.h
  • DEC_ClassString_QN : decContext.h
  • DEC_ClassString_SN : decContext.h
  • DEC_ClassString_UN : decContext.h
  • DEC_Condition_CS : decContext.h
  • DEC_Condition_DI : decContext.h
  • DEC_Condition_DU : decContext.h
  • DEC_Condition_DZ : decContext.h
  • DEC_Condition_IC : decContext.h
  • DEC_Condition_IE : decContext.h
  • DEC_Condition_IO : decContext.h
  • DEC_Condition_IS : decContext.h
  • DEC_Condition_Length : decContext.h
  • DEC_Condition_MU : decContext.h
  • DEC_Condition_OV : decContext.h
  • DEC_Condition_PA : decContext.h
  • DEC_Condition_RO : decContext.h
  • DEC_Condition_SU : decContext.h
  • DEC_Condition_UN : decContext.h
  • DEC_Condition_ZE : decContext.h
  • DEC_Conversion_syntax : decContext.h
  • DEC_Division_by_zero : decContext.h
  • DEC_Division_impossible : decContext.h
  • DEC_Division_undefined : decContext.h
  • DEC_English : DecFloat.hpp
  • DEC_Errors : decContext.h
  • DEC_French : DecFloat.hpp
  • DEC_IEEE_754_Division_by_zero : decContext.h
  • DEC_IEEE_754_Inexact : decContext.h
  • DEC_IEEE_754_Invalid_operation : decContext.h
  • DEC_IEEE_754_Overflow : decContext.h
  • DEC_IEEE_754_Underflow : decContext.h
  • DEC_IEEE_854_Division_by_zero : decContext.h
  • DEC_IEEE_854_Inexact : decContext.h
  • DEC_IEEE_854_Invalid_operation : decContext.h
  • DEC_IEEE_854_Overflow : decContext.h
  • DEC_IEEE_854_Underflow : decContext.h
  • DEC_Inexact : decContext.h
  • DEC_Information : decContext.h
  • DEC_INIT_BASE : decContext.h
  • DEC_INIT_DECDOUBLE : decContext.h
  • DEC_INIT_DECIMAL128 : decContext.h
  • DEC_INIT_DECIMAL32 : decContext.h
  • DEC_INIT_DECIMAL64 : decContext.h
  • DEC_INIT_DECQUAD : decContext.h
  • DEC_INIT_DECSINGLE : decContext.h
  • DEC_Insufficient_storage : decContext.h
  • DEC_Invalid_context : decContext.h
  • DEC_Invalid_operation : decContext.h
  • DEC_MAX_DIGITS : decContext.h
  • DEC_MAX_EMAX : decContext.h
  • DEC_MAX_EMIN : decContext.h
  • DEC_MAX_MATH : decContext.h
  • DEC_MIN_DIGITS : decContext.h
  • DEC_MIN_EMAX : decContext.h
  • DEC_MIN_EMIN : decContext.h
  • DEC_NaNs : decContext.h
  • DEC_Overflow : decContext.h
  • DEC_ROUND_05UP : decContext.h
  • DEC_ROUND_CEILING : decContext.h
  • DEC_ROUND_DEFAULT : decContext.h
  • DEC_ROUND_DOWN : decContext.h
  • DEC_ROUND_FLOOR : decContext.h
  • DEC_ROUND_HALF_DOWN : decContext.h
  • DEC_ROUND_HALF_EVEN : decContext.h
  • DEC_ROUND_HALF_UP : decContext.h
  • DEC_ROUND_MAX : decContext.h
  • DEC_ROUND_UP : decContext.h
  • DEC_Rounded : decContext.h
  • DEC_sNaN : decNumber.c
  • DEC_Subnormal : decContext.h
  • DEC_Underflow : decContext.h
  • decAddOp() : decNumber.c
  • DECALLOC : decNumberLocal.h
  • decApplyRound() : decNumber.c
  • DECAUTHOR : decNumber.h
  • decBiStr() : decNumber.c
  • DECBUFFER : decNumberLocal.h
  • DECCAUTHOR : decContext.h
  • DECCFULLNAME : decContext.h
  • DECCHECK : decNumberLocal.h
  • decCheckMath() : decNumber.c
  • decClass : decContext.h
  • DECCNAME : decContext.h
  • DECCOMBFROM : decNumberLocal.h
  • DECCOMBMSD : decNumberLocal.h
  • decCompare() : decNumber.c
  • decCompareOp() : decNumber.c
  • DECCONTEXT : decContext.h
  • decContextClearStatus() : decContext.c , decContext.h
  • decContextDefault() : decContext.c , decContext.h
  • decContextGetRounding() : decContext.c , decContext.h
  • decContextGetStatus() : decContext.c , decContext.h
  • decContextRestoreStatus() : decContext.c , decContext.h
  • decContextSaveStatus() : decContext.c , decContext.h
  • decContextSetRounding() : decContext.c , decContext.h
  • decContextSetStatus() : decContext.c , decContext.h
  • decContextSetStatusFromString() : decContext.c , decContext.h
  • decContextSetStatusFromStringQuiet() : decContext.c , decContext.h
  • decContextSetStatusQuiet() : decContext.c , decContext.h
  • DecContextStatusString() : DecFloat.hpp
  • decContextStatusToString() : decContext.c , decContext.h
  • decContextTestEndian() : decContext.c , decContext.h
  • decContextTestSavedStatus() : decContext.c , decContext.h
  • decContextTestStatus() : decContext.c , decContext.h
  • decContextZeroStatus() : decContext.c , decContext.h
  • decCopyFit() : decNumber.c
  • decDecap() : decNumber.c
  • decDivideOp() : decNumber.c
  • DECDPUN : decNumber.h
  • DecErrStatus() : DecFloat.hpp
  • decExpOp() : decNumber.c
  • DECEXTFLAG : decContext.h
  • decFinalize() : decNumber.c
  • decFinish : decNumber.c
  • DECFULLNAME : decNumber.h
  • decGetDigits() : decNumber.c
  • decGetInt() : decNumber.c
  • DECINF : decNumber.h
  • DECLITEND : decNumberLocal.h
  • decLnOp() : decNumber.c
  • DECMAXD2U : decNumberLocal.h
  • decMultiplyOp() : decNumber.c
  • DECNAME : decNumber.h
  • DECNAN : decNumber.h
  • decNaNs() : decNumber.c
  • DECNEG : decNumber.h
  • DECNLAUTHOR : decNumberLocal.h
  • DECNOINT : decNumberLocal.h
  • DECNUMBER : decNumber.h
  • decNumberAbs() : decNumber.h , decNumber.c
  • decNumberAdd() : decNumber.h , decNumber.c
  • decNumberAnd() : decNumber.h , decNumber.c
  • decNumberClass() : decNumber.c , decNumber.h
  • decNumberClassToString() : decNumber.h , decNumber.c
  • decNumberCompare() : decNumber.h , decNumber.c
  • decNumberCompareSignal() : decNumber.h , decNumber.c
  • decNumberCompareTotal() : decNumber.h , decNumber.c
  • decNumberCompareTotalMag() : decNumber.h , decNumber.c
  • decNumberCopy() : decNumber.h , decNumber.c
  • decNumberCopy_() : decNumber.h
  • decNumberCopyAbs() : decNumber.h , decNumber.c
  • decNumberCopyNegate() : decNumber.c , decNumber.h
  • decNumberCopySign() : decNumber.c , decNumber.h
  • decNumberDivide() : decNumber.h , decNumber.c
  • decNumberDivideInteger() : decNumber.h , decNumber.c
  • decNumberExp() : decNumber.h , decNumber.c
  • decNumberFMA() : decNumber.h , decNumber.c
  • decNumberFromInt32() : decNumber.h , decNumber.c
  • decNumberFromString() : decNumber.h , decNumber.c
  • decNumberFromUInt32() : decNumber.h , decNumber.c
  • decNumberGetBCD() : decNumber.h , decNumber.c
  • decNumberInvert() : decNumber.h , decNumber.c
  • decNumberIsCanonical : decNumber.h
  • decNumberIsFinite : decNumber.h
  • decNumberIsInfinite : decNumber.h
  • decNumberIsNaN : decNumber.h
  • decNumberIsNegative : decNumber.h
  • decNumberIsNormal() : decNumber.c , decNumber.h
  • decNumberIsQNaN : decNumber.h
  • decNumberIsSNaN : decNumber.h
  • decNumberIsSpecial : decNumber.h
  • decNumberIsSubnormal() : decNumber.c , decNumber.h
  • decNumberIsZero : decNumber.h
  • decNumberLn() : decNumber.h , decNumber.c
  • DECNUMBERLOC : decNumberLocal.h
  • decNumberLog10() : decNumber.c , decNumber.h
  • decNumberLogB() : decNumber.h , decNumber.c
  • decNumberMax() : decNumber.h , decNumber.c
  • decNumberMaxMag() : decNumber.c , decNumber.h
  • decNumberMin() : decNumber.h , decNumber.c
  • decNumberMinMag() : decNumber.h , decNumber.c
  • decNumberMinus() : decNumber.c , decNumber.h
  • decNumberMultiply() : decNumber.c , decNumber.h
  • decNumberNextMinus() : decNumber.c , decNumber.h
  • decNumberNextPlus() : decNumber.c , decNumber.h
  • decNumberNextToward() : decNumber.h , decNumber.c
  • decNumberNormalize() : decNumber.c , decNumber.h
  • decNumberOr() : decNumber.c , decNumber.h
  • decNumberPlus() : decNumber.h , decNumber.c
  • decNumberPower() : decNumber.h , decNumber.c
  • decNumberQuantize() : decNumber.c , decNumber.h
  • decNumberRadix : decNumber.h
  • decNumberReduce() : decNumber.c , decNumber.h
  • decNumberRemainder() : decNumber.c , decNumber.h
  • decNumberRemainderNear() : decNumber.h , decNumber.c
  • decNumberRescale() : decNumber.c , decNumber.h
  • decNumberRotate() : decNumber.c , decNumber.h
  • decNumberSameQuantum() : decNumber.c , decNumber.h
  • decNumberScaleB() : decNumber.c , decNumber.h
  • decNumberSetBCD() : decNumber.h , decNumber.c
  • decNumberShift() : decNumber.c , decNumber.h
  • decNumberSquareRoot() : decNumber.h , decNumber.c
  • decNumberSubtract() : decNumber.c , decNumber.h
  • decNumberToEngString() : decNumber.h , decNumber.c
  • decNumberToInt32() : decNumber.h , decNumber.c
  • decNumberToIntegralExact() : decNumber.c , decNumber.h
  • decNumberToIntegralValue() : decNumber.c , decNumber.h
  • decNumberToString() : decNumber.h , decNumber.c
  • decNumberToUInt32() : decNumber.h , decNumber.c
  • decNumberTrim() : decNumber.h , decNumber.c
  • decNumberUnit : decNumber.h
  • decNumberVersion() : decNumber.c , decNumber.h
  • decNumberXor() : decNumber.c , decNumber.h
  • decNumberZero() : decNumber.c , decNumber.h
  • DECNUMDIGITS : decNumber.h , DecFloat.hpp
  • DECNUMMAXE : decNumberLocal.h
  • DECNUMMAXP : decNumberLocal.h
  • DECNUMMINE : decNumberLocal.h
  • DECNUMUNITS : decNumber.h
  • DECPOWERS : decContext.c , decNumberLocal.h
  • decQuantizeOp() : decNumber.c
  • decReverse() : decNumber.c
  • decSetCoeff() : decNumber.c
  • decSetMaxValue() : decNumber.c
  • decSetOverflow() : decNumber.c
  • decSetSubnormal() : decNumber.c
  • decShiftToLeast() : decNumber.c
  • decShiftToMost() : decNumber.c
  • DECSNAN : decNumber.h
  • DECSPECIAL : decNumber.h
  • decStatus() : decNumber.c
  • DECSTICKYTAB : decContext.c , decNumberLocal.h
  • DECSUBSET : decContext.h
  • decToString() : decNumber.c
  • DECTRACE : decNumberLocal.h
  • decTrim() : decNumber.c
  • decUnitAddSub() : decNumber.c
  • decUnitCompare() : decNumber.c
  • DECUSE64 : decNumberLocal.h
  • DECVERB : decNumber.c
  • DECVERSION : decNumberLocal.h
  • DECWORDS : decNumberLocal.h
  • DECWWORDS : decNumberLocal.h
  • DFBYTE : decNumberLocal.h
  • DFISINF : decNumberLocal.h
  • DFISNAN : decNumberLocal.h
  • DFISQNAN : decNumberLocal.h
  • DFISSIGNED : decNumberLocal.h
  • DFISSNAN : decNumberLocal.h
  • DFISSPECIAL : decNumberLocal.h
  • DFWORD : decNumberLocal.h
  • DFWWORD : decNumberLocal.h
  • DIVIDE : decNumber.c
  • DIVIDEINT : decNumber.c
  • DivideInteger() : DecFloat.hpp
  • DPD2BCD8 : decNumberLocal.h
  • DPD2BIN : decNumberLocal.h
  • DPD2BINK : decNumberLocal.h
  • DPD2BINM : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- e -

  • eInt : decNumber.c
  • EXPISINF : decNumberLocal.h
  • EXPISNAN : decNumberLocal.h
  • EXPISSPECIAL : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- f -

  • FASTBASE : decNumber.c
  • FASTDIGS : decNumber.c
  • FASTLAZY : decNumber.c
  • FASTMUL : decNumber.c
  • Flag : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- i -

  • Int : decNumberLocal.h
  • ISZERO : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- p -

  • pow() : DecFloat.hpp
  • powers : decNumber.c


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- q -

  • QUOT10 : decNumber.c


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- r -

  • REMAINDER : decNumber.c
  • RemainderNear() : DecFloat.hpp
  • REMNEAR : decNumber.c
  • resmap : decNumber.c
  • ROUNDDOWN : decNumberLocal.h
  • ROUNDDOWN4 : decNumberLocal.h
  • rounding : decContext.h
  • ROUNDUP : decNumberLocal.h
  • ROUNDUP4 : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- s -

  • SD2U : decNumberLocal.h
  • Short : decNumberLocal.h
  • SPECIALARG : decNumber.c
  • SPECIALARGS : decNumber.c
  • sqrt() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- t -

  • TODIGIT : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- u -

  • uarrone : decNumber.c
  • UBFROMUI : decNumberLocal.h
  • UBFROMUS : decNumberLocal.h
  • UBTOUI : decNumberLocal.h
  • UBTOUS : decNumberLocal.h
  • uByte : decNumberLocal.h
  • ueInt : decNumber.c
  • uInt : decNumberLocal.h
  • uLong : decNumberLocal.h
  • Unit : decNumberLocal.h
  • uShort : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • _
  • a
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • o
  • p
  • q
  • r
  • s
  • t
  • u
  • x

Liste de tous les membres de fichier avec liens vers les fichiers auxquels ils appartiennent :

- x -

  • X10 : decNumberLocal.h
  • X100 : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • b
  • c
  • d
  • e
  • f
  • i
  • l
  • m
  • n
  • p
  • q
  • r
  • s
  • t
  • u
  • x

- b -

  • BADINT : decNumber.c
  • BIGEVEN : decNumber.c
  • BIGODD : decNumber.c
  • BILLION : decNumberLocal.h
  • Byte : decNumberLocal.h

- c -

  • CHARMASK : decNumberLocal.h
  • COMPARE : decNumber.c
  • COMPMAX : decNumber.c
  • COMPMAXMAG : decNumber.c
  • COMPMIN : decNumber.c
  • COMPMINMAG : decNumber.c
  • COMPNAN : decNumber.c
  • COMPSIG : decNumber.c
  • COMPTOTAL : decNumber.c

- d -

  • D2N : decNumberLocal.h
  • D2U : decNumberLocal.h
  • DEC_Clamped : decContext.h
  • DEC_ClassString_NI : decContext.h
  • DEC_ClassString_NN : decContext.h
  • DEC_ClassString_NS : decContext.h
  • DEC_ClassString_NZ : decContext.h
  • DEC_ClassString_PI : decContext.h
  • DEC_ClassString_PN : decContext.h
  • DEC_ClassString_PS : decContext.h
  • DEC_ClassString_PZ : decContext.h
  • DEC_ClassString_QN : decContext.h
  • DEC_ClassString_SN : decContext.h
  • DEC_ClassString_UN : decContext.h
  • DEC_Condition_CS : decContext.h
  • DEC_Condition_DI : decContext.h
  • DEC_Condition_DU : decContext.h
  • DEC_Condition_DZ : decContext.h
  • DEC_Condition_IC : decContext.h
  • DEC_Condition_IE : decContext.h
  • DEC_Condition_IO : decContext.h
  • DEC_Condition_IS : decContext.h
  • DEC_Condition_Length : decContext.h
  • DEC_Condition_MU : decContext.h
  • DEC_Condition_OV : decContext.h
  • DEC_Condition_PA : decContext.h
  • DEC_Condition_RO : decContext.h
  • DEC_Condition_SU : decContext.h
  • DEC_Condition_UN : decContext.h
  • DEC_Condition_ZE : decContext.h
  • DEC_Conversion_syntax : decContext.h
  • DEC_Division_by_zero : decContext.h
  • DEC_Division_impossible : decContext.h
  • DEC_Division_undefined : decContext.h
  • DEC_English : DecFloat.hpp
  • DEC_Errors : decContext.h
  • DEC_French : DecFloat.hpp
  • DEC_IEEE_754_Division_by_zero : decContext.h
  • DEC_IEEE_754_Inexact : decContext.h
  • DEC_IEEE_754_Invalid_operation : decContext.h
  • DEC_IEEE_754_Overflow : decContext.h
  • DEC_IEEE_754_Underflow : decContext.h
  • DEC_IEEE_854_Division_by_zero : decContext.h
  • DEC_IEEE_854_Inexact : decContext.h
  • DEC_IEEE_854_Invalid_operation : decContext.h
  • DEC_IEEE_854_Overflow : decContext.h
  • DEC_IEEE_854_Underflow : decContext.h
  • DEC_Inexact : decContext.h
  • DEC_Information : decContext.h
  • DEC_INIT_BASE : decContext.h
  • DEC_INIT_DECDOUBLE : decContext.h
  • DEC_INIT_DECIMAL128 : decContext.h
  • DEC_INIT_DECIMAL32 : decContext.h
  • DEC_INIT_DECIMAL64 : decContext.h
  • DEC_INIT_DECQUAD : decContext.h
  • DEC_INIT_DECSINGLE : decContext.h
  • DEC_Insufficient_storage : decContext.h
  • DEC_Invalid_context : decContext.h
  • DEC_Invalid_operation : decContext.h
  • DEC_MAX_DIGITS : decContext.h
  • DEC_MAX_EMAX : decContext.h
  • DEC_MAX_EMIN : decContext.h
  • DEC_MAX_MATH : decContext.h
  • DEC_MIN_DIGITS : decContext.h
  • DEC_MIN_EMAX : decContext.h
  • DEC_MIN_EMIN : decContext.h
  • DEC_NaNs : decContext.h
  • DEC_Overflow : decContext.h
  • DEC_ROUND_DEFAULT : decContext.h
  • DEC_Rounded : decContext.h
  • DEC_sNaN : decNumber.c
  • DEC_Subnormal : decContext.h
  • DEC_Underflow : decContext.h
  • DECALLOC : decNumberLocal.h
  • DECAUTHOR : decNumber.h
  • DECBUFFER : decNumberLocal.h
  • DECCAUTHOR : decContext.h
  • DECCFULLNAME : decContext.h
  • DECCHECK : decNumberLocal.h
  • DECCNAME : decContext.h
  • DECCONTEXT : decContext.h
  • DECDPUN : decNumber.h
  • DECEXTFLAG : decContext.h
  • decFinish : decNumber.c
  • DECFULLNAME : decNumber.h
  • DECINF : decNumber.h
  • DECLITEND : decNumberLocal.h
  • DECMAXD2U : decNumberLocal.h
  • DECNAME : decNumber.h
  • DECNAN : decNumber.h
  • DECNEG : decNumber.h
  • DECNLAUTHOR : decNumberLocal.h
  • DECNOINT : decNumberLocal.h
  • DECNUMBER : decNumber.h
  • decNumberIsCanonical : decNumber.h
  • decNumberIsFinite : decNumber.h
  • decNumberIsInfinite : decNumber.h
  • decNumberIsNaN : decNumber.h
  • decNumberIsNegative : decNumber.h
  • decNumberIsQNaN : decNumber.h
  • decNumberIsSNaN : decNumber.h
  • decNumberIsSpecial : decNumber.h
  • decNumberIsZero : decNumber.h
  • DECNUMBERLOC : decNumberLocal.h
  • decNumberRadix : decNumber.h
  • decNumberUnit : decNumber.h
  • DECNUMDIGITS : decNumber.h , DecFloat.hpp
  • DECNUMMAXE : decNumberLocal.h
  • DECNUMMAXP : decNumberLocal.h
  • DECNUMMINE : decNumberLocal.h
  • DECNUMUNITS : decNumber.h
  • DECSNAN : decNumber.h
  • DECSPECIAL : decNumber.h
  • DECSUBSET : decContext.h
  • DECTRACE : decNumberLocal.h
  • DECUSE64 : decNumberLocal.h
  • DECVERB : decNumber.c
  • DECVERSION : decNumberLocal.h
  • DECWORDS : decNumberLocal.h
  • DECWWORDS : decNumberLocal.h
  • DFBYTE : decNumberLocal.h
  • DFISINF : decNumberLocal.h
  • DFISNAN : decNumberLocal.h
  • DFISQNAN : decNumberLocal.h
  • DFISSIGNED : decNumberLocal.h
  • DFISSNAN : decNumberLocal.h
  • DFISSPECIAL : decNumberLocal.h
  • DFWORD : decNumberLocal.h
  • DFWWORD : decNumberLocal.h
  • DIVIDE : decNumber.c
  • DIVIDEINT : decNumber.c

- e -

  • eInt : decNumber.c
  • EXPISINF : decNumberLocal.h
  • EXPISNAN : decNumberLocal.h
  • EXPISSPECIAL : decNumberLocal.h

- f -

  • FASTBASE : decNumber.c
  • FASTDIGS : decNumber.c
  • FASTLAZY : decNumber.c
  • FASTMUL : decNumber.c
  • Flag : decNumberLocal.h

- i -

  • Int : decNumberLocal.h
  • ISZERO : decNumberLocal.h

- l -

  • LITEND : decContext.c
  • LN10 : decNumber.c
  • LN2 : decNumber.c
  • Long : decNumberLocal.h
  • LONGMUL32HI : decNumberLocal.h

- m -

  • MAXI : decNumberLocal.h
  • MINI : decNumberLocal.h
  • MSUDIGITS : decNumberLocal.h

- n -

  • NEEDTWO : decNumber.c
  • NUMISSPECIAL : decNumberLocal.h

- p -

  • powers : decNumber.c

- q -

  • QUOT10 : decNumber.c

- r -

  • REMAINDER : decNumber.c
  • REMNEAR : decNumber.c
  • ROUNDDOWN : decNumberLocal.h
  • ROUNDDOWN4 : decNumberLocal.h
  • ROUNDUP : decNumberLocal.h
  • ROUNDUP4 : decNumberLocal.h

- s -

  • SD2U : decNumberLocal.h
  • Short : decNumberLocal.h
  • SPECIALARG : decNumber.c
  • SPECIALARGS : decNumber.c

- t -

  • TODIGIT : decNumberLocal.h

- u -

  • UBFROMUI : decNumberLocal.h
  • UBFROMUS : decNumberLocal.h
  • UBTOUI : decNumberLocal.h
  • UBTOUS : decNumberLocal.h
  • uByte : decNumberLocal.h
  • ueInt : decNumber.c
  • uInt : decNumberLocal.h
  • uLong : decNumberLocal.h
  • Unit : decNumberLocal.h
  • uShort : decNumberLocal.h

- x -

  • X10 : decNumberLocal.h
  • X100 : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros

  • decClass : decContext.h
  • rounding : decContext.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros

  • DEC_CLASS_NEG_INF : decContext.h
  • DEC_CLASS_NEG_NORMAL : decContext.h
  • DEC_CLASS_NEG_SUBNORMAL : decContext.h
  • DEC_CLASS_NEG_ZERO : decContext.h
  • DEC_CLASS_POS_INF : decContext.h
  • DEC_CLASS_POS_NORMAL : decContext.h
  • DEC_CLASS_POS_SUBNORMAL : decContext.h
  • DEC_CLASS_POS_ZERO : decContext.h
  • DEC_CLASS_QNAN : decContext.h
  • DEC_CLASS_SNAN : decContext.h
  • DEC_ROUND_05UP : decContext.h
  • DEC_ROUND_CEILING : decContext.h
  • DEC_ROUND_DOWN : decContext.h
  • DEC_ROUND_FLOOR : decContext.h
  • DEC_ROUND_HALF_DOWN : decContext.h
  • DEC_ROUND_HALF_EVEN : decContext.h
  • DEC_ROUND_HALF_UP : decContext.h
  • DEC_ROUND_MAX : decContext.h
  • DEC_ROUND_UP : decContext.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • a
  • d
  • m
  • o
  • p
  • r
  • s

- a -

  • abs() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • a
  • d
  • m
  • o
  • p
  • r
  • s

- m -

  • max() : DecFloat.hpp
  • min() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • a
  • d
  • m
  • o
  • p
  • r
  • s

- o -

  • operator *() : DecFloat.hpp
  • operator!=() : DecFloat.hpp
  • operator%() : DecFloat.hpp
  • operator+() : DecFloat.hpp
  • operator-() : DecFloat.hpp
  • operator/() : DecFloat.hpp
  • operator<() : DecFloat.hpp
  • operator<<() : DecFloat.hpp
  • operator<=() : DecFloat.hpp
  • operator==() : DecFloat.hpp
  • operator>() : DecFloat.hpp
  • operator>=() : DecFloat.hpp
  • operator>>() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • a
  • d
  • m
  • o
  • p
  • r
  • s

- d -

  • decAddOp() : decNumber.c
  • decApplyRound() : decNumber.c
  • decBiStr() : decNumber.c
  • decCheckMath() : decNumber.c
  • decCompare() : decNumber.c
  • decCompareOp() : decNumber.c
  • decContextClearStatus() : decContext.c , decContext.h
  • decContextDefault() : decContext.c , decContext.h
  • decContextGetRounding() : decContext.h , decContext.c
  • decContextGetStatus() : decContext.c , decContext.h
  • decContextRestoreStatus() : decContext.c , decContext.h
  • decContextSaveStatus() : decContext.h , decContext.c
  • decContextSetRounding() : decContext.h , decContext.c
  • decContextSetStatus() : decContext.c , decContext.h
  • decContextSetStatusFromString() : decContext.c , decContext.h
  • decContextSetStatusFromStringQuiet() : decContext.c , decContext.h
  • decContextSetStatusQuiet() : decContext.c , decContext.h
  • DecContextStatusString() : DecFloat.hpp
  • decContextStatusToString() : decContext.c , decContext.h
  • decContextTestEndian() : decContext.c , decContext.h
  • decContextTestSavedStatus() : decContext.c , decContext.h
  • decContextTestStatus() : decContext.c , decContext.h
  • decContextZeroStatus() : decContext.h , decContext.c
  • decCopyFit() : decNumber.c
  • decDecap() : decNumber.c
  • decDivideOp() : decNumber.c
  • DecErrStatus() : DecFloat.hpp
  • decExpOp() : decNumber.c
  • decFinalize() : decNumber.c
  • decGetDigits() : decNumber.c
  • decGetInt() : decNumber.c
  • decLnOp() : decNumber.c
  • decMultiplyOp() : decNumber.c
  • decNaNs() : decNumber.c
  • decNumberAbs() : decNumber.h , decNumber.c
  • decNumberAdd() : decNumber.h , decNumber.c
  • decNumberAnd() : decNumber.h , decNumber.c
  • decNumberClass() : decNumber.h , decNumber.c
  • decNumberClassToString() : decNumber.h , decNumber.c
  • decNumberCompare() : decNumber.h , decNumber.c
  • decNumberCompareSignal() : decNumber.h , decNumber.c
  • decNumberCompareTotal() : decNumber.h , decNumber.c
  • decNumberCompareTotalMag() : decNumber.c , decNumber.h
  • decNumberCopy() : decNumber.h , decNumber.c
  • decNumberCopy_() : decNumber.h
  • decNumberCopyAbs() : decNumber.h , decNumber.c
  • decNumberCopyNegate() : decNumber.h , decNumber.c
  • decNumberCopySign() : decNumber.h , decNumber.c
  • decNumberDivide() : decNumber.h , decNumber.c
  • decNumberDivideInteger() : decNumber.h , decNumber.c
  • decNumberExp() : decNumber.h , decNumber.c
  • decNumberFMA() : decNumber.c , decNumber.h
  • decNumberFromInt32() : decNumber.h , decNumber.c
  • decNumberFromString() : decNumber.c , decNumber.h
  • decNumberFromUInt32() : decNumber.h , decNumber.c
  • decNumberGetBCD() : decNumber.h , decNumber.c
  • decNumberInvert() : decNumber.h , decNumber.c
  • decNumberIsNormal() : decNumber.h , decNumber.c
  • decNumberIsSubnormal() : decNumber.h , decNumber.c
  • decNumberLn() : decNumber.c , decNumber.h
  • decNumberLog10() : decNumber.c , decNumber.h
  • decNumberLogB() : decNumber.h , decNumber.c
  • decNumberMax() : decNumber.c , decNumber.h
  • decNumberMaxMag() : decNumber.h , decNumber.c
  • decNumberMin() : decNumber.h , decNumber.c
  • decNumberMinMag() : decNumber.c , decNumber.h
  • decNumberMinus() : decNumber.h , decNumber.c
  • decNumberMultiply() : decNumber.h , decNumber.c
  • decNumberNextMinus() : decNumber.h , decNumber.c
  • decNumberNextPlus() : decNumber.h , decNumber.c
  • decNumberNextToward() : decNumber.h , decNumber.c
  • decNumberNormalize() : decNumber.c , decNumber.h
  • decNumberOr() : decNumber.c , decNumber.h
  • decNumberPlus() : decNumber.h , decNumber.c
  • decNumberPower() : decNumber.h , decNumber.c
  • decNumberQuantize() : decNumber.h , decNumber.c
  • decNumberReduce() : decNumber.h , decNumber.c
  • decNumberRemainder() : decNumber.c , decNumber.h
  • decNumberRemainderNear() : decNumber.h , decNumber.c
  • decNumberRescale() : decNumber.c , decNumber.h
  • decNumberRotate() : decNumber.h , decNumber.c
  • decNumberSameQuantum() : decNumber.h , decNumber.c
  • decNumberScaleB() : decNumber.c , decNumber.h
  • decNumberSetBCD() : decNumber.h , decNumber.c
  • decNumberShift() : decNumber.c , decNumber.h
  • decNumberSquareRoot() : decNumber.h , decNumber.c
  • decNumberSubtract() : decNumber.h , decNumber.c
  • decNumberToEngString() : decNumber.h , decNumber.c
  • decNumberToInt32() : decNumber.h , decNumber.c
  • decNumberToIntegralExact() : decNumber.c , decNumber.h
  • decNumberToIntegralValue() : decNumber.c , decNumber.h
  • decNumberToString() : decNumber.h , decNumber.c
  • decNumberToUInt32() : decNumber.h , decNumber.c
  • decNumberTrim() : decNumber.h , decNumber.c
  • decNumberVersion() : decNumber.h , decNumber.c
  • decNumberXor() : decNumber.h , decNumber.c
  • decNumberZero() : decNumber.c , decNumber.h
  • decQuantizeOp() : decNumber.c
  • decReverse() : decNumber.c
  • decSetCoeff() : decNumber.c
  • decSetMaxValue() : decNumber.c
  • decSetOverflow() : decNumber.c
  • decSetSubnormal() : decNumber.c
  • decShiftToLeast() : decNumber.c
  • decShiftToMost() : decNumber.c
  • decStatus() : decNumber.c
  • decToString() : decNumber.c
  • decTrim() : decNumber.c
  • decUnitAddSub() : decNumber.c
  • decUnitCompare() : decNumber.c
  • DivideInteger() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • a
  • d
  • m
  • o
  • p
  • r
  • s

- p -

  • pow() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • a
  • d
  • m
  • o
  • p
  • r
  • s

- r -

  • RemainderNear() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros
  • a
  • d
  • m
  • o
  • p
  • r
  • s

- s -

  • sqrt() : DecFloat.hpp


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros

  • DCML : DecFloat.hpp
  • LI : decNumberLocal.h


Decimal: Membres de classe

  • Fonctions
  • Variables
  • Définition de type
  • Énumérations
  • Valeurs énumérées
  • Macros

  • _EnFr_ : DecFloat.hpp
  • BCD2DPD : decNumberLocal.h
  • BIN2BCD8 : decNumberLocal.h
  • BIN2DPD : decNumberLocal.h
  • Context : DecFloat.hpp
  • d2utable : decNumberLocal.h , decNumber.c
  • DECCOMBFROM : decNumberLocal.h
  • DECCOMBMSD : decNumberLocal.h
  • DECPOWERS : decContext.c , decNumberLocal.h
  • DECSTICKYTAB : decNumberLocal.h , decContext.c
  • DPD2BCD8 : decNumberLocal.h
  • DPD2BIN : decNumberLocal.h
  • DPD2BINK : decNumberLocal.h
  • DPD2BINM : decNumberLocal.h
  • LNnn : decNumber.c
  • mfcone : decContext.c
  • mfctop : decContext.c
  • multies : decNumber.c
  • resmap : decNumber.c
  • uarrone : decNumber.c