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

decNumberdecNumberFromInt32 (decNumber *, int32_t)
decNumberdecNumberFromUInt32 (decNumber *, uint32_t)
decNumberdecNumberFromString (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 *)
decNumberdecNumberSetBCD (decNumber *, const uint8_t *, uint32_t)
decNumberdecNumberAbs (decNumber *, const decNumber *, decContext *)
decNumberdecNumberAdd (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberAnd (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberCompare (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberCompareSignal (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberCompareTotal (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberCompareTotalMag (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberDivide (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberDivideInteger (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberExp (decNumber *, const decNumber *, decContext *)
decNumberdecNumberFMA (decNumber *, const decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberInvert (decNumber *, const decNumber *, decContext *)
decNumberdecNumberLn (decNumber *, const decNumber *, decContext *)
decNumberdecNumberLogB (decNumber *, const decNumber *, decContext *)
decNumberdecNumberLog10 (decNumber *, const decNumber *, decContext *)
decNumberdecNumberMax (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberMaxMag (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberMin (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberMinMag (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberMinus (decNumber *, const decNumber *, decContext *)
decNumberdecNumberMultiply (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberNormalize (decNumber *, const decNumber *, decContext *)
decNumberdecNumberOr (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberPlus (decNumber *, const decNumber *, decContext *)
decNumberdecNumberPower (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberQuantize (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberReduce (decNumber *, const decNumber *, decContext *)
decNumberdecNumberRemainder (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberRemainderNear (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberRescale (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberRotate (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberSameQuantum (decNumber *, const decNumber *, const decNumber *)
decNumberdecNumberScaleB (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberShift (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberSquareRoot (decNumber *, const decNumber *, decContext *)
decNumberdecNumberSubtract (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberToIntegralExact (decNumber *, const decNumber *, decContext *)
decNumberdecNumberToIntegralValue (decNumber *, const decNumber *, decContext *)
decNumberdecNumberXor (decNumber *, const decNumber *, const decNumber *, decContext *)
enum decClass decNumberClass (const decNumber *, decContext *)
const char * decNumberClassToString (enum decClass)
decNumberdecNumberCopy (decNumber *, const decNumber *)
decNumberdecNumberCopyAbs (decNumber *, const decNumber *)
decNumberdecNumberCopyNegate (decNumber *, const decNumber *)
decNumberdecNumberCopySign (decNumber *, const decNumber *, const decNumber *)
decNumberdecNumberNextMinus (decNumber *, const decNumber *, decContext *)
decNumberdecNumberNextPlus (decNumber *, const decNumber *, decContext *)
decNumberdecNumberNextToward (decNumber *, const decNumber *, const decNumber *, decContext *)
decNumberdecNumberTrim (decNumber *)
const char * decNumberVersion (void)
decNumberdecNumberZero (decNumber *)
decNumberdecNumberCopy_ (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


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