diff options
author | bje <bje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-29 00:33:22 +0000 |
---|---|---|
committer | bje <bje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-29 00:33:22 +0000 |
commit | 2bdb7dc9687774660e04a943e0ca382c47d14de6 (patch) | |
tree | 9ce194cc5467e65c729657e8e356f5d17eef3a16 /libdecnumber | |
parent | 8611e632761e9657da3a47854e1633746d9437c5 (diff) | |
download | gcc-2bdb7dc9687774660e04a943e0ca382c47d14de6.tar.gz |
* decNumber.c, decNumber.h, decNumberLocal.h, decDouble.c,
decDouble.h, decSingle.c, decContext.c, decSingle.h, decPacked.c,
decCommon.c, decContext.h, decQuad.c, decPacked.h, decQuad.h,
decDPD.h, decBasic.c: Upgrade to decNumber 3.61.
* dpd/decimal128.h, dpd/decimal32.c, dpd/decimal32.h,
dpd/decimal64.c, dpd/decimal128.c, dpd/decimal64.h: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145222 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libdecnumber')
-rw-r--r-- | libdecnumber/ChangeLog | 9 | ||||
-rw-r--r-- | libdecnumber/decBasic.c | 911 | ||||
-rw-r--r-- | libdecnumber/decCommon.c | 431 | ||||
-rw-r--r-- | libdecnumber/decContext.c | 83 | ||||
-rw-r--r-- | libdecnumber/decContext.h | 82 | ||||
-rw-r--r-- | libdecnumber/decDPD.h | 45 | ||||
-rw-r--r-- | libdecnumber/decDouble.c | 174 | ||||
-rw-r--r-- | libdecnumber/decDouble.h | 25 | ||||
-rw-r--r-- | libdecnumber/decNumber.c | 866 | ||||
-rw-r--r-- | libdecnumber/decNumber.h | 6 | ||||
-rw-r--r-- | libdecnumber/decNumberLocal.h | 241 | ||||
-rw-r--r-- | libdecnumber/decPacked.c | 24 | ||||
-rw-r--r-- | libdecnumber/decPacked.h | 14 | ||||
-rw-r--r-- | libdecnumber/decQuad.c | 170 | ||||
-rw-r--r-- | libdecnumber/decQuad.h | 49 | ||||
-rw-r--r-- | libdecnumber/decSingle.c | 53 | ||||
-rw-r--r-- | libdecnumber/decSingle.h | 20 | ||||
-rw-r--r-- | libdecnumber/dpd/decimal128.c | 119 | ||||
-rw-r--r-- | libdecnumber/dpd/decimal128.h | 16 | ||||
-rw-r--r-- | libdecnumber/dpd/decimal32.c | 83 | ||||
-rw-r--r-- | libdecnumber/dpd/decimal32.h | 14 | ||||
-rw-r--r-- | libdecnumber/dpd/decimal64.c | 133 | ||||
-rw-r--r-- | libdecnumber/dpd/decimal64.h | 14 |
23 files changed, 1971 insertions, 1611 deletions
diff --git a/libdecnumber/ChangeLog b/libdecnumber/ChangeLog index 21943b9e9ae..d49bfb5a7d5 100644 --- a/libdecnumber/ChangeLog +++ b/libdecnumber/ChangeLog @@ -1,3 +1,12 @@ +2009-03-29 Ben Elliston <bje@au.ibm.com> + + * decNumber.c, decNumber.h, decNumberLocal.h, decDouble.c, + decDouble.h, decSingle.c, decContext.c, decSingle.h, decPacked.c, + decCommon.c, decContext.h, decQuad.c, decPacked.h, decQuad.h, + decDPD.h, decBasic.c: Upgrade to decNumber 3.61. + * dpd/decimal128.h, dpd/decimal32.c, dpd/decimal32.h, + dpd/decimal64.c, dpd/decimal128.c, dpd/decimal64.h: Likewise. + 2009-02-10 Joseph Myers <joseph@codesourcery.com> * Makefile.in (clean): Don't remove makedepend$(EXEEXT). diff --git a/libdecnumber/decBasic.c b/libdecnumber/decBasic.c index fddba979053..06aa8bae320 100644 --- a/libdecnumber/decBasic.c +++ b/libdecnumber/decBasic.c @@ -32,8 +32,8 @@ /* decBasic.c -- common base code for Basic decimal types */ /* ------------------------------------------------------------------ */ /* This module comprises code that is shared between decDouble and */ -/* decQuad (but not decSingle). The main arithmetic operations are */ -/* here (Add, Subtract, Multiply, FMA, and Division operators). */ +/* decQuad (but not decSingle). The main arithmetic operations are */ +/* here (Add, Subtract, Multiply, FMA, and Division operators). */ /* */ /* Unlike decNumber, parameterization takes place at compile time */ /* rather than at runtime. The parameters are set in the decDouble.c */ @@ -59,7 +59,7 @@ #define DIVIDE 0x80000000 /* Divide operations [as flags] */ #define REMAINDER 0x40000000 /* .. */ #define DIVIDEINT 0x20000000 /* .. */ -#define REMNEAR 0x10000000 /* .. */ +#define REMNEAR 0x10000000 /* .. */ /* Private functions (local, used only by routines in this module) */ static decFloat *decDivide(decFloat *, const decFloat *, @@ -81,7 +81,7 @@ static uInt decToInt32(const decFloat *, decContext *, enum rounding, /* decCanonical -- copy a decFloat, making canonical */ /* */ /* result gets the canonicalized df */ -/* df is the decFloat to copy and make canonical */ +/* df is the decFloat to copy and make canonical */ /* returns result */ /* */ /* This is exposed via decFloatCanonical for Double and Quad only. */ @@ -141,14 +141,14 @@ static decFloat * decCanonical(decFloat *result, const decFloat *df) { uoff-=32; dpd|=encode<<(10-uoff); /* get pending bits */ } - dpd&=0x3ff; /* clear uninteresting bits */ + dpd&=0x3ff; /* clear uninteresting bits */ if (dpd<0x16e) continue; /* must be canonical */ canon=BIN2DPD[DPD2BIN[dpd]]; /* determine canonical declet */ if (canon==dpd) continue; /* have canonical declet */ /* need to replace declet */ if (uoff>=10) { /* all within current word */ encode&=~(0x3ff<<(uoff-10)); /* clear the 10 bits ready for replace */ - encode|=canon<<(uoff-10); /* insert the canonical form */ + encode|=canon<<(uoff-10); /* insert the canonical form */ DFWORD(result, inword)=encode; /* .. and save */ continue; } @@ -167,16 +167,16 @@ static decFloat * decCanonical(decFloat *result, const decFloat *df) { /* decDivide -- divide operations */ /* */ /* result gets the result of dividing dfl by dfr: */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ -/* op is the operation selector */ +/* op is the operation selector */ /* returns result */ /* */ /* op is one of DIVIDE, REMAINDER, DIVIDEINT, or REMNEAR. */ /* ------------------------------------------------------------------ */ #define DIVCOUNT 0 /* 1 to instrument subtractions counter */ -#define DIVBASE BILLION /* the base used for divide */ +#define DIVBASE ((uInt)BILLION) /* the base used for divide */ #define DIVOPLEN DECPMAX9 /* operand length ('digits' base 10**9) */ #define DIVACCLEN (DIVOPLEN*3) /* accumulator length (ditto) */ static decFloat * decDivide(decFloat *result, const decFloat *dfl, @@ -184,17 +184,18 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, decFloat quotient; /* for remainders */ bcdnum num; /* for final conversion */ uInt acc[DIVACCLEN]; /* coefficent in base-billion .. */ - uInt div[DIVOPLEN]; /* divisor in base-billion .. */ + uInt div[DIVOPLEN]; /* divisor in base-billion .. */ uInt quo[DIVOPLEN+1]; /* quotient in base-billion .. */ - uByte bcdacc[(DIVOPLEN+1)*9+2]; /* for quotient in BCD, +1, +1 */ + uByte bcdacc[(DIVOPLEN+1)*9+2]; /* for quotient in BCD, +1, +1 */ uInt *msua, *msud, *msuq; /* -> msu of acc, div, and quo */ Int divunits, accunits; /* lengths */ Int quodigits; /* digits in quotient */ uInt *lsua, *lsuq; /* -> current acc and quo lsus */ Int length, multiplier; /* work */ uInt carry, sign; /* .. */ - uInt *ua, *ud, *uq; /* .. */ - uByte *ub; /* .. */ + uInt *ua, *ud, *uq; /* .. */ + uByte *ub; /* .. */ + uInt uiwork; /* for macros */ uInt divtop; /* top unit of div adjusted for estimating */ #if DIVCOUNT static uInt maxcount=0; /* worst-seen subtractions count */ @@ -235,7 +236,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, if (op&(REMAINDER|REMNEAR)) return decInvalid(result, set); /* bad rem */ set->status|=DEC_Division_by_zero; DFWORD(result, 0)=num.sign; - return decInfinity(result, result); /* x/0 -> signed Infinity */ + return decInfinity(result, result); /* x/0 -> signed Infinity */ } num.exponent=GETEXPUN(dfl)-GETEXPUN(dfr); /* ideal exponent */ if (DFISZERO(dfl)) { /* 0/x (x!=0) */ @@ -246,7 +247,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, DFWORD(result, 0)|=num.sign; /* add sign */ return result; } - if (!(op&DIVIDE)) { /* a remainder */ + if (!(op&DIVIDE)) { /* a remainder */ /* exponent is the minimum of the operands */ num.exponent=MINI(GETEXPUN(dfl), GETEXPUN(dfr)); /* if the result is zero the sign shall be sign of dfl */ @@ -289,7 +290,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, #endif /* set msu and lsu pointers */ - msua=acc+DIVACCLEN-1; /* [leading zeros removed below] */ + msua=acc+DIVACCLEN-1; /* [leading zeros removed below] */ msuq=quo+DIVOPLEN; /*[loop for div will terminate because operands are non-zero] */ for (msud=div+DIVOPLEN-1; *msud==0;) msud--; @@ -298,7 +299,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, /* This moves one position towards the least possible for each */ /* iteration */ divunits=(Int)(msud-div+1); /* precalculate */ - lsua=msua-divunits+1; /* initial working lsu of acc */ + lsua=msua-divunits+1; /* initial working lsu of acc */ lsuq=msuq; /* and of quo */ /* set up the estimator for the multiplier; this is the msu of div, */ @@ -371,7 +372,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, for (ud=msud, ua=msua; ud>div; ud--, ua--) if (*ud!=*ua) break; /* [now at first mismatch or lsu] */ if (*ud>*ua) break; /* next time... */ - if (*ud==*ua) { /* all compared equal */ + if (*ud==*ua) { /* all compared equal */ *lsuq+=1; /* increment result */ msua=lsua; /* collapse acc units */ *msua=0; /* .. to a zero */ @@ -418,10 +419,11 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, } else if (divunits==1) { mul=(uLong)*msua * DIVBASE + *(msua-1); - mul/=*msud; /* no more to the right */ + mul/=*msud; /* no more to the right */ } else { - mul=(uLong)(*msua) * (uInt)(DIVBASE<<2) + (*(msua-1)<<2); + mul=(uLong)(*msua) * (uInt)(DIVBASE<<2) + + (*(msua-1)<<2); mul/=divtop; /* [divtop already allows for sticky bits] */ } multiplier=(Int)mul; @@ -540,10 +542,10 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, /* most significant end [offset by one into bcdacc to leave room */ /* for a possible carry digit if rounding for REMNEAR is needed] */ for (uq=msuq, ub=bcdacc+1; uq>=lsuq; uq--, ub+=9) { - uInt top, mid, rem; /* work */ + uInt top, mid, rem; /* work */ if (*uq==0) { /* no split needed */ - UINTAT(ub)=0; /* clear 9 BCD8s */ - UINTAT(ub+4)=0; /* .. */ + UBFROMUI(ub, 0); /* clear 9 BCD8s */ + UBFROMUI(ub+4, 0); /* .. */ *(ub+8)=0; /* .. */ continue; } @@ -558,11 +560,11 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, mid=rem/divsplit6; rem=rem%divsplit6; /* lay out the nine BCD digits (plus one unwanted byte) */ - UINTAT(ub) =UINTAT(&BIN2BCD8[top*4]); - UINTAT(ub+3)=UINTAT(&BIN2BCD8[mid*4]); - UINTAT(ub+6)=UINTAT(&BIN2BCD8[rem*4]); + UBFROMUI(ub, UBTOUI(&BIN2BCD8[top*4])); + UBFROMUI(ub+3, UBTOUI(&BIN2BCD8[mid*4])); + UBFROMUI(ub+6, UBTOUI(&BIN2BCD8[rem*4])); } /* BCD conversion loop */ - ub--; /* -> lsu */ + ub--; /* -> lsu */ /* complete the bcdnum; quodigits is correct, so the position of */ /* the first non-zero is known */ @@ -642,7 +644,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, num.msd--; /* use the 0 .. */ num.lsd=num.msd; /* .. at the new MSD place */ } - if (reround!=0) { /* discarding non-zero */ + if (reround!=0) { /* discarding non-zero */ uInt bump=0; /* rounding is DEC_ROUND_HALF_EVEN always */ if (reround>5) bump=1; /* >0.5 goes up */ @@ -651,7 +653,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, if (bump!=0) { /* need increment */ /* increment the coefficient; this might end up with 1000... */ ub=num.lsd; - for (; UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0; + for (; UBTOUI(ub-3)==0x09090909; ub-=4) UBFROMUI(ub-3, 0); for (; *ub==9; ub--) *ub=0; /* at most 3 more */ *ub+=1; if (ub<num.msd) num.msd--; /* carried */ @@ -680,7 +682,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, /* */ /* num gets the result of multiplying dfl and dfr */ /* bcdacc .. with the coefficient in this array */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* */ /* This effects the multiplication of two decFloats, both known to be */ @@ -695,7 +697,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, /* variables (Ints and uInts) or smaller; the other uses uLongs (for */ /* multiplication and addition only). Both implementations cover */ /* both arithmetic sizes (DOUBLE and QUAD) in order to allow timing */ -/* comparisons. In any one compilation only one implementation for */ +/* comparisons. In any one compilation only one implementation for */ /* each size can be used, and if DECUSE64 is 0 then use of the 32-bit */ /* version is forced. */ /* */ @@ -704,7 +706,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl, /* during lazy carry splitting because the initial quotient estimate */ /* (est) can exceed 32 bits. */ -#define MULTBASE BILLION /* the base used for multiply */ +#define MULTBASE ((uInt)BILLION) /* the base used for multiply */ #define MULOPLEN DECPMAX9 /* operand length ('digits' base 10**9) */ #define MULACCLEN (MULOPLEN*2) /* accumulator length (ditto) */ #define LEADZEROS (MULACCLEN*9 - DECPMAX*2) /* leading zeros always */ @@ -723,11 +725,12 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, uInt bufl[MULOPLEN]; /* left coefficient (base-billion) */ uInt bufr[MULOPLEN]; /* right coefficient (base-billion) */ uInt *ui, *uj; /* work */ - uByte *ub; /* .. */ + uByte *ub; /* .. */ + uInt uiwork; /* for macros */ #if DECUSE64 - uLong accl[MULACCLEN]; /* lazy accumulator (base-billion+) */ - uLong *pl; /* work -> lazy accumulator */ + uLong accl[MULACCLEN]; /* lazy accumulator (base-billion+) */ + uLong *pl; /* work -> lazy accumulator */ uInt acc[MULACCLEN]; /* coefficent in base-billion .. */ #else uInt acc[MULACCLEN*2]; /* accumulator in base-billion .. */ @@ -760,7 +763,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, /* zero the accumulator */ #if MULACCLEN==4 accl[0]=0; accl[1]=0; accl[2]=0; accl[3]=0; - #else /* use a loop */ + #else /* use a loop */ /* MULACCLEN is a multiple of four, asserted above */ for (pl=accl; pl<accl+MULACCLEN; pl+=4) { *pl=0; *(pl+1)=0; *(pl+2)=0; *(pl+3)=0;/* [reduce overhead] */ @@ -812,8 +815,8 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, /* */ /* Type OPLEN A B maxX maxError maxCorrection */ /* --------------------------------------------------------- */ - /* DOUBLE 2 29 32 <2*10**18 0.63 1 */ - /* QUAD 4 30 31 <4*10**18 1.17 2 */ + /* DOUBLE 2 29 32 <2*10**18 0.63 1 */ + /* QUAD 4 30 31 <4*10**18 1.17 2 */ /* */ /* In the OPLEN==2 case there is most choice, but the value for B */ /* of 32 has a big advantage as then the calculation of the */ @@ -840,7 +843,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, for (pl=accl, pa=acc; pl<accl+MULACCLEN; pl++, pa++) { /* each column position */ uInt lo, hop; /* work */ uInt est; /* cannot exceed 4E+9 */ - if (*pl>MULTBASE) { + if (*pl>=MULTBASE) { /* *pl holds a binary number which needs to be split */ hop=(uInt)(*pl>>MULSHIFTA); est=(uInt)(((uLong)hop*MULMAGIC)>>MULSHIFTB); @@ -905,7 +908,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, /* quotient/remainder has to be calculated for base-billion (1E+9). */ /* For this, Clark & Cowlishaw's quotient estimation approach (also */ /* used in decNumber) is needed, because 64-bit divide is generally */ - /* extremely slow on 32-bit machines. This algorithm splits X */ + /* extremely slow on 32-bit machines. This algorithm splits X */ /* using: */ /* */ /* magic=2**(A+B)/1E+9; // 'magic number' */ @@ -927,8 +930,8 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, /* */ /* Type OPLEN A B maxX maxError maxCorrection */ /* --------------------------------------------------------- */ - /* DOUBLE 2 29 32 <2*10**18 0.63 1 */ - /* QUAD 4 30 31 <4*10**18 1.17 2 */ + /* DOUBLE 2 29 32 <2*10**18 0.63 1 */ + /* QUAD 4 30 31 <4*10**18 1.17 2 */ /* */ /* In the OPLEN==2 case there is most choice, but the value for B */ /* of 32 has a big advantage as then the calculation of the */ @@ -952,15 +955,15 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, printf("\n"); #endif - for (pa=acc;; pa++) { /* each low uInt */ + for (pa=acc;; pa++) { /* each low uInt */ uInt hi, lo; /* words of exact multiply result */ uInt hop, estlo; /* work */ #if QUAD - uInt esthi; /* .. */ + uInt esthi; /* .. */ #endif lo=*pa; - hi=*(pa+MULACCLEN); /* top 32 bits */ + hi=*(pa+MULACCLEN); /* top 32 bits */ /* hi and lo now hold a binary number which needs to be split */ #if DOUBLE @@ -1032,7 +1035,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, uInt top, mid, rem; /* work */ /* *pa is non-zero -- split the base-billion acc digit into */ /* hi, mid, and low three-digits */ - #define mulsplit9 1000000 /* divisor */ + #define mulsplit9 1000000 /* divisor */ #define mulsplit6 1000 /* divisor */ /* The splitting is done by simple divides and remainders, */ /* assuming the compiler will optimize these where useful */ @@ -1042,13 +1045,13 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, mid=rem/mulsplit6; rem=rem%mulsplit6; /* lay out the nine BCD digits (plus one unwanted byte) */ - UINTAT(ub) =UINTAT(&BIN2BCD8[top*4]); - UINTAT(ub+3)=UINTAT(&BIN2BCD8[mid*4]); - UINTAT(ub+6)=UINTAT(&BIN2BCD8[rem*4]); + UBFROMUI(ub, UBTOUI(&BIN2BCD8[top*4])); + UBFROMUI(ub+3, UBTOUI(&BIN2BCD8[mid*4])); + UBFROMUI(ub+6, UBTOUI(&BIN2BCD8[rem*4])); } else { /* *pa==0 */ - UINTAT(ub)=0; /* clear 9 BCD8s */ - UINTAT(ub+4)=0; /* .. */ + UBFROMUI(ub, 0); /* clear 9 BCD8s */ + UBFROMUI(ub+4, 0); /* .. */ *(ub+8)=0; /* .. */ } if (pa==acc) break; @@ -1068,7 +1071,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, /* decFloatAbs -- absolute value, heeding NaNs, etc. */ /* */ /* result gets the canonicalized df with sign 0 */ -/* df is the decFloat to abs */ +/* df is the decFloat to abs */ /* set is the context */ /* returns result */ /* */ @@ -1090,26 +1093,45 @@ decFloat * decFloatAbs(decFloat *result, const decFloat *df, /* decFloatAdd -- add two decFloats */ /* */ /* result gets the result of adding dfl and dfr: */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ /* */ /* ------------------------------------------------------------------ */ +#if QUAD +/* Table for testing MSDs for fastpath elimination; returns the MSD of */ +/* a decDouble or decQuad (top 6 bits tested) ignoring the sign. */ +/* Infinities return -32 and NaNs return -128 so that summing the two */ +/* MSDs also allows rapid tests for the Specials (see code below). */ +const Int DECTESTMSD[64]={ + 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, -32, -128, + 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, -32, -128}; +#else +/* The table for testing MSDs is shared between the modules */ +extern const Int DECTESTMSD[64]; +#endif + decFloat * decFloatAdd(decFloat *result, const decFloat *dfl, const decFloat *dfr, decContext *set) { bcdnum num; /* for final conversion */ - Int expl, expr; /* left and right exponents */ - uInt *ui, *uj; /* work */ - uByte *ub; /* .. */ + Int bexpl, bexpr; /* left and right biased exponents */ + uByte *ub, *us, *ut; /* work */ + uInt uiwork; /* for macros */ + #if QUAD + uShort uswork; /* .. */ + #endif uInt sourhil, sourhir; /* top words from source decFloats */ - /* [valid only until specials */ - /* handled or exponents decoded] */ + /* [valid only through end of */ + /* fastpath code -- before swap] */ uInt diffsign; /* non-zero if signs differ */ uInt carry; /* carry: 0 or 1 before add loop */ - Int overlap; /* coefficient overlap (if full) */ + Int overlap; /* coefficient overlap (if full) */ + Int summ; /* sum of the MSDs */ /* the following buffers hold coefficients with various alignments */ /* (see commentary and diagrams below) */ uByte acc[4+2+DECPMAX*3+8]; @@ -1117,48 +1139,116 @@ decFloat * decFloatAdd(decFloat *result, uByte *umsd, *ulsd; /* local MSD and LSD pointers */ #if DECLITEND - #define CARRYPAT 0x01000000 /* carry=1 pattern */ + #define CARRYPAT 0x01000000 /* carry=1 pattern */ #else - #define CARRYPAT 0x00000001 /* carry=1 pattern */ + #define CARRYPAT 0x00000001 /* carry=1 pattern */ #endif /* Start decoding the arguments */ - /* the initial exponents are placed into the opposite Ints to */ + /* The initial exponents are placed into the opposite Ints to */ /* that which might be expected; there are two sets of data to */ /* keep track of (each decFloat and the corresponding exponent), */ /* and this scheme means that at the swap point (after comparing */ /* exponents) only one pair of words needs to be swapped */ - /* whichever path is taken (thereby minimising worst-case path) */ + /* whichever path is taken (thereby minimising worst-case path). */ + /* The calculated exponents will be nonsense when the arguments are */ + /* Special, but are not used in that path */ sourhil=DFWORD(dfl, 0); /* LHS top word */ - expr=DECCOMBEXP[sourhil>>26]; /* get exponent high bits (in place) */ + summ=DECTESTMSD[sourhil>>26]; /* get first MSD for testing */ + bexpr=DECCOMBEXP[sourhil>>26]; /* get exponent high bits (in place) */ + bexpr+=GETECON(dfl); /* .. + continuation */ + sourhir=DFWORD(dfr, 0); /* RHS top word */ - expl=DECCOMBEXP[sourhir>>26]; + summ+=DECTESTMSD[sourhir>>26]; /* sum MSDs for testing */ + bexpl=DECCOMBEXP[sourhir>>26]; + bexpl+=GETECON(dfr); + + /* here bexpr has biased exponent from lhs, and vice versa */ diffsign=(sourhil^sourhir)&DECFLOAT_Sign; - if (EXPISSPECIAL(expl | expr)) { /* either is special? */ - if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); - /* one or two infinities */ - /* two infinities with different signs is invalid */ - if (diffsign && DFISINF(dfl) && DFISINF(dfr)) - return decInvalid(result, set); - if (DFISINF(dfl)) return decInfinity(result, dfl); /* LHS is infinite */ - return decInfinity(result, dfr); /* RHS must be Infinite */ - } + /* now determine whether to take a fast path or the full-function */ + /* slow path. The slow path must be taken when: */ + /* -- both numbers are finite, and: */ + /* the exponents are different, or */ + /* the signs are different, or */ + /* the sum of the MSDs is >8 (hence might overflow) */ + /* specialness and the sum of the MSDs can be tested at once using */ + /* the summ value just calculated, so the test for specials is no */ + /* longer on the worst-case path (as of 3.60) */ + + if (summ<=8) { /* MSD+MSD is good, or there is a special */ + if (summ<0) { /* there is a special */ + /* Inf+Inf would give -64; Inf+finite is -32 or higher */ + if (summ<-64) return decNaNs(result, dfl, dfr, set); /* one or two NaNs */ + /* two infinities with different signs is invalid */ + if (summ==-64 && diffsign) return decInvalid(result, set); + if (DFISINF(dfl)) return decInfinity(result, dfl); /* LHS is infinite */ + return decInfinity(result, dfr); /* RHS must be Inf */ + } + /* Here when both arguments are finite; fast path is possible */ + /* (currently only for aligned and same-sign) */ + if (bexpr==bexpl && !diffsign) { + uInt tac[DECLETS+1]; /* base-1000 coefficient */ + uInt encode; /* work */ + + /* Get one coefficient as base-1000 and add the other */ + GETCOEFFTHOU(dfl, tac); /* least-significant goes to [0] */ + ADDCOEFFTHOU(dfr, tac); + /* here the sum of the MSDs (plus any carry) will be <10 due to */ + /* the fastpath test earlier */ + + /* construct the result; low word is the same for both formats */ + encode =BIN2DPD[tac[0]]; + encode|=BIN2DPD[tac[1]]<<10; + encode|=BIN2DPD[tac[2]]<<20; + encode|=BIN2DPD[tac[3]]<<30; + DFWORD(result, (DECBYTES/4)-1)=encode; + + /* collect next two declets (all that remains, for Double) */ + encode =BIN2DPD[tac[3]]>>2; + encode|=BIN2DPD[tac[4]]<<8; - /* Here when both arguments are finite */ + #if QUAD + /* complete and lay out middling words */ + encode|=BIN2DPD[tac[5]]<<18; + encode|=BIN2DPD[tac[6]]<<28; + DFWORD(result, 2)=encode; + + encode =BIN2DPD[tac[6]]>>4; + encode|=BIN2DPD[tac[7]]<<6; + encode|=BIN2DPD[tac[8]]<<16; + encode|=BIN2DPD[tac[9]]<<26; + DFWORD(result, 1)=encode; + + /* and final two declets */ + encode =BIN2DPD[tac[9]]>>6; + encode|=BIN2DPD[tac[10]]<<4; + #endif - /* complete exponent gathering (keeping swapped) */ - expr+=GETECON(dfl)-DECBIAS; /* .. + continuation and unbias */ - expl+=GETECON(dfr)-DECBIAS; - /* here expr has exponent from lhs, and vice versa */ + /* add exponent continuation and sign (from either argument) */ + encode|=sourhil & (ECONMASK | DECFLOAT_Sign); + + /* create lookup index = MSD + top two bits of biased exponent <<4 */ + tac[DECLETS]|=(bexpl>>DECECONL)<<4; + encode|=DECCOMBFROM[tac[DECLETS]]; /* add constructed combination field */ + DFWORD(result, 0)=encode; /* complete */ + + /* decFloatShow(result, ">"); */ + return result; + } /* fast path OK */ + /* drop through to slow path */ + } /* low sum or Special(s) */ + + /* Slow path required -- arguments are finite and might overflow, */ + /* or require alignment, or might have different signs */ /* now swap either exponents or argument pointers */ - if (expl<=expr) { + if (bexpl<=bexpr) { /* original left is bigger */ - Int expswap=expl; - expl=expr; - expr=expswap; + Int bexpswap=bexpl; + bexpl=bexpr; + bexpr=bexpswap; /* printf("left bigger\n"); */ } else { @@ -1167,7 +1257,7 @@ decFloat * decFloatAdd(decFloat *result, dfr=dfswap; /* printf("right bigger\n"); */ } - /* [here dfl and expl refer to the datum with the larger exponent, */ + /* [here dfl and bexpl refer to the datum with the larger exponent, */ /* of if the exponents are equal then the original LHS argument] */ /* if lhs is zero then result will be the rhs (now known to have */ @@ -1209,19 +1299,19 @@ decFloat * decFloatAdd(decFloat *result, #if DOUBLE #define COFF 4 /* offset into acc */ #elif QUAD - USHORTAT(acc+4)=0; /* prefix 00 */ + UBFROMUS(acc+4, 0); /* prefix 00 */ #define COFF 6 /* offset into acc */ #endif GETCOEFF(dfl, acc+COFF); /* decode from decFloat */ ulsd=acc+COFF+DECPMAX-1; umsd=acc+4; /* [having this here avoids */ - /* weird GCC optimizer failure] */ + #if DECTRACE {bcdnum tum; tum.msd=umsd; tum.lsd=ulsd; - tum.exponent=expl; + tum.exponent=bexpl-DECBIAS; tum.sign=DFWORD(dfl, 0) & DECFLOAT_Sign; decShowNum(&tum, "dflx");} #endif @@ -1235,16 +1325,16 @@ decFloat * decFloatAdd(decFloat *result, carry=0; /* assume no carry */ if (diffsign) { carry=CARRYPAT; /* for +1 during add */ - UINTAT(acc+ 4)=0x09090909-UINTAT(acc+ 4); - UINTAT(acc+ 8)=0x09090909-UINTAT(acc+ 8); - UINTAT(acc+12)=0x09090909-UINTAT(acc+12); - UINTAT(acc+16)=0x09090909-UINTAT(acc+16); + UBFROMUI(acc+ 4, 0x09090909-UBTOUI(acc+ 4)); + UBFROMUI(acc+ 8, 0x09090909-UBTOUI(acc+ 8)); + UBFROMUI(acc+12, 0x09090909-UBTOUI(acc+12)); + UBFROMUI(acc+16, 0x09090909-UBTOUI(acc+16)); #if QUAD - UINTAT(acc+20)=0x09090909-UINTAT(acc+20); - UINTAT(acc+24)=0x09090909-UINTAT(acc+24); - UINTAT(acc+28)=0x09090909-UINTAT(acc+28); - UINTAT(acc+32)=0x09090909-UINTAT(acc+32); - UINTAT(acc+36)=0x09090909-UINTAT(acc+36); + UBFROMUI(acc+20, 0x09090909-UBTOUI(acc+20)); + UBFROMUI(acc+24, 0x09090909-UBTOUI(acc+24)); + UBFROMUI(acc+28, 0x09090909-UBTOUI(acc+28)); + UBFROMUI(acc+32, 0x09090909-UBTOUI(acc+32)); + UBFROMUI(acc+36, 0x09090909-UBTOUI(acc+36)); #endif } /* diffsign */ @@ -1252,9 +1342,9 @@ decFloat * decFloatAdd(decFloat *result, /* it can be put straight into acc (with an appropriate gap, if */ /* needed) because no actual addition will be needed (except */ /* possibly to complete ten's complement) */ - overlap=DECPMAX-(expl-expr); + overlap=DECPMAX-(bexpl-bexpr); #if DECTRACE - printf("exps: %ld %ld\n", (LI)expl, (LI)expr); + printf("exps: %ld %ld\n", (LI)(bexpl-DECBIAS), (LI)(bexpr-DECBIAS)); printf("Overlap=%ld carry=%08lx\n", (LI)overlap, (LI)carry); #endif @@ -1274,13 +1364,13 @@ decFloat * decFloatAdd(decFloat *result, /* safe because the lhs is non-zero]. */ gap=-overlap; if (gap>DECPMAX) { - expr+=gap-1; + bexpr+=gap-1; gap=DECPMAX; } ub=ulsd+gap+1; /* where MSD will go */ /* Fill the gap with 0s; note that there is no addition to do */ - ui=&UINTAT(acc+COFF+DECPMAX); /* start of gap */ - for (; ui<&UINTAT(ub); ui++) *ui=0; /* mind the gap */ + ut=acc+COFF+DECPMAX; /* start of gap */ + for (; ut<ub; ut+=4) UBFROMUI(ut, 0); /* mind the gap */ if (overlap<-DECPMAX) { /* gap was > DECPMAX */ *ub=(uByte)(!DFISZERO(dfr)); /* make sticky digit */ } @@ -1294,63 +1384,74 @@ decFloat * decFloatAdd(decFloat *result, else { /* overlap>0 */ /* coefficients overlap (perhaps completely, although also */ /* perhaps only where zeros) */ - ub=buf+COFF+DECPMAX-overlap; /* where MSD will go */ - /* Fill the prefix gap with 0s; 8 will cover most common */ - /* unalignments, so start with direct assignments (a loop is */ - /* then used for any remaining -- the loop (and the one in a */ - /* moment) is not then on the critical path because the number */ - /* of additions is reduced by (at least) two in this case) */ - UINTAT(buf+4)=0; /* [clears decQuad 00 too] */ - UINTAT(buf+8)=0; - if (ub>buf+12) { - ui=&UINTAT(buf+12); /* start of any remaining */ - for (; ui<&UINTAT(ub); ui++) *ui=0; /* fill them */ - } - GETCOEFF(dfr, ub); /* decode from decFloat */ - - /* now move tail of rhs across to main acc; again use direct */ - /* assignment for 8 digits-worth */ - UINTAT(acc+COFF+DECPMAX)=UINTAT(buf+COFF+DECPMAX); - UINTAT(acc+COFF+DECPMAX+4)=UINTAT(buf+COFF+DECPMAX+4); - if (buf+COFF+DECPMAX+8<ub+DECPMAX) { - uj=&UINTAT(buf+COFF+DECPMAX+8); /* source */ - ui=&UINTAT(acc+COFF+DECPMAX+8); /* target */ - for (; uj<&UINTAT(ub+DECPMAX); ui++, uj++) *ui=*uj; + if (overlap==DECPMAX) { /* aligned */ + ub=buf+COFF; /* where msd will go */ + #if QUAD + UBFROMUS(buf+4, 0); /* clear quad's 00 */ + #endif + GETCOEFF(dfr, ub); /* decode from decFloat */ } + else { /* unaligned */ + ub=buf+COFF+DECPMAX-overlap; /* where MSD will go */ + /* Fill the prefix gap with 0s; 8 will cover most common */ + /* unalignments, so start with direct assignments (a loop is */ + /* then used for any remaining -- the loop (and the one in a */ + /* moment) is not then on the critical path because the number */ + /* of additions is reduced by (at least) two in this case) */ + UBFROMUI(buf+4, 0); /* [clears decQuad 00 too] */ + UBFROMUI(buf+8, 0); + if (ub>buf+12) { + ut=buf+12; /* start any remaining */ + for (; ut<ub; ut+=4) UBFROMUI(ut, 0); /* fill them */ + } + GETCOEFF(dfr, ub); /* decode from decFloat */ + + /* now move tail of rhs across to main acc; again use direct */ + /* copies for 8 digits-worth */ + UBFROMUI(acc+COFF+DECPMAX, UBTOUI(buf+COFF+DECPMAX)); + UBFROMUI(acc+COFF+DECPMAX+4, UBTOUI(buf+COFF+DECPMAX+4)); + if (buf+COFF+DECPMAX+8<ub+DECPMAX) { + us=buf+COFF+DECPMAX+8; /* source */ + ut=acc+COFF+DECPMAX+8; /* target */ + for (; us<ub+DECPMAX; us+=4, ut+=4) UBFROMUI(ut, UBTOUI(us)); + } + } /* unaligned */ ulsd=acc+(ub-buf+DECPMAX-1); /* update LSD pointer */ - /* now do the add of the non-tail; this is all nicely aligned, */ + /* Now do the add of the non-tail; this is all nicely aligned, */ /* and is over a multiple of four digits (because for Quad two */ - /* two 0 digits were added on the left); words in both acc and */ + /* zero digits were added on the left); words in both acc and */ /* buf (buf especially) will often be zero */ - /* [byte-by-byte add, here, is about 15% slower than the by-fours] */ + /* [byte-by-byte add, here, is about 15% slower total effect than */ + /* the by-fours] */ /* Now effect the add; this is harder on a little-endian */ /* machine as the inter-digit carry cannot use the usual BCD */ /* addition trick because the bytes are loaded in the wrong order */ /* [this loop could be unrolled, but probably scarcely worth it] */ - ui=&UINTAT(acc+COFF+DECPMAX-4); /* target LSW (acc) */ - uj=&UINTAT(buf+COFF+DECPMAX-4); /* source LSW (buf, to add to acc) */ + ut=acc+COFF+DECPMAX-4; /* target LSW (acc) */ + us=buf+COFF+DECPMAX-4; /* source LSW (buf, to add to acc) */ #if !DECLITEND - for (; ui>=&UINTAT(acc+4); ui--, uj--) { + for (; ut>=acc+4; ut-=4, us-=4) { /* big-endian add loop */ /* bcd8 add */ - carry+=*uj; /* rhs + carry */ + carry+=UBTOUI(us); /* rhs + carry */ if (carry==0) continue; /* no-op */ - carry+=*ui; /* lhs */ + carry+=UBTOUI(ut); /* lhs */ /* Big-endian BCD adjust (uses internal carry) */ carry+=0x76f6f6f6; /* note top nibble not all bits */ - *ui=(carry & 0x0f0f0f0f) - ((carry & 0x60606060)>>4); /* BCD adjust */ + /* apply BCD adjust and save */ + UBFROMUI(ut, (carry & 0x0f0f0f0f) - ((carry & 0x60606060)>>4)); carry>>=31; /* true carry was at far left */ } /* add loop */ #else - for (; ui>=&UINTAT(acc+4); ui--, uj--) { + for (; ut>=acc+4; ut-=4, us-=4) { /* little-endian add loop */ /* bcd8 add */ - carry+=*uj; /* rhs + carry */ + carry+=UBTOUI(us); /* rhs + carry */ if (carry==0) continue; /* no-op [common if unaligned] */ - carry+=*ui; /* lhs */ + carry+=UBTOUI(ut); /* lhs */ /* Little-endian BCD adjust; inter-digit carry must be manual */ /* because the lsb from the array will be in the most-significant */ /* byte of carry */ @@ -1359,12 +1460,13 @@ decFloat * decFloatAdd(decFloat *result, carry+=(carry & 0x00800000)>>15; carry+=(carry & 0x00008000)>>15; carry-=(carry & 0x60606060)>>4; /* BCD adjust back */ - *ui=carry & 0x0f0f0f0f; /* clear debris and save */ + UBFROMUI(ut, carry & 0x0f0f0f0f); /* clear debris and save */ /* here, final carry-out bit is at 0x00000080; move it ready */ /* for next word-add (i.e., to 0x01000000) */ carry=(carry & 0x00000080)<<17; } /* add loop */ #endif + #if DECTRACE {bcdnum tum; printf("Add done, carry=%08lx, diffsign=%ld\n", (LI)carry, (LI)diffsign); @@ -1392,36 +1494,36 @@ decFloat * decFloatAdd(decFloat *result, *(ulsd+1)=0; #endif /* there are always at least four coefficient words */ - UINTAT(umsd) =0x09090909-UINTAT(umsd); - UINTAT(umsd+4) =0x09090909-UINTAT(umsd+4); - UINTAT(umsd+8) =0x09090909-UINTAT(umsd+8); - UINTAT(umsd+12)=0x09090909-UINTAT(umsd+12); + UBFROMUI(umsd, 0x09090909-UBTOUI(umsd)); + UBFROMUI(umsd+4, 0x09090909-UBTOUI(umsd+4)); + UBFROMUI(umsd+8, 0x09090909-UBTOUI(umsd+8)); + UBFROMUI(umsd+12, 0x09090909-UBTOUI(umsd+12)); #if DOUBLE #define BNEXT 16 #elif QUAD - UINTAT(umsd+16)=0x09090909-UINTAT(umsd+16); - UINTAT(umsd+20)=0x09090909-UINTAT(umsd+20); - UINTAT(umsd+24)=0x09090909-UINTAT(umsd+24); - UINTAT(umsd+28)=0x09090909-UINTAT(umsd+28); - UINTAT(umsd+32)=0x09090909-UINTAT(umsd+32); + UBFROMUI(umsd+16, 0x09090909-UBTOUI(umsd+16)); + UBFROMUI(umsd+20, 0x09090909-UBTOUI(umsd+20)); + UBFROMUI(umsd+24, 0x09090909-UBTOUI(umsd+24)); + UBFROMUI(umsd+28, 0x09090909-UBTOUI(umsd+28)); + UBFROMUI(umsd+32, 0x09090909-UBTOUI(umsd+32)); #define BNEXT 36 #endif if (ulsd>=umsd+BNEXT) { /* unaligned */ /* eight will handle most unaligments for Double; 16 for Quad */ - UINTAT(umsd+BNEXT)=0x09090909-UINTAT(umsd+BNEXT); - UINTAT(umsd+BNEXT+4)=0x09090909-UINTAT(umsd+BNEXT+4); + UBFROMUI(umsd+BNEXT, 0x09090909-UBTOUI(umsd+BNEXT)); + UBFROMUI(umsd+BNEXT+4, 0x09090909-UBTOUI(umsd+BNEXT+4)); #if DOUBLE #define BNEXTY (BNEXT+8) #elif QUAD - UINTAT(umsd+BNEXT+8)=0x09090909-UINTAT(umsd+BNEXT+8); - UINTAT(umsd+BNEXT+12)=0x09090909-UINTAT(umsd+BNEXT+12); + UBFROMUI(umsd+BNEXT+8, 0x09090909-UBTOUI(umsd+BNEXT+8)); + UBFROMUI(umsd+BNEXT+12, 0x09090909-UBTOUI(umsd+BNEXT+12)); #define BNEXTY (BNEXT+16) #endif if (ulsd>=umsd+BNEXTY) { /* very unaligned */ - ui=&UINTAT(umsd+BNEXTY); /* -> continue */ - for (;;ui++) { - *ui=0x09090909-*ui; /* invert four digits */ - if (ui>=&UINTAT(ulsd-3)) break; /* all done */ + ut=umsd+BNEXTY; /* -> continue */ + for (;;ut+=4) { + UBFROMUI(ut, 0x09090909-UBTOUI(ut)); /* invert four digits */ + if (ut>=ulsd-3) break; /* all done */ } } } @@ -1446,10 +1548,10 @@ decFloat * decFloatAdd(decFloat *result, umsd=acc+COFF+DECPMAX-1; /* so far, so zero */ if (ulsd>umsd) { /* more to check */ umsd++; /* to align after checked area */ - for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4; + for (; UBTOUI(umsd)==0 && umsd+3<ulsd;) umsd+=4; for (; *umsd==0 && umsd<ulsd;) umsd++; } - if (*umsd==0) { /* must be true zero (and diffsign) */ + if (*umsd==0) { /* must be true zero (and diffsign) */ num.sign=0; /* assume + */ if (set->round==DEC_ROUND_FLOOR) num.sign=DECFLOAT_Sign; } @@ -1468,9 +1570,9 @@ decFloat * decFloatAdd(decFloat *result, #endif } /* same sign */ - num.msd=umsd; /* set MSD .. */ - num.lsd=ulsd; /* .. and LSD */ - num.exponent=expr; /* set exponent to smaller */ + num.msd=umsd; /* set MSD .. */ + num.lsd=ulsd; /* .. and LSD */ + num.exponent=bexpr-DECBIAS; /* set exponent to smaller, unbiassed */ #if DECTRACE decFloatShow(dfl, "dfl"); @@ -1484,12 +1586,12 @@ decFloat * decFloatAdd(decFloat *result, /* decFloatAnd -- logical digitwise AND of two decFloats */ /* */ /* result gets the result of ANDing dfl and dfr */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result, which will be canonical with sign=0 */ /* */ -/* The operands must be positive, finite with exponent q=0, and */ +/* The operands must be positive, finite with exponent q=0, and */ /* comprise just zeros and ones; if not, Invalid operation results. */ /* ------------------------------------------------------------------ */ decFloat * decFloatAnd(decFloat *result, @@ -1516,7 +1618,7 @@ decFloat * decFloatAnd(decFloat *result, /* decFloatCanonical -- copy a decFloat, making canonical */ /* */ /* result gets the canonicalized df */ -/* df is the decFloat to copy and make canonical */ +/* df is the decFloat to copy and make canonical */ /* returns result */ /* */ /* This works on specials, too; no error or exception is possible. */ @@ -1528,7 +1630,7 @@ decFloat * decFloatCanonical(decFloat *result, const decFloat *df) { /* ------------------------------------------------------------------ */ /* decFloatClass -- return the class of a decFloat */ /* */ -/* df is the decFloat to test */ +/* df is the decFloat to test */ /* returns the decClass that df falls into */ /* ------------------------------------------------------------------ */ enum decClass decFloatClass(const decFloat *df) { @@ -1560,7 +1662,7 @@ enum decClass decFloatClass(const decFloat *df) { /* ------------------------------------------------------------------ */ /* decFloatClassString -- return the class of a decFloat as a string */ /* */ -/* df is the decFloat to test */ +/* df is the decFloat to test */ /* returns a constant string describing the class df falls into */ /* ------------------------------------------------------------------ */ const char *decFloatClassString(const decFloat *df) { @@ -1579,10 +1681,10 @@ const char *decFloatClassString(const decFloat *df) { } /* decFloatClassString */ /* ------------------------------------------------------------------ */ -/* decFloatCompare -- compare two decFloats; quiet NaNs allowed */ +/* decFloatCompare -- compare two decFloats; quiet NaNs allowed */ /* */ /* result gets the result of comparing dfl and dfr */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result, which may be -1, 0, 1, or NaN (Unordered) */ @@ -1606,7 +1708,7 @@ decFloat * decFloatCompare(decFloat *result, /* decFloatCompareSignal -- compare two decFloats; all NaNs signal */ /* */ /* result gets the result of comparing dfl and dfr */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result, which may be -1, 0, 1, or NaN (Unordered) */ @@ -1633,17 +1735,21 @@ decFloat * decFloatCompareSignal(decFloat *result, /* decFloatCompareTotal -- compare two decFloats with total ordering */ /* */ /* result gets the result of comparing dfl and dfr */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* returns result, which may be -1, 0, or 1 */ /* ------------------------------------------------------------------ */ decFloat * decFloatCompareTotal(decFloat *result, const decFloat *dfl, const decFloat *dfr) { - Int comp; /* work */ + Int comp; /* work */ + uInt uiwork; /* for macros */ + #if QUAD + uShort uswork; /* .. */ + #endif if (DFISNAN(dfl) || DFISNAN(dfr)) { Int nanl, nanr; /* work */ /* morph NaNs to +/- 1 or 2, leave numbers as 0 */ - nanl=DFISSNAN(dfl)+DFISQNAN(dfl)*2; /* quiet > signalling */ + nanl=DFISSNAN(dfl)+DFISQNAN(dfl)*2; /* quiet > signalling */ if (DFISSIGNED(dfl)) nanl=-nanl; nanr=DFISSNAN(dfr)+DFISQNAN(dfr)*2; if (DFISSIGNED(dfr)) nanr=-nanr; @@ -1654,23 +1760,22 @@ decFloat * decFloatCompareTotal(decFloat *result, uByte bufl[DECPMAX+4]; /* for LHS coefficient + foot */ uByte bufr[DECPMAX+4]; /* for RHS coefficient + foot */ uByte *ub, *uc; /* work */ - Int sigl; /* signum of LHS */ + Int sigl; /* signum of LHS */ sigl=(DFISSIGNED(dfl) ? -1 : +1); /* decode the coefficients */ /* (shift both right two if Quad to make a multiple of four) */ #if QUAD - ub = bufl; /* avoid type-pun violation */ - USHORTAT(ub)=0; - uc = bufr; /* avoid type-pun violation */ - USHORTAT(uc)=0; + UBFROMUS(bufl, 0); + UBFROMUS(bufr, 0); #endif GETCOEFF(dfl, bufl+QUAD*2); /* decode from decFloat */ GETCOEFF(dfr, bufr+QUAD*2); /* .. */ /* all multiples of four, here */ comp=0; /* assume equal */ for (ub=bufl, uc=bufr; ub<bufl+DECPMAX+QUAD*2; ub+=4, uc+=4) { - if (UINTAT(ub)==UINTAT(uc)) continue; /* so far so same */ + uInt ui=UBTOUI(ub); + if (ui==UBTOUI(uc)) continue; /* so far so same */ /* about to find a winner; go by bytes in case little-endian */ for (;; ub++, uc++) { if (*ub==*uc) continue; @@ -1696,7 +1801,7 @@ decFloat * decFloatCompareTotal(decFloat *result, /* decFloatCompareTotalMag -- compare magnitudes with total ordering */ /* */ /* result gets the result of comparing abs(dfl) and abs(dfr) */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* returns result, which may be -1, 0, or 1 */ /* ------------------------------------------------------------------ */ @@ -1747,7 +1852,7 @@ decFloat * decFloatCopyAbs(decFloat *result, const decFloat *dfl) { /* ------------------------------------------------------------------ */ /* decFloatCopyNegate -- copy a decFloat as-is with inverted sign bit */ /* */ -/* result gets the copy of dfl with sign bit inverted */ +/* result gets the copy of dfl with sign bit inverted */ /* dfl is the decFloat to copy */ /* returns result */ /* */ @@ -1760,10 +1865,10 @@ decFloat * decFloatCopyNegate(decFloat *result, const decFloat *dfl) { } /* decFloatCopyNegate */ /* ------------------------------------------------------------------ */ -/* decFloatCopySign -- copy a decFloat with the sign of another */ +/* decFloatCopySign -- copy a decFloat with the sign of another */ /* */ -/* result gets the result of copying dfl with the sign of dfr */ -/* dfl is the first decFloat (lhs) */ +/* result gets the result of copying dfl with the sign of dfr */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* returns result */ /* */ @@ -1795,7 +1900,7 @@ decFloat * decFloatCopySign(decFloat *result, /* next one is used when it is known that the declet must be */ /* non-zero, or is the final zero declet */ #define dpdlendun(n, form) {dpd=(form)&0x3ff; \ - if (dpd==0) return 1; \ + if (dpd==0) return 1; \ return (DECPMAX-1-3*(n))-(3-DPD2BCD8[dpd*4+3]);} uInt decFloatDigits(const decFloat *df) { @@ -1819,7 +1924,7 @@ uInt decFloatDigits(const decFloat *df) { } /* [cannot drop through] */ sourlo=DFWORD(df, 1); /* sourhi not involved now */ if (sourlo&0xfff00000) { /* in one of first two */ - dpdlenchk(1, sourlo>>30); /* very rare */ + dpdlenchk(1, sourlo>>30); /* very rare */ dpdlendun(2, sourlo>>20); } /* [cannot drop through] */ dpdlenchk(3, sourlo>>10); @@ -1850,7 +1955,7 @@ uInt decFloatDigits(const decFloat *df) { } /* [cannot drop through] */ sourlo=DFWORD(df, 3); if (sourlo&0xfff00000) { /* in one of first two */ - dpdlenchk(7, sourlo>>30); /* very rare */ + dpdlenchk(7, sourlo>>30); /* very rare */ dpdlendun(8, sourlo>>20); } /* [cannot drop through] */ dpdlenchk(9, sourlo>>10); @@ -1863,7 +1968,7 @@ uInt decFloatDigits(const decFloat *df) { /* decFloatDivide -- divide a decFloat by another */ /* */ /* result gets the result of dividing dfl by dfr: */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -1880,7 +1985,7 @@ decFloat * decFloatDivide(decFloat *result, /* decFloatDivideInteger -- integer divide a decFloat by another */ /* */ /* result gets the result of dividing dfl by dfr: */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -1896,9 +2001,9 @@ decFloat * decFloatDivideInteger(decFloat *result, /* decFloatFMA -- multiply and add three decFloats, fused */ /* */ /* result gets the result of (dfl*dfr)+dff with a single rounding */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ -/* dff is the final decFloat (fhs) */ +/* dff is the final decFloat (fhs) */ /* set is the context */ /* returns result */ /* */ @@ -1906,21 +2011,23 @@ decFloat * decFloatDivideInteger(decFloat *result, decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, const decFloat *dfr, const decFloat *dff, decContext *set) { + /* The accumulator has the bytes needed for FiniteMultiply, plus */ /* one byte to the left in case of carry, plus DECPMAX+2 to the */ /* right for the final addition (up to full fhs + round & sticky) */ - #define FMALEN (1+ (DECPMAX9*18) +DECPMAX+2) - uByte acc[FMALEN]; /* for multiplied coefficient in BCD */ + #define FMALEN (ROUNDUP4(1+ (DECPMAX9*18+1) +DECPMAX+2)) + uByte acc[FMALEN]; /* for multiplied coefficient in BCD */ /* .. and for final result */ bcdnum mul; /* for multiplication result */ bcdnum fin; /* for final operand, expanded */ - uByte coe[DECPMAX]; /* dff coefficient in BCD */ + uByte coe[ROUNDUP4(DECPMAX)]; /* dff coefficient in BCD */ bcdnum *hi, *lo; /* bcdnum with higher/lower exponent */ uInt diffsign; /* non-zero if signs differ */ - uInt hipad; /* pad digit for hi if needed */ + uInt hipad; /* pad digit for hi if needed */ Int padding; /* excess exponent */ - uInt carry; /* +1 for ten's complement and during add */ - uByte *ub, *uh, *ul; /* work */ + uInt carry; /* +1 for ten's complement and during add */ + uByte *ub, *uh, *ul; /* work */ + uInt uiwork; /* for macros */ /* handle all the special values [any special operand leads to a */ /* special result] */ @@ -1971,8 +2078,8 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, GETCOEFF(dff, coe); /* extract the coefficient */ /* now set hi and lo so that hi points to whichever of mul and fin */ - /* has the higher exponent and lo point to the other [don't care if */ - /* the same] */ + /* has the higher exponent and lo points to the other [don't care, */ + /* if the same]. One coefficient will be in acc, the other in coe. */ if (mul.exponent>=fin.exponent) { hi=&mul; lo=&fin; @@ -1983,22 +2090,23 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, } /* remove leading zeros on both operands; this will save time later */ - /* and make testing for zero trivial */ - for (; UINTAT(hi->msd)==0 && hi->msd+3<hi->lsd;) hi->msd+=4; + /* and make testing for zero trivial (tests are safe because acc */ + /* and coe are rounded up to uInts) */ + for (; UBTOUI(hi->msd)==0 && hi->msd+3<hi->lsd;) hi->msd+=4; for (; *hi->msd==0 && hi->msd<hi->lsd;) hi->msd++; - for (; UINTAT(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4; + for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4; for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++; /* if hi is zero then result will be lo (which has the smaller */ /* exponent), which also may need to be tested for zero for the */ /* weird IEEE 754 sign rules */ - if (*hi->msd==0 && hi->msd==hi->lsd) { /* hi is zero */ + if (*hi->msd==0) { /* hi is zero */ /* "When the sum of two operands with opposite signs is */ /* exactly zero, the sign of that sum shall be '+' in all */ /* rounding modes except round toward -Infinity, in which */ /* mode that sign shall be '-'." */ if (diffsign) { - if (*lo->msd==0 && lo->msd==lo->lsd) { /* lo is zero */ + if (*lo->msd==0) { /* lo is zero */ lo->sign=0; if (set->round==DEC_ROUND_FLOOR) lo->sign=DECFLOAT_Sign; } /* diffsign && lo=0 */ @@ -2006,10 +2114,11 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, return decFinalize(result, lo, set); /* may need clamping */ } /* numfl is zero */ /* [here, both are minimal length and hi is non-zero] */ + /* (if lo is zero then padding with zeros may be needed, below) */ /* if signs differ, take the ten's complement of hi (zeros to the */ - /* right do not matter because the complement of zero is zero); */ - /* the +1 is done later, as part of the addition, inserted at the */ + /* right do not matter because the complement of zero is zero); the */ + /* +1 is done later, as part of the addition, inserted at the */ /* correct digit */ hipad=0; carry=0; @@ -2017,7 +2126,7 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, hipad=9; carry=1; /* exactly the correct number of digits must be inverted */ - for (uh=hi->msd; uh<hi->lsd-3; uh+=4) UINTAT(uh)=0x09090909-UINTAT(uh); + for (uh=hi->msd; uh<hi->lsd-3; uh+=4) UBFROMUI(uh, 0x09090909-UBTOUI(uh)); for (; uh<=hi->lsd; uh++) *uh=(uByte)(0x09-*uh); } @@ -2032,7 +2141,8 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, /* printf("FMA pad %ld\n", (LI)padding); */ /* the result of the addition will be built into the accumulator, */ - /* starting from the far right; this could be either hi or lo */ + /* starting from the far right; this could be either hi or lo, and */ + /* will be aligned */ ub=acc+FMALEN-1; /* where lsd of result will go */ ul=lo->lsd; /* lsd of rhs */ @@ -2042,45 +2152,43 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, /* digit at the right place, as it stays clear of hi digits */ /* [it must be DECPMAX+2 because during a subtraction the msd */ /* could become 0 after a borrow from 1.000 to 0.9999...] */ - Int hilen=(Int)(hi->lsd-hi->msd+1); /* lengths */ - Int lolen=(Int)(lo->lsd-lo->msd+1); /* .. */ - Int newexp=MINI(hi->exponent, hi->exponent+hilen-DECPMAX)-3; - Int reduce=newexp-lo->exponent; - if (reduce>0) { /* [= case gives reduce=0 nop] */ + + Int hilen=(Int)(hi->lsd-hi->msd+1); /* length of hi */ + Int lolen=(Int)(lo->lsd-lo->msd+1); /* and of lo */ + + if (hilen+padding-lolen > DECPMAX+2) { /* can reduce lo to single */ + /* make sure it is virtually at least DECPMAX from hi->msd, at */ + /* least to right of hi->lsd (in case of destructive subtract), */ + /* and separated by at least two digits from either of those */ + /* (the tricky DOUBLE case is when hi is a 1 that will become a */ + /* 0.9999... by subtraction: */ + /* hi: 1 E+16 */ + /* lo: .................1000000000000000 E-16 */ + /* which for the addition pads to: */ + /* hi: 1000000000000000000 E-16 */ + /* lo: .................1000000000000000 E-16 */ + Int newexp=MINI(hi->exponent, hi->exponent+hilen-DECPMAX)-3; + /* printf("FMA reduce: %ld\n", (LI)reduce); */ - if (reduce>=lolen) { /* eating all */ - lo->lsd=lo->msd; /* reduce to single digit */ - lo->exponent=newexp; /* [known to be non-zero] */ - } - else { /* < */ - uByte *up=lo->lsd; - lo->lsd=lo->lsd-reduce; - if (*lo->lsd==0) /* could need sticky bit */ - for (; up>lo->lsd; up--) { /* search discarded digits */ - if (*up!=0) { /* found one... */ - *lo->lsd=1; /* set sticky bit */ - break; - } - } - lo->exponent+=reduce; - } - padding=hi->exponent-lo->exponent; /* recalculate */ - ul=lo->lsd; /* .. */ - } /* maybe reduce */ - /* padding is now <= DECPMAX+2 but still > 0; tricky DOUBLE case */ - /* is when hi is a 1 that will become a 0.9999... by subtraction: */ - /* hi: 1 E+16 */ - /* lo: .................1000000000000000 E-16 */ - /* which for the addition pads and reduces to: */ - /* hi: 1000000000000000000 E-2 */ - /* lo: .................1 E-2 */ + lo->lsd=lo->msd; /* to single digit [maybe 0] */ + lo->exponent=newexp; /* new lowest exponent */ + padding=hi->exponent-lo->exponent; /* recalculate */ + ul=lo->lsd; /* .. and repoint */ + } + + /* padding is still > 0, but will fit in acc (less leading carry slot) */ #if DECCHECK - if (padding>DECPMAX+2) printf("FMA excess padding: %ld\n", (LI)padding); if (padding<=0) printf("FMA low padding: %ld\n", (LI)padding); + if (hilen+padding+1>FMALEN) + printf("FMA excess hilen+padding: %ld+%ld \n", (LI)hilen, (LI)padding); /* printf("FMA padding: %ld\n", (LI)padding); */ #endif + /* padding digits can now be set in the result; one or more of */ /* these will come from lo; others will be zeros in the gap */ + for (; ul-3>=lo->msd && padding>3; padding-=4, ul-=4, ub-=4) { + UBFROMUI(ub-3, UBTOUI(ul-3)); /* [cannot overlap] */ + } for (; ul>=lo->msd && padding>0; padding--, ul--, ub--) *ub=*ul; for (;padding>0; padding--, ub--) *ub=0; /* mind the gap */ } @@ -2088,23 +2196,39 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, /* addition now complete to the right of the rightmost digit of hi */ uh=hi->lsd; - /* carry was set up depending on ten's complement above; do the add... */ + /* dow do the add from hi->lsd to the left */ + /* [bytewise, because either operand can run out at any time] */ + /* carry was set up depending on ten's complement above */ + /* first assume both operands have some digits */ for (;; ub--) { - uInt hid, lod; - if (uh<hi->msd) { + if (uh<hi->msd || ul<lo->msd) break; + *ub=(uByte)(carry+(*uh--)+(*ul--)); + carry=0; + if (*ub<10) continue; + *ub-=10; + carry=1; + } /* both loop */ + + if (ul<lo->msd) { /* to left of lo */ + for (;; ub--) { + if (uh<hi->msd) break; + *ub=(uByte)(carry+(*uh--)); /* [+0] */ + carry=0; + if (*ub<10) continue; + *ub-=10; + carry=1; + } /* hi loop */ + } + else { /* to left of hi */ + for (;; ub--) { if (ul<lo->msd) break; - hid=hipad; - } - else hid=*uh--; - if (ul<lo->msd) lod=0; - else lod=*ul--; - *ub=(uByte)(carry+hid+lod); - if (*ub<10) carry=0; - else { + *ub=(uByte)(carry+hipad+(*ul--)); + carry=0; + if (*ub<10) continue; *ub-=10; carry=1; - } - } /* addition loop */ + } /* lo loop */ + } /* addition complete -- now handle carry, borrow, etc. */ /* use lo to set up the num (its exponent is already correct, and */ @@ -2122,7 +2246,7 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, if (!carry) { /* no carry out means hi<lo */ /* borrowed -- take ten's complement of the right digits */ lo->sign=hi->sign; /* sign is lhs sign */ - for (ul=lo->msd; ul<lo->lsd-3; ul+=4) UINTAT(ul)=0x09090909-UINTAT(ul); + for (ul=lo->msd; ul<lo->lsd-3; ul+=4) UBFROMUI(ul, 0x09090909-UBTOUI(ul)); for (; ul<=lo->lsd; ul++) *ul=(uByte)(0x09-*ul); /* [leaves ul at lsd+1] */ /* complete the ten's complement by adding 1 [cannot overrun] */ for (ul--; *ul==9; ul--) *ul=0; @@ -2133,7 +2257,7 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, /* all done except for the special IEEE 754 exact-zero-result */ /* rule (see above); while testing for zero, strip leading */ /* zeros (which will save decFinalize doing it) */ - for (; UINTAT(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4; + for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4; for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++; if (*lo->msd==0) { /* must be true zero (and diffsign) */ lo->sign=0; /* assume + */ @@ -2143,11 +2267,18 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, } /* subtraction gave positive result */ } /* diffsign */ + #if DECCHECK + /* assert no left underrun */ + if (lo->msd<acc) { + printf("FMA underrun by %ld \n", (LI)(acc-lo->msd)); + } + #endif + return decFinalize(result, lo, set); /* round, check, and lay out */ } /* decFloatFMA */ /* ------------------------------------------------------------------ */ -/* decFloatFromInt -- initialise a decFloat from an Int */ +/* decFloatFromInt -- initialise a decFloat from an Int */ /* */ /* result gets the converted Int */ /* n is the Int to convert */ @@ -2213,7 +2344,7 @@ decFloat * decFloatFromUInt32(decFloat *result, uInt u) { /* decFloatInvert -- logical digitwise INVERT of a decFloat */ /* */ /* result gets the result of INVERTing df */ -/* df is the decFloat to invert */ +/* df is the decFloat to invert */ /* set is the context */ /* returns result, which will be canonical with sign=0 */ /* */ @@ -2241,12 +2372,12 @@ decFloat * decFloatInvert(decFloat *result, const decFloat *df, /* ------------------------------------------------------------------ */ /* decFloatIs -- decFloat tests (IsSigned, etc.) */ /* */ -/* df is the decFloat to test */ -/* returns 0 or 1 in an int32_t */ +/* df is the decFloat to test */ +/* returns 0 or 1 in a uInt */ /* */ /* Many of these could be macros, but having them as real functions */ -/* is a bit cleaner (and they can be referred to here by the generic */ -/* names) */ +/* is a little cleaner (and they can be referred to here by the */ +/* generic names) */ /* ------------------------------------------------------------------ */ uInt decFloatIsCanonical(const decFloat *df) { if (DFISSPECIAL(df)) { @@ -2333,10 +2464,10 @@ uInt decFloatIsZero(const decFloat *df) { } /* decFloatIs... */ /* ------------------------------------------------------------------ */ -/* decFloatLogB -- return adjusted exponent, by 754r rules */ +/* decFloatLogB -- return adjusted exponent, by 754 rules */ /* */ /* result gets the adjusted exponent as an integer, or a NaN etc. */ -/* df is the decFloat to be examined */ +/* df is the decFloat to be examined */ /* set is the context */ /* returns result */ /* */ @@ -2353,12 +2484,12 @@ decFloat * decFloatLogB(decFloat *result, const decFloat *df, if (DFISNAN(df)) return decNaNs(result, df, NULL, set); if (DFISINF(df)) { DFWORD(result, 0)=0; /* need +ve */ - return decInfinity(result, result); /* canonical +Infinity */ + return decInfinity(result, result); /* canonical +Infinity */ } if (DFISZERO(df)) { - set->status|=DEC_Division_by_zero; /* as per 754r */ + set->status|=DEC_Division_by_zero; /* as per 754 */ DFWORD(result, 0)=DECFLOAT_Sign; /* make negative */ - return decInfinity(result, result); /* canonical -Infinity */ + return decInfinity(result, result); /* canonical -Infinity */ } ae=GETEXPUN(df) /* get unbiased exponent .. */ +decFloatDigits(df)-1; /* .. and make adjusted exponent */ @@ -2381,10 +2512,10 @@ decFloat * decFloatLogB(decFloat *result, const decFloat *df, } /* decFloatLogB */ /* ------------------------------------------------------------------ */ -/* decFloatMax -- return maxnum of two operands */ +/* decFloatMax -- return maxnum of two operands */ /* */ /* result gets the chosen decFloat */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -2416,7 +2547,7 @@ decFloat * decFloatMax(decFloat *result, /* decFloatMaxMag -- return maxnummag of two operands */ /* */ /* result gets the chosen decFloat */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -2440,10 +2571,10 @@ decFloat * decFloatMaxMag(decFloat *result, } /* decFloatMaxMag */ /* ------------------------------------------------------------------ */ -/* decFloatMin -- return minnum of two operands */ +/* decFloatMin -- return minnum of two operands */ /* */ /* result gets the chosen decFloat */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -2475,7 +2606,7 @@ decFloat * decFloatMin(decFloat *result, /* decFloatMinMag -- return minnummag of two operands */ /* */ /* result gets the chosen decFloat */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -2501,8 +2632,8 @@ decFloat * decFloatMinMag(decFloat *result, /* ------------------------------------------------------------------ */ /* decFloatMinus -- negate value, heeding NaNs, etc. */ /* */ -/* result gets the canonicalized 0-df */ -/* df is the decFloat to minus */ +/* result gets the canonicalized 0-df */ +/* df is the decFloat to minus */ /* set is the context */ /* returns result */ /* */ @@ -2524,8 +2655,8 @@ decFloat * decFloatMinus(decFloat *result, const decFloat *df, /* ------------------------------------------------------------------ */ /* decFloatMultiply -- multiply two decFloats */ /* */ -/* result gets the result of multiplying dfl and dfr: */ -/* dfl is the first decFloat (lhs) */ +/* result gets the result of multiplying dfl and dfr: */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -2535,7 +2666,7 @@ decFloat * decFloatMultiply(decFloat *result, const decFloat *dfl, const decFloat *dfr, decContext *set) { bcdnum num; /* for final conversion */ - uByte bcdacc[DECPMAX9*18+1]; /* for coefficent in BCD */ + uByte bcdacc[DECPMAX9*18+1]; /* for coefficent in BCD */ if (DFISSPECIAL(dfl) || DFISSPECIAL(dfr)) { /* either is special? */ /* NaNs are handled as usual */ @@ -2561,7 +2692,7 @@ decFloat * decFloatMultiply(decFloat *result, /* set is the context */ /* returns result */ /* */ -/* This is 754r nextdown; Invalid is the only status possible (from */ +/* This is 754 nextdown; Invalid is the only status possible (from */ /* an sNaN). */ /* ------------------------------------------------------------------ */ decFloat * decFloatNextMinus(decFloat *result, const decFloat *dfl, @@ -2580,19 +2711,19 @@ decFloat * decFloatNextMinus(decFloat *result, const decFloat *dfl, /* here (but can be done with normal add if the sign of zero is */ /* treated carefully, because no Inexactitude is interesting); */ /* rounding to -Infinity then pushes the result to next below */ - decFloatZero(&delta); /* set up tiny delta */ - DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ + decFloatZero(&delta); /* set up tiny delta */ + DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ DFWORD(&delta, 0)=DECFLOAT_Sign; /* Sign=1 + biased exponent=0 */ /* set up for the directional round */ - saveround=set->round; /* save mode */ + saveround=set->round; /* save mode */ set->round=DEC_ROUND_FLOOR; /* .. round towards -Infinity */ - savestat=set->status; /* save status */ + savestat=set->status; /* save status */ decFloatAdd(result, dfl, &delta, set); /* Add rules mess up the sign when going from +Ntiny to 0 */ if (DFISZERO(result)) DFWORD(result, 0)^=DECFLOAT_Sign; /* correct */ set->status&=DEC_Invalid_operation; /* preserve only sNaN status */ set->status|=savestat; /* restore pending flags */ - set->round=saveround; /* .. and mode */ + set->round=saveround; /* .. and mode */ return result; } /* decFloatNextMinus */ @@ -2604,7 +2735,7 @@ decFloat * decFloatNextMinus(decFloat *result, const decFloat *dfl, /* set is the context */ /* returns result */ /* */ -/* This is 754r nextup; Invalid is the only status possible (from */ +/* This is 754 nextup; Invalid is the only status possible (from */ /* an sNaN). */ /* ------------------------------------------------------------------ */ decFloat * decFloatNextPlus(decFloat *result, const decFloat *dfl, @@ -2624,19 +2755,19 @@ decFloat * decFloatNextPlus(decFloat *result, const decFloat *dfl, /* here (but can be done with normal add if the sign of zero is */ /* treated carefully, because no Inexactitude is interesting); */ /* rounding to +Infinity then pushes the result to next above */ - decFloatZero(&delta); /* set up tiny delta */ - DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ + decFloatZero(&delta); /* set up tiny delta */ + DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ DFWORD(&delta, 0)=0; /* Sign=0 + biased exponent=0 */ /* set up for the directional round */ - saveround=set->round; /* save mode */ - set->round=DEC_ROUND_CEILING; /* .. round towards +Infinity */ - savestat=set->status; /* save status */ + saveround=set->round; /* save mode */ + set->round=DEC_ROUND_CEILING; /* .. round towards +Infinity */ + savestat=set->status; /* save status */ decFloatAdd(result, dfl, &delta, set); /* Add rules mess up the sign when going from -Ntiny to -0 */ if (DFISZERO(result)) DFWORD(result, 0)^=DECFLOAT_Sign; /* correct */ set->status&=DEC_Invalid_operation; /* preserve only sNaN status */ set->status|=savestat; /* restore pending flags */ - set->round=saveround; /* .. and mode */ + set->round=saveround; /* .. and mode */ return result; } /* decFloatNextPlus */ @@ -2649,8 +2780,9 @@ decFloat * decFloatNextPlus(decFloat *result, const decFloat *dfl, /* set is the context */ /* returns result */ /* */ -/* This is 754r nextafter; status may be set unless the result is a */ -/* normal number. */ +/* This is 754-1985 nextafter, as modified during revision (dropped */ +/* from 754-2008); status may be set unless the result is a normal */ +/* number. */ /* ------------------------------------------------------------------ */ decFloat * decFloatNextToward(decFloat *result, const decFloat *dfl, const decFloat *dfr, @@ -2676,7 +2808,7 @@ decFloat * decFloatNextToward(decFloat *result, } saveround=set->round; /* save mode */ set->round=DEC_ROUND_CEILING; /* .. round towards +Infinity */ - deltatop=0; /* positive delta */ + deltatop=0; /* positive delta */ } else { /* lhs>rhs, do NextMinus, see above for commentary */ if (DFISINF(dfl) && !DFISSIGNED(dfl)) { /* +Infinity special case */ @@ -2684,23 +2816,23 @@ decFloat * decFloatNextToward(decFloat *result, return result; } saveround=set->round; /* save mode */ - set->round=DEC_ROUND_FLOOR; /* .. round towards -Infinity */ + set->round=DEC_ROUND_FLOOR; /* .. round towards -Infinity */ deltatop=DECFLOAT_Sign; /* negative delta */ } - savestat=set->status; /* save status */ + savestat=set->status; /* save status */ /* Here, Inexact is needed where appropriate (and hence Underflow, */ /* etc.). Therefore the tiny delta which is otherwise */ /* unrepresentable (see NextPlus and NextMinus) is constructed */ /* using the multiplication of FMA. */ - decFloatZero(&delta); /* set up tiny delta */ - DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ + decFloatZero(&delta); /* set up tiny delta */ + DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ DFWORD(&delta, 0)=deltatop; /* Sign + biased exponent=0 */ decFloatFromString(&pointone, "1E-1", set); /* set up multiplier */ decFloatFMA(result, &delta, &pointone, dfl, set); /* [Delta is truly tiny, so no need to correct sign of zero] */ /* use new status unless the result is normal */ if (decFloatIsNormal(result)) set->status=savestat; /* else goes forward */ - set->round=saveround; /* restore mode */ + set->round=saveround; /* restore mode */ return result; } /* decFloatNextToward */ @@ -2708,12 +2840,12 @@ decFloat * decFloatNextToward(decFloat *result, /* decFloatOr -- logical digitwise OR of two decFloats */ /* */ /* result gets the result of ORing dfl and dfr */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result, which will be canonical with sign=0 */ /* */ -/* The operands must be positive, finite with exponent q=0, and */ +/* The operands must be positive, finite with exponent q=0, and */ /* comprise just zeros and ones; if not, Invalid operation results. */ /* ------------------------------------------------------------------ */ decFloat * decFloatOr(decFloat *result, @@ -2739,14 +2871,14 @@ decFloat * decFloatOr(decFloat *result, /* ------------------------------------------------------------------ */ /* decFloatPlus -- add value to 0, heeding NaNs, etc. */ /* */ -/* result gets the canonicalized 0+df */ -/* df is the decFloat to plus */ +/* result gets the canonicalized 0+df */ +/* df is the decFloat to plus */ /* set is the context */ /* returns result */ /* */ /* This has the same effect as 0+df where the exponent of the zero is */ /* the same as that of df (if df is finite). */ -/* The effect is also the same as decFloatCopy except that NaNs */ +/* The effect is also the same as decFloatCopy except that NaNs */ /* are handled normally (the sign of a NaN is not affected, and an */ /* sNaN will signal), the result is canonical, and zero gets sign 0. */ /* ------------------------------------------------------------------ */ @@ -2762,7 +2894,7 @@ decFloat * decFloatPlus(decFloat *result, const decFloat *df, /* decFloatQuantize -- quantize a decFloat */ /* */ /* result gets the result of quantizing dfl to match dfr */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs), which sets the exponent */ /* set is the context */ /* returns result */ @@ -2775,16 +2907,19 @@ decFloat * decFloatQuantize(decFloat *result, decContext *set) { Int explb, exprb; /* left and right biased exponents */ uByte *ulsd; /* local LSD pointer */ - uInt *ui; /* work */ - uByte *ub; /* .. */ + uByte *ub, *uc; /* work */ Int drop; /* .. */ uInt dpd; /* .. */ - uInt encode; /* encoding accumulator */ + uInt encode; /* encoding accumulator */ uInt sourhil, sourhir; /* top words from source decFloats */ + uInt uiwork; /* for macros */ + #if QUAD + uShort uswork; /* .. */ + #endif /* the following buffer holds the coefficient for manipulation */ - uByte buf[4+DECPMAX*3]; /* + space for zeros to left or right */ + uByte buf[4+DECPMAX*3+2*QUAD]; /* + space for zeros to left or right */ #if DECTRACE - bcdnum num; /* for trace displays */ + bcdnum num; /* for trace displays */ #endif /* Start decoding the arguments */ @@ -2827,7 +2962,7 @@ decFloat * decFloatQuantize(decFloat *result, decShowNum(&num, "dfl"); #endif - if (drop>0) { /* [most common case] */ + if (drop>0) { /* [most common case] */ /* (this code is very similar to that in decFloatFinalize, but */ /* has many differences so is duplicated here -- so any changes */ /* may need to be made there, too) */ @@ -2838,7 +2973,7 @@ decFloat * decFloatQuantize(decFloat *result, /* there is at least one zero needed to the left, in all but one */ /* exceptional (all-nines) case, so place four zeros now; this is */ /* needed almost always and makes rounding all-nines by fours safe */ - UINTAT(BUFOFF-4)=0; + UBFROMUI(BUFOFF-4, 0); /* Three cases here: */ /* 1. new LSD is in coefficient (almost always) */ @@ -2849,7 +2984,7 @@ decFloat * decFloatQuantize(decFloat *result, /* [duplicate check-stickies code to save a test] */ /* [by-digit check for stickies as runs of zeros are rare] */ - if (drop<DECPMAX) { /* NB lengths not addresses */ + if (drop<DECPMAX) { /* NB lengths not addresses */ roundat=BUFOFF+DECPMAX-drop; reround=*roundat; for (ub=roundat+1; ub<BUFOFF+DECPMAX; ub++) { @@ -2932,7 +3067,7 @@ decFloat * decFloatQuantize(decFloat *result, /* increment the coefficient; this could give 1000... (after */ /* the all nines case) */ ub=ulsd; - for (; UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0; + for (; UBTOUI(ub-3)==0x09090909; ub-=4) UBFROMUI(ub-3, 0); /* now at most 3 digits left to non-9 (usually just the one) */ for (; *ub==9; ub--) *ub=0; *ub+=1; @@ -2945,8 +3080,8 @@ decFloat * decFloatQuantize(decFloat *result, /* available in the coefficent -- the first word to the left was */ /* cleared earlier for safe carry; now add any more needed */ if (drop>4) { - UINTAT(BUFOFF-8)=0; /* must be at least 5 */ - for (ui=&UINTAT(BUFOFF-12); ui>&UINTAT(ulsd-DECPMAX-3); ui--) *ui=0; + UBFROMUI(BUFOFF-8, 0); /* must be at least 5 */ + for (uc=BUFOFF-12; uc>ulsd-DECPMAX-3; uc-=4) UBFROMUI(uc, 0); } } /* need round (drop>0) */ @@ -2967,18 +3102,21 @@ decFloat * decFloatQuantize(decFloat *result, #else static const uInt dmask[]={0, 0xff000000, 0xffff0000, 0xffffff00}; #endif - for (ui=&UINTAT(BUFOFF+DECPMAX);; ui++) { - *ui=0; - if (UINTAT(&UBYTEAT(ui)-DECPMAX)!=0) { /* could be bad */ + /* note that here zeros to the right are added by fours, so in */ + /* the Quad case this could write 36 zeros if the coefficient has */ + /* fewer than three significant digits (hence the +2*QUAD for buf) */ + for (uc=BUFOFF+DECPMAX;; uc+=4) { + UBFROMUI(uc, 0); + if (UBTOUI(uc-DECPMAX)!=0) { /* could be bad */ /* if all four digits should be zero, definitely bad */ - if (ui<=&UINTAT(BUFOFF+DECPMAX+(-drop)-4)) + if (uc<=BUFOFF+DECPMAX+(-drop)-4) return decInvalid(result, set); /* must be a 1- to 3-digit sequence; check more carefully */ - if ((UINTAT(&UBYTEAT(ui)-DECPMAX)&dmask[(-drop)%4])!=0) + if ((UBTOUI(uc-DECPMAX)&dmask[(-drop)%4])!=0) return decInvalid(result, set); break; /* no need for loop end test */ } - if (ui>=&UINTAT(BUFOFF+DECPMAX+(-drop)-4)) break; /* done */ + if (uc>=BUFOFF+DECPMAX+(-drop)-4) break; /* done */ } ulsd=BUFOFF+DECPMAX+(-drop)-1; } /* pad and check leading zeros */ @@ -3045,7 +3183,7 @@ decFloat * decFloatQuantize(decFloat *result, /* decFloatReduce -- reduce finite coefficient to minimum length */ /* */ /* result gets the reduced decFloat */ -/* df is the source decFloat */ +/* df is the source decFloat */ /* set is the context */ /* returns result, which will be canonical */ /* */ @@ -3085,7 +3223,7 @@ decFloat * decFloatReduce(decFloat *result, const decFloat *df, /* decFloatRemainder -- integer divide and return remainder */ /* */ /* result gets the remainder of dividing dfl by dfr: */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -3101,7 +3239,7 @@ decFloat * decFloatRemainder(decFloat *result, /* decFloatRemainderNear -- integer divide to nearest and remainder */ /* */ /* result gets the remainder of dividing dfl by dfr: */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -3145,7 +3283,7 @@ decFloat * decFloatRotate(decFloat *result, if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); if (!DFISINT(dfr)) return decInvalid(result, set); digits=decFloatDigits(dfr); /* calculate digits */ - if (digits>2) return decInvalid(result, set); /* definitely out of range */ + if (digits>2) return decInvalid(result, set); /* definitely out of range */ rotate=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff]; /* is in bottom declet */ if (rotate>DECPMAX) return decInvalid(result, set); /* too big */ /* [from here on no error or status change is possible] */ @@ -3178,16 +3316,16 @@ decFloat * decFloatRotate(decFloat *result, num.lsd=num.msd+DECPMAX-1; num.sign=DFWORD(dfl, 0)&DECFLOAT_Sign; num.exponent=GETEXPUN(dfl); - savestat=set->status; /* record */ + savestat=set->status; /* record */ decFinalize(result, &num, set); - set->status=savestat; /* restore */ + set->status=savestat; /* restore */ return result; } /* decFloatRotate */ /* ------------------------------------------------------------------ */ /* decFloatSameQuantum -- test decFloats for same quantum */ /* */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* returns 1 if the operands have the same quantum, 0 otherwise */ /* */ @@ -3204,11 +3342,11 @@ uInt decFloatSameQuantum(const decFloat *dfl, const decFloat *dfr) { } /* decFloatSameQuantum */ /* ------------------------------------------------------------------ */ -/* decFloatScaleB -- multiply by a power of 10, as per 754r */ +/* decFloatScaleB -- multiply by a power of 10, as per 754 */ /* */ /* result gets the result of the operation */ -/* dfl is the first decFloat (lhs) */ -/* dfr is the second decFloat (rhs), am integer (with q=0) */ +/* dfl is the first decFloat (lhs) */ +/* dfr is the second decFloat (rhs), am integer (with q=0) */ /* set is the context */ /* returns result */ /* */ @@ -3229,10 +3367,10 @@ decFloat * decFloatScaleB(decFloat *result, digits=decFloatDigits(dfr); /* calculate digits */ #if DOUBLE - if (digits>3) return decInvalid(result, set); /* definitely out of range */ + if (digits>3) return decInvalid(result, set); /* definitely out of range */ expr=DPD2BIN[DFWORD(dfr, 1)&0x3ff]; /* must be in bottom declet */ #elif QUAD - if (digits>5) return decInvalid(result, set); /* definitely out of range */ + if (digits>5) return decInvalid(result, set); /* definitely out of range */ expr=DPD2BIN[DFWORD(dfr, 3)&0x3ff] /* in bottom 2 declets .. */ +DPD2BIN[(DFWORD(dfr, 3)>>10)&0x3ff]*1000; /* .. */ #endif @@ -3241,7 +3379,7 @@ decFloat * decFloatScaleB(decFloat *result, if (DFISINF(dfl)) return decInfinity(result, dfl); /* canonical */ if (DFISSIGNED(dfr)) expr=-expr; /* dfl is finite and expr is valid */ - *result=*dfl; /* copy to target */ + *result=*dfl; /* copy to target */ return decFloatSetExponent(result, set, GETEXPUN(result)+expr); } /* decFloatScaleB */ @@ -3266,23 +3404,24 @@ decFloat * decFloatScaleB(decFloat *result, decFloat * decFloatShift(decFloat *result, const decFloat *dfl, const decFloat *dfr, decContext *set) { - Int shift; /* dfr as an Int */ - uByte buf[DECPMAX*2]; /* coefficient + padding */ - uInt digits, savestat; /* work */ + Int shift; /* dfr as an Int */ + uByte buf[DECPMAX*2]; /* coefficient + padding */ + uInt digits, savestat; /* work */ bcdnum num; /* .. */ + uInt uiwork; /* for macros */ if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); if (!DFISINT(dfr)) return decInvalid(result, set); digits=decFloatDigits(dfr); /* calculate digits */ - if (digits>2) return decInvalid(result, set); /* definitely out of range */ - shift=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff]; /* is in bottom declet */ + if (digits>2) return decInvalid(result, set); /* definitely out of range */ + shift=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff]; /* is in bottom declet */ if (shift>DECPMAX) return decInvalid(result, set); /* too big */ /* [from here on no error or status change is possible] */ if (DFISINF(dfl)) return decInfinity(result, dfl); /* canonical */ /* handle no-shift and all-shift (clear to zero) cases */ if (shift==0) return decCanonical(result, dfl); - if (shift==DECPMAX) { /* zero with sign */ + if (shift==DECPMAX) { /* zero with sign */ uByte sign=(uByte)(DFBYTE(dfl, 0)&0x80); /* save sign bit */ decFloatZero(result); /* make +0 */ DFBYTE(result, 0)=(uByte)(DFBYTE(result, 0)|sign); /* and set sign */ @@ -3299,23 +3438,23 @@ decFloat * decFloatShift(decFloat *result, num.lsd=buf+DECPMAX-shift-1; } else { /* shift left -- zero padding needed to right */ - UINTAT(buf+DECPMAX)=0; /* 8 will handle most cases */ - UINTAT(buf+DECPMAX+4)=0; /* .. */ + UBFROMUI(buf+DECPMAX, 0); /* 8 will handle most cases */ + UBFROMUI(buf+DECPMAX+4, 0); /* .. */ if (shift>8) memset(buf+DECPMAX+8, 0, 8+QUAD*18); /* all other cases */ num.msd+=shift; num.lsd=num.msd+DECPMAX-1; } - savestat=set->status; /* record */ + savestat=set->status; /* record */ decFinalize(result, &num, set); - set->status=savestat; /* restore */ + set->status=savestat; /* restore */ return result; } /* decFloatShift */ /* ------------------------------------------------------------------ */ -/* decFloatSubtract -- subtract a decFloat from another */ +/* decFloatSubtract -- subtract a decFloat from another */ /* */ /* result gets the result of subtracting dfr from dfl: */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result */ @@ -3333,9 +3472,9 @@ decFloat * decFloatSubtract(decFloat *result, } /* decFloatSubtract */ /* ------------------------------------------------------------------ */ -/* decFloatToInt -- round to 32-bit binary integer (4 flavours) */ +/* decFloatToInt -- round to 32-bit binary integer (4 flavours) */ /* */ -/* df is the decFloat to round */ +/* df is the decFloat to round */ /* set is the context */ /* round is the rounding mode to use */ /* returns a uInt or an Int, rounded according to the name */ @@ -3361,12 +3500,12 @@ Int decFloatToInt32Exact(const decFloat *df, decContext *set, return (Int)decToInt32(df, set, round, 1, 0);} /* ------------------------------------------------------------------ */ -/* decFloatToIntegral -- round to integral value (two flavours) */ +/* decFloatToIntegral -- round to integral value (two flavours) */ /* */ /* result gets the result */ -/* df is the decFloat to round */ +/* df is the decFloat to round */ /* set is the context */ -/* round is the rounding mode to use */ +/* round is the rounding mode to use */ /* returns result */ /* */ /* No exceptions, even Inexact, are raised except for sNaN input, or */ @@ -3384,12 +3523,12 @@ decFloat * decFloatToIntegralExact(decFloat *result, const decFloat *df, /* decFloatXor -- logical digitwise XOR of two decFloats */ /* */ /* result gets the result of XORing dfl and dfr */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) */ /* set is the context */ /* returns result, which will be canonical with sign=0 */ /* */ -/* The operands must be positive, finite with exponent q=0, and */ +/* The operands must be positive, finite with exponent q=0, and */ /* comprise just zeros and ones; if not, Invalid operation results. */ /* ------------------------------------------------------------------ */ decFloat * decFloatXor(decFloat *result, @@ -3432,14 +3571,14 @@ static decFloat *decInvalid(decFloat *result, decContext *set) { /* decInfinity -- set canonical Infinity with sign from a decFloat */ /* */ /* result gets a canonical Infinity */ -/* df is source decFloat (only the sign is used) */ +/* df is source decFloat (only the sign is used) */ /* returns result */ /* */ -/* df may be the same as result */ +/* df may be the same as result */ /* ------------------------------------------------------------------ */ static decFloat *decInfinity(decFloat *result, const decFloat *df) { uInt sign=DFWORD(df, 0); /* save source signword */ - decFloatZero(result); /* clear everything */ + decFloatZero(result); /* clear everything */ DFWORD(result, 0)=DECFLOAT_Inf | (sign & DECFLOAT_Sign); return result; } /* decInfinity */ @@ -3449,7 +3588,7 @@ static decFloat *decInfinity(decFloat *result, const decFloat *df) { /* */ /* result gets the result of handling dfl and dfr, one or both of */ /* which is a NaN */ -/* dfl is the first decFloat (lhs) */ +/* dfl is the first decFloat (lhs) */ /* dfr is the second decFloat (rhs) -- may be NULL for a single- */ /* operand operation */ /* set is the context */ @@ -3476,19 +3615,20 @@ static decFloat *decNaNs(decFloat *result, } /* decNaNs */ /* ------------------------------------------------------------------ */ -/* decNumCompare -- numeric comparison of two decFloats */ +/* decNumCompare -- numeric comparison of two decFloats */ /* */ /* dfl is the left-hand decFloat, which is not a NaN */ /* dfr is the right-hand decFloat, which is not a NaN */ /* tot is 1 for total order compare, 0 for simple numeric */ -/* returns -1, 0, or +1 for dfl<dfr, dfl=dfr, dfl>dfr */ +/* returns -1, 0, or +1 for dfl<dfr, dfl=dfr, dfl>dfr */ /* */ -/* No error is possible; status and mode are unchanged. */ +/* No error is possible; status and mode are unchanged. */ /* ------------------------------------------------------------------ */ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { Int sigl, sigr; /* LHS and RHS non-0 signums */ Int shift; /* shift needed to align operands */ uByte *ub, *uc; /* work */ + uInt uiwork; /* for macros */ /* buffers +2 if Quad (36 digits), need double plus 4 for safe padding */ uByte bufl[DECPMAX*2+QUAD*2+4]; /* for LHS coefficient + padding */ uByte bufr[DECPMAX*2+QUAD*2+4]; /* for RHS coefficient + padding */ @@ -3512,7 +3652,7 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { sigr=-sigl; /* sign to return if abs(RHS) wins */ if (DFISINF(dfl)) { - if (DFISINF(dfr)) return 0; /* both infinite & same sign */ + if (DFISINF(dfr)) return 0; /* both infinite & same sign */ return sigl; /* inf > n */ } if (DFISINF(dfr)) return sigr; /* n < inf [dfl is finite] */ @@ -3544,17 +3684,16 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { /* decode the coefficients */ /* (shift both right two if Quad to make a multiple of four) */ #if QUAD - ub=bufl; /* avoid type-pun violation */ - UINTAT(ub)=0; - uc=bufr; /* avoid type-pun violation */ - UINTAT(uc)=0; + UBFROMUI(bufl, 0); + UBFROMUI(bufr, 0); #endif GETCOEFF(dfl, bufl+QUAD*2); /* decode from decFloat */ GETCOEFF(dfr, bufr+QUAD*2); /* .. */ if (shift==0) { /* aligned; common and easy */ /* all multiples of four, here */ for (ub=bufl, uc=bufr; ub<bufl+DECPMAX+QUAD*2; ub+=4, uc+=4) { - if (UINTAT(ub)==UINTAT(uc)) continue; /* so far so same */ + uInt ui=UBTOUI(ub); + if (ui==UBTOUI(uc)) continue; /* so far so same */ /* about to find a winner; go by bytes in case little-endian */ for (;; ub++, uc++) { if (*ub>*uc) return sigl; /* difference found */ @@ -3565,17 +3704,17 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { else if (shift>0) { /* lhs to left */ ub=bufl; /* RHS pointer */ /* pad bufl so right-aligned; most shifts will fit in 8 */ - UINTAT(bufl+DECPMAX+QUAD*2)=0; /* add eight zeros */ - UINTAT(bufl+DECPMAX+QUAD*2+4)=0; /* .. */ + UBFROMUI(bufl+DECPMAX+QUAD*2, 0); /* add eight zeros */ + UBFROMUI(bufl+DECPMAX+QUAD*2+4, 0); /* .. */ if (shift>8) { /* more than eight; fill the rest, and also worth doing the */ /* lead-in by fours */ - uByte *up; /* work */ + uByte *up; /* work */ uByte *upend=bufl+DECPMAX+QUAD*2+shift; - for (up=bufl+DECPMAX+QUAD*2+8; up<upend; up+=4) UINTAT(up)=0; + for (up=bufl+DECPMAX+QUAD*2+8; up<upend; up+=4) UBFROMUI(up, 0); /* [pads up to 36 in all for Quad] */ for (;; ub+=4) { - if (UINTAT(ub)!=0) return sigl; + if (UBTOUI(ub)!=0) return sigl; if (ub+4>bufl+shift-4) break; } } @@ -3585,7 +3724,8 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { /* comparison can go for the full length of bufr, which is a */ /* multiple of 4 bytes */ for (uc=bufr; ; uc+=4, ub+=4) { - if (UINTAT(uc)!=UINTAT(ub)) { /* mismatch found */ + uInt ui=UBTOUI(ub); + if (ui!=UBTOUI(uc)) { /* mismatch found */ for (;; uc++, ub++) { /* check from left [little-endian?] */ if (*ub>*uc) return sigl; /* difference found */ if (*ub<*uc) return sigr; /* .. */ @@ -3598,17 +3738,17 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { else { /* shift<0) .. RHS is to left of LHS; mirror shift>0 */ uc=bufr; /* RHS pointer */ /* pad bufr so right-aligned; most shifts will fit in 8 */ - UINTAT(bufr+DECPMAX+QUAD*2)=0; /* add eight zeros */ - UINTAT(bufr+DECPMAX+QUAD*2+4)=0; /* .. */ + UBFROMUI(bufr+DECPMAX+QUAD*2, 0); /* add eight zeros */ + UBFROMUI(bufr+DECPMAX+QUAD*2+4, 0); /* .. */ if (shift<-8) { /* more than eight; fill the rest, and also worth doing the */ /* lead-in by fours */ - uByte *up; /* work */ + uByte *up; /* work */ uByte *upend=bufr+DECPMAX+QUAD*2-shift; - for (up=bufr+DECPMAX+QUAD*2+8; up<upend; up+=4) UINTAT(up)=0; + for (up=bufr+DECPMAX+QUAD*2+8; up<upend; up+=4) UBFROMUI(up, 0); /* [pads up to 36 in all for Quad] */ for (;; uc+=4) { - if (UINTAT(uc)!=0) return sigr; + if (UBTOUI(uc)!=0) return sigr; if (uc+4>bufr-shift-4) break; } } @@ -3618,7 +3758,8 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { /* comparison can go for the full length of bufl, which is a */ /* multiple of 4 bytes */ for (ub=bufl; ; ub+=4, uc+=4) { - if (UINTAT(ub)!=UINTAT(uc)) { /* mismatch found */ + uInt ui=UBTOUI(ub); + if (ui!=UBTOUI(uc)) { /* mismatch found */ for (;; ub++, uc++) { /* check from left [little-endian?] */ if (*ub>*uc) return sigl; /* difference found */ if (*ub<*uc) return sigr; /* .. */ @@ -3639,10 +3780,10 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { /* ------------------------------------------------------------------ */ /* decToInt32 -- local routine to effect ToInteger conversions */ /* */ -/* df is the decFloat to convert */ +/* df is the decFloat to convert */ /* set is the context */ -/* rmode is the rounding mode to use */ -/* exact is 1 if Inexact should be signalled */ +/* rmode is the rounding mode to use */ +/* exact is 1 if Inexact should be signalled */ /* unsign is 1 if the result a uInt, 0 if an Int (cast to uInt) */ /* returns 32-bit result as a uInt */ /* */ @@ -3652,13 +3793,13 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { static uInt decToInt32(const decFloat *df, decContext *set, enum rounding rmode, Flag exact, Flag unsign) { Int exp; /* exponent */ - uInt sourhi, sourpen, sourlo; /* top word from source decFloat .. */ + uInt sourhi, sourpen, sourlo; /* top word from source decFloat .. */ uInt hi, lo; /* .. penultimate, least, etc. */ decFloat zero, result; /* work */ Int i; /* .. */ /* Start decoding the argument */ - sourhi=DFWORD(df, 0); /* top word */ + sourhi=DFWORD(df, 0); /* top word */ exp=DECCOMBEXP[sourhi>>26]; /* get exponent high bits (in place) */ if (EXPISSPECIAL(exp)) { /* is special? */ set->status|=DEC_Invalid_operation; /* signal */ @@ -3730,10 +3871,10 @@ static uInt decToInt32(const decFloat *df, decContext *set, /* decToIntegral -- local routine to effect ToIntegral value */ /* */ /* result gets the result */ -/* df is the decFloat to round */ +/* df is the decFloat to round */ /* set is the context */ -/* rmode is the rounding mode to use */ -/* exact is 1 if Inexact should be signalled */ +/* rmode is the rounding mode to use */ +/* exact is 1 if Inexact should be signalled */ /* returns result */ /* ------------------------------------------------------------------ */ static decFloat * decToIntegral(decFloat *result, const decFloat *df, @@ -3746,7 +3887,7 @@ static decFloat * decToIntegral(decFloat *result, const decFloat *df, decFloat zero; /* work */ /* Start decoding the argument */ - sourhi=DFWORD(df, 0); /* top word */ + sourhi=DFWORD(df, 0); /* top word */ exp=DECCOMBEXP[sourhi>>26]; /* get exponent high bits (in place) */ if (EXPISSPECIAL(exp)) { /* is special? */ @@ -3762,12 +3903,12 @@ static decFloat * decToIntegral(decFloat *result, const decFloat *df, if (exp>=0) return decCanonical(result, df); /* already integral */ - saveround=set->round; /* save rounding mode .. */ + saveround=set->round; /* save rounding mode .. */ savestatus=set->status; /* .. and status */ set->round=rmode; /* set mode */ decFloatZero(&zero); /* make 0E+0 */ decFloatQuantize(result, df, &zero, set); /* 'integrate'; cannot fail */ - set->round=saveround; /* restore rounding mode .. */ + set->round=saveround; /* restore rounding mode .. */ if (!exact) set->status=savestatus; /* .. and status, unless exact */ return result; } /* decToIntegral */ diff --git a/libdecnumber/decCommon.c b/libdecnumber/decCommon.c index fa16e792e66..845b9143d61 100644 --- a/libdecnumber/decCommon.c +++ b/libdecnumber/decCommon.c @@ -104,15 +104,15 @@ static decFloat * decFinalize(decFloat *, bcdnum *, decContext *); static Flag decBiStr(const char *, const char *, const char *); /* Macros and private tables; those which are not format-dependent */ -/* are only included if decQuad is being built. */ +/* are only included if decQuad is being built. */ /* ------------------------------------------------------------------ */ /* Combination field lookup tables (uInts to save measurable work) */ /* */ -/* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */ +/* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */ /* 10), shifted left for format, or DECFLOAT_Inf/NaN */ /* DECCOMBWEXP - The same, for the next-wider format (unless QUAD) */ -/* DECCOMBMSD - 4-bit most-significant-digit */ +/* DECCOMBMSD - 4-bit most-significant-digit */ /* [0 if the index is a special (Infinity or NaN)] */ /* DECCOMBFROM - 5-bit combination field from EXP top bits and MSD */ /* (placed in uInt so no shift is needed) */ @@ -123,7 +123,7 @@ static Flag decBiStr(const char *, const char *, const char *); /* DECCOMBFROM is indexed by expTopTwoBits*16 + msd */ /* */ /* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are */ -/* only included once, when QUAD is being built */ +/* only included once, when QUAD is being built */ /* ------------------------------------------------------------------ */ static const uInt DECCOMBEXP[64]={ 0, 0, 0, 0, 0, 0, 0, 0, @@ -161,7 +161,7 @@ static const uInt DECCOMBWEXP[64]={ #if QUAD const uInt DECCOMBMSD[64]={ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0}; @@ -223,7 +223,7 @@ static Flag decBiStr(const char *targ, const char *str1, const char *str2) { /* returns df */ /* */ /* The num descriptor may point to a bcd8 string of any length; this */ -/* string may have leading insignificant zeros. If it has more than */ +/* string may have leading insignificant zeros. If it has more than */ /* DECPMAX digits then the final digit can be a round-for-reround */ /* digit (i.e., it may include a sticky bit residue). */ /* */ @@ -248,8 +248,9 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, decContext *set) { uByte *ub; /* work */ uInt dpd; /* .. */ - uByte *umsd=num->msd; /* local copy */ - uByte *ulsd=num->lsd; /* .. */ + uInt uiwork; /* for macros */ + uByte *umsd=num->msd; /* local copy */ + uByte *ulsd=num->lsd; /* .. */ uInt encode; /* encoding accumulator */ Int length; /* coefficient length */ @@ -275,11 +276,11 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, length=(uInt)(ulsd-umsd+1); /* coefficient length */ if (!NUMISSPECIAL(num)) { - Int drop; /* digits to be dropped */ + Int drop; /* digits to be dropped */ /* skip leading insignificant zeros to calculate an exact length */ /* [this is quite expensive] */ if (*umsd==0) { - for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4; + for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4; for (; *umsd==0 && umsd<ulsd;) umsd++; length=ulsd-umsd+1; /* recalculate */ } @@ -305,12 +306,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, roundat=umsd+length-drop; reround=*roundat; for (ub=roundat+1; ub<=ulsd; ub++) { - if (*ub!=0) { /* non-zero to be discarded */ + if (*ub!=0) { /* non-zero to be discarded */ reround=DECSTICKYTAB[reround]; /* apply sticky bit */ break; /* [remainder don't-care] */ } } /* check stickies */ - ulsd=roundat-1; /* new LSD */ + ulsd=roundat-1; /* new LSD */ } else { /* edge case */ if (drop==length) { @@ -322,7 +323,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, reround=0; } for (ub=roundat+1; ub<=ulsd; ub++) { - if (*ub!=0) { /* non-zero to be discarded */ + if (*ub!=0) { /* non-zero to be discarded */ reround=DECSTICKYTAB[reround]; /* apply sticky bit */ break; /* [remainder don't-care] */ } @@ -331,7 +332,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, ulsd=umsd; /* .. */ } - if (reround!=0) { /* discarding non-zero */ + if (reround!=0) { /* discarding non-zero */ uInt bump=0; set->status|=DEC_Inexact; /* if adjusted exponent [exp+digits-1] is < EMIN then num is */ @@ -342,7 +343,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, /* next decide whether increment of the coefficient is needed */ if (set->round==DEC_ROUND_HALF_EVEN) { /* fastpath slowest case */ if (reround>5) bump=1; /* >0.5 goes up */ - else if (reround==5) /* exactly 0.5000 .. */ + else if (reround==5) /* exactly 0.5000 .. */ bump=*ulsd & 0x01; /* .. up iff [new] lsd is odd */ } /* r-h-e */ else switch (set->round) { @@ -382,13 +383,15 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, #endif break;} } /* switch (not r-h-e) */ - /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */ + /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */ if (bump!=0) { /* need increment */ /* increment the coefficient; this might end up with 1000... */ /* (after the all nines case) */ ub=ulsd; - for(; ub-3>=umsd && UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0; + for(; ub-3>=umsd && UBTOUI(ub-3)==0x09090909; ub-=4) { + UBFROMUI(ub-3, 0); /* to 00000000 */ + } /* [note ub could now be to left of msd, and it is not safe */ /* to write to the the left of the msd] */ /* now at most 3 digits left to non-9 (usually just the one) */ @@ -436,7 +439,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */ /* Overflow -- these could go straight to encoding, here, but */ /* instead num is adjusted to keep the code cleaner */ - Flag needmax=0; /* 1 for finite result */ + Flag needmax=0; /* 1 for finite result */ set->status|=(DEC_Overflow | DEC_Inexact); switch (set->round) { case DEC_ROUND_DOWN: { @@ -453,12 +456,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, break;} /* r-f */ default: break; /* Infinity in all other cases */ } - if (!needmax) { /* easy .. set Infinity */ + if (!needmax) { /* easy .. set Infinity */ num->exponent=DECFLOAT_Inf; *umsd=0; /* be clean: coefficient to 0 */ ulsd=umsd; /* .. */ } - else { /* return Nmax */ + else { /* return Nmax */ umsd=allnines; /* use constant array */ ulsd=allnines+DECPMAX-1; num->exponent=DECEMAX-(DECPMAX-1); @@ -475,8 +478,8 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, uByte *t=buffer; /* safe target */ uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */ /* printf("folddown shift=%ld\n", (LI)shift); */ - for (; s<=ulsd; s+=4, t+=4) UINTAT(t)=UINTAT(s); - for (t=tlsd-shift+1; t<=tlsd; t+=4) UINTAT(t)=0; /* pad */ + for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s)); + for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0); /* pad 0s */ num->exponent-=shift; umsd=buffer; ulsd=tlsd; @@ -492,23 +495,23 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, /*------------------------------------------------------------------*/ /* Following code does not alter coefficient (could be allnines array) */ + /* fast path possible when DECPMAX digits */ if (length==DECPMAX) { return decFloatFromBCD(df, num->exponent, umsd, num->sign); - } + } /* full-length */ - /* Here when length is short */ + /* slower path when not a full-length number; must care about length */ + /* [coefficient length here will be < DECPMAX] */ if (!NUMISSPECIAL(num)) { /* is still finite */ /* encode the combination field and exponent continuation */ uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */ uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */ - /* [msd=0] */ + /* [msd==0] */ /* look up the combination field and make high word */ encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */ encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */ } else encode=num->exponent; /* special [already in word] */ - /* [coefficient length here will be < DECPMAX] */ - encode|=num->sign; /* add sign */ /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ @@ -519,7 +522,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, /* working pointer, uInt *ub. */ /* As not full-length then chances are there are many leading zeros */ /* [and there may be a partial triad] */ - #define getDPD(dpd, n) ub=ulsd-(3*(n))-2; \ + #define getDPDt(dpd, n) ub=ulsd-(3*(n))-2; \ if (ub<umsd-2) dpd=0; \ else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; \ else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];} @@ -528,48 +531,48 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, /* according to endianness; in all cases complete the sign word */ /* first */ #if DECPMAX==7 - getDPD(dpd, 1); + getDPDt(dpd, 1); encode|=dpd<<10; - getDPD(dpd, 0); + getDPDt(dpd, 0); encode|=dpd; DFWORD(df, 0)=encode; /* just the one word */ #elif DECPMAX==16 - getDPD(dpd, 4); encode|=dpd<<8; - getDPD(dpd, 3); encode|=dpd>>2; + getDPDt(dpd, 4); encode|=dpd<<8; + getDPDt(dpd, 3); encode|=dpd>>2; DFWORD(df, 0)=encode; encode=dpd<<30; - getDPD(dpd, 2); encode|=dpd<<20; - getDPD(dpd, 1); encode|=dpd<<10; - getDPD(dpd, 0); encode|=dpd; + getDPDt(dpd, 2); encode|=dpd<<20; + getDPDt(dpd, 1); encode|=dpd<<10; + getDPDt(dpd, 0); encode|=dpd; DFWORD(df, 1)=encode; #elif DECPMAX==34 - getDPD(dpd,10); encode|=dpd<<4; - getDPD(dpd, 9); encode|=dpd>>6; + getDPDt(dpd,10); encode|=dpd<<4; + getDPDt(dpd, 9); encode|=dpd>>6; DFWORD(df, 0)=encode; encode=dpd<<26; - getDPD(dpd, 8); encode|=dpd<<16; - getDPD(dpd, 7); encode|=dpd<<6; - getDPD(dpd, 6); encode|=dpd>>4; + getDPDt(dpd, 8); encode|=dpd<<16; + getDPDt(dpd, 7); encode|=dpd<<6; + getDPDt(dpd, 6); encode|=dpd>>4; DFWORD(df, 1)=encode; encode=dpd<<28; - getDPD(dpd, 5); encode|=dpd<<18; - getDPD(dpd, 4); encode|=dpd<<8; - getDPD(dpd, 3); encode|=dpd>>2; + getDPDt(dpd, 5); encode|=dpd<<18; + getDPDt(dpd, 4); encode|=dpd<<8; + getDPDt(dpd, 3); encode|=dpd>>2; DFWORD(df, 2)=encode; encode=dpd<<30; - getDPD(dpd, 2); encode|=dpd<<20; - getDPD(dpd, 1); encode|=dpd<<10; - getDPD(dpd, 0); encode|=dpd; + getDPDt(dpd, 2); encode|=dpd<<20; + getDPDt(dpd, 1); encode|=dpd<<10; + getDPDt(dpd, 0); encode|=dpd; DFWORD(df, 3)=encode; #endif /* printf("Status: %08lx\n", (LI)set->status); */ - /* decFloatShow(df, "final"); */ + /* decFloatShow(df, "final2"); */ return df; } /* decFinalize */ @@ -579,12 +582,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num, /* df is the target decFloat */ /* exp is the in-range unbiased exponent, q, or a special value in */ /* the form returned by decFloatGetExponent */ -/* bcdar holds DECPMAX digits to set the coefficient from, one */ +/* bcdar holds DECPMAX digits to set the coefficient from, one */ /* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ /* if df is a NaN; all are ignored if df is infinite. */ -/* All bytes must be in 0-9; results undefined otherwise. */ +/* All bytes must be in 0-9; results are undefined otherwise. */ /* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ -/* returns df, which will be canonical */ +/* returns df, which will be canonical */ /* */ /* No error is possible, and no status will be set. */ /* ------------------------------------------------------------------ */ @@ -609,53 +612,53 @@ decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar, /* and put the corresponding DPD code into dpd. */ /* Use of a working pointer, uInt *ub, is assumed. */ - #define getDPDf(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \ + #define getDPDb(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \ dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; /* place the declets in the encoding words and copy to result (df), */ /* according to endianness; in all cases complete the sign word */ /* first */ #if DECPMAX==7 - getDPDf(dpd, 1); + getDPDb(dpd, 1); encode|=dpd<<10; - getDPDf(dpd, 0); + getDPDb(dpd, 0); encode|=dpd; DFWORD(df, 0)=encode; /* just the one word */ #elif DECPMAX==16 - getDPDf(dpd, 4); encode|=dpd<<8; - getDPDf(dpd, 3); encode|=dpd>>2; + getDPDb(dpd, 4); encode|=dpd<<8; + getDPDb(dpd, 3); encode|=dpd>>2; DFWORD(df, 0)=encode; encode=dpd<<30; - getDPDf(dpd, 2); encode|=dpd<<20; - getDPDf(dpd, 1); encode|=dpd<<10; - getDPDf(dpd, 0); encode|=dpd; + getDPDb(dpd, 2); encode|=dpd<<20; + getDPDb(dpd, 1); encode|=dpd<<10; + getDPDb(dpd, 0); encode|=dpd; DFWORD(df, 1)=encode; #elif DECPMAX==34 - getDPDf(dpd,10); encode|=dpd<<4; - getDPDf(dpd, 9); encode|=dpd>>6; + getDPDb(dpd,10); encode|=dpd<<4; + getDPDb(dpd, 9); encode|=dpd>>6; DFWORD(df, 0)=encode; encode=dpd<<26; - getDPDf(dpd, 8); encode|=dpd<<16; - getDPDf(dpd, 7); encode|=dpd<<6; - getDPDf(dpd, 6); encode|=dpd>>4; + getDPDb(dpd, 8); encode|=dpd<<16; + getDPDb(dpd, 7); encode|=dpd<<6; + getDPDb(dpd, 6); encode|=dpd>>4; DFWORD(df, 1)=encode; encode=dpd<<28; - getDPDf(dpd, 5); encode|=dpd<<18; - getDPDf(dpd, 4); encode|=dpd<<8; - getDPDf(dpd, 3); encode|=dpd>>2; + getDPDb(dpd, 5); encode|=dpd<<18; + getDPDb(dpd, 4); encode|=dpd<<8; + getDPDb(dpd, 3); encode|=dpd>>2; DFWORD(df, 2)=encode; encode=dpd<<30; - getDPDf(dpd, 2); encode|=dpd<<20; - getDPDf(dpd, 1); encode|=dpd<<10; - getDPDf(dpd, 0); encode|=dpd; + getDPDb(dpd, 2); encode|=dpd<<20; + getDPDb(dpd, 1); encode|=dpd<<10; + getDPDb(dpd, 0); encode|=dpd; DFWORD(df, 3)=encode; #endif - /* decFloatShow(df, "final"); */ + /* decFloatShow(df, "fromB"); */ return df; } /* decFloatFromBCD */ @@ -671,7 +674,7 @@ decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar, /* and QUAD the first (pad) nibble is also ignored in all cases. */ /* All coefficient nibbles must be in 0-9 and sign in A-F; results */ /* are undefined otherwise. */ -/* returns df, which will be canonical */ +/* returns df, which will be canonical */ /* */ /* No error is possible, and no status will be set. */ /* ------------------------------------------------------------------ */ @@ -691,7 +694,7 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) { *op++=*ip>>4; *op++=(uByte)(*ip&0x0f); /* [final nibble is sign] */ } - op--; /* -> sign byte */ + op--; /* -> sign byte */ if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign; if (EXPISSPECIAL(exp)) { /* Infinity or NaN */ @@ -702,7 +705,71 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) { } /* decFloatFromPacked */ /* ------------------------------------------------------------------ */ -/* decFloatFromString -- conversion from numeric string */ +/* decFloatFromPackedChecked -- set from exponent and packed; checked */ +/* */ +/* df is the target decFloat */ +/* exp is the in-range unbiased exponent, q, or a special value in */ +/* the form returned by decFloatGetExponent */ +/* packed holds DECPMAX packed decimal digits plus a sign nibble */ +/* (all 6 codes are OK); the first (MSD) must be 0 if df is a NaN */ +/* and all digits must be 0 if df is infinite. For DOUBLE and */ +/* QUAD the first (pad) nibble must be 0. */ +/* All coefficient nibbles must be in 0-9 and sign in A-F. */ +/* returns df, which will be canonical or NULL if any of the */ +/* requirements are not met (if this case df is unchanged); that */ +/* is, the input data must be as returned by decFloatToPacked, */ +/* except that all six sign codes are acccepted. */ +/* */ +/* No status will be set. */ +/* ------------------------------------------------------------------ */ +decFloat * decFloatFromPackedChecked(decFloat *df, Int exp, + const uByte *packed) { + uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */ + const uByte *ip; /* .. */ + uByte *op; /* .. */ + Int sig=0; /* sign */ + + /* expand coefficient and sign to BCDAR */ + #if SINGLE + op=bcdar+1; /* no pad digit */ + #else + op=bcdar; /* first (pad) digit here */ + #endif + for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) { + *op=*ip>>4; + if (*op>9) return NULL; + op++; + *op=(uByte)(*ip&0x0f); /* [final nibble is sign] */ + if (*op>9 && ip<packed+((DECPMAX+2)/2)-1) return NULL; + op++; + } + op--; /* -> sign byte */ + if (*op<=9) return NULL; /* bad sign */ + if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign; + + #if !SINGLE + if (bcdar[0]!=0) return NULL; /* bad pad nibble */ + #endif + + if (EXPISNAN(exp)) { /* a NaN */ + if (bcdar[1]!=0) return NULL; /* bad msd */ + } /* NaN */ + else if (EXPISINF(exp)) { /* is infinite */ + Int i; + for (i=0; i<DECPMAX; i++) { + if (bcdar[i+1]!=0) return NULL; /* should be all zeros */ + } + } /* infinity */ + else { /* finite */ + /* check the exponent is in range */ + if (exp>DECEMAX-DECPMAX+1) return NULL; + if (exp<DECEMIN-DECPMAX+1) return NULL; + } + return decFloatFromBCD(df, exp, bcdar+1, sig); + } /* decFloatFromPacked */ + +/* ------------------------------------------------------------------ */ +/* decFloatFromString -- conversion from numeric string */ /* */ /* result is the decFloat format number which gets the result of */ /* the conversion */ @@ -710,12 +777,12 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) { /* number (which may be a special value), \0-terminated */ /* If there are too many significant digits in the */ /* coefficient it will be rounded. */ -/* set is the context */ +/* set is the context */ /* returns result */ /* */ /* The length of the coefficient and the size of the exponent are */ /* checked by this routine, so the correct error (Underflow or */ -/* Overflow) can be reported or rounding applied, as necessary. */ +/* Overflow) can be reported or rounding applied, as necessary. */ /* */ /* There is no limit to the coefficient length for finite inputs; */ /* NaN payloads must be integers with no more than DECPMAX-1 digits. */ @@ -726,20 +793,21 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) { decFloat * decFloatFromString(decFloat *result, const char *string, decContext *set) { Int digits; /* count of digits in coefficient */ - const char *dotchar=NULL; /* where dot was found [NULL if none] */ - const char *cfirst=string; /* -> first character of decimal part */ - const char *c; /* work */ + const char *dotchar=NULL; /* where dot was found [NULL if none] */ + const char *cfirst=string; /* -> first character of decimal part */ + const char *c; /* work */ uByte *ub; /* .. */ + uInt uiwork; /* for macros */ bcdnum num; /* collects data for finishing */ uInt error=DEC_Conversion_syntax; /* assume the worst */ - uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */ + uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */ /* some common rounding, +3, & pad */ #if DECTRACE /* printf("FromString %s ...\n", string); */ #endif for(;;) { /* once-only 'loop' */ - num.sign=0; /* assume non-negative */ + num.sign=0; /* assume non-negative */ num.msd=buffer; /* MSD is here always */ /* detect and validate the coefficient, including any leading, */ @@ -810,7 +878,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string, exp-=(Int)(clast-dotchar); /* adjust exponent */ /* [the '.' can now be ignored] */ } - num.exponent=exp; /* exponent is good; store it */ + num.exponent=exp; /* exponent is good; store it */ /* Here when whole string has been inspected and syntax is good */ /* cfirst->first digit or dot, clast->last digit or dot */ @@ -832,8 +900,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string, /* as usual, go by fours when safe; NB it has been asserted */ /* that a '.' does not have the same mask as a digit */ if (c<=clast-3 /* safe for four */ - && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* test four */ - UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */ + && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* test four */ + UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */ ub+=4; c+=4; continue; @@ -846,7 +914,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string, } } /* had dot */ /* Now no dot; do this by fours (where safe) */ - for (; c<=clast-3; c+=4, ub+=4) UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; + for (; c<=clast-3; c+=4, ub+=4) UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0'); num.lsd=buffer+digits-1; /* record new LSD */ } /* fits */ @@ -857,7 +925,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string, if (*cfirst=='.') cfirst++; /* step past dot at start */ if (*cfirst=='0') { /* [cfirst always -> digit] */ for (; cfirst<clast; cfirst++) { - if (*cfirst!='0') { /* non-zero found */ + if (*cfirst!='0') { /* non-zero found */ if (*cfirst=='.') continue; /* [ignore] */ break; /* done */ } @@ -871,8 +939,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string, for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) { /* (see commentary just above) */ if (c<=clast-3 /* safe for four */ - && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */ - UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */ + && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */ + UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */ ub+=4; c+=3; /* [will become 4] */ continue; @@ -881,7 +949,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string, *ub++=(uByte)(*c-'0'); } ub--; /* -> LSD */ - for (; c<=clast; c++) { /* inspect remaining chars */ + for (; c<=clast; c++) { /* inspect remaining chars */ if (*c!='0') { /* sticky bit needed */ if (*c=='.') continue; /* [ignore] */ *ub=DECSTICKYTAB[*ub]; /* update round-for-reround */ @@ -925,7 +993,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string, *ub=(uByte)(*c-'0'); /* good bcd8 */ } if (*c!='\0') break; /* not all digits, or too many */ - num.lsd=ub-1; /* record new LSD */ + num.lsd=ub-1; /* record new LSD */ } } /* NaN or sNaN */ error=0; /* syntax is OK */ @@ -938,8 +1006,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string, if (error!=0) { set->status|=error; - num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */ - num.sign=0; /* .. with 0 sign */ + num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */ + num.sign=0; /* .. with 0 sign */ buffer[0]=0; /* .. and coefficient */ num.lsd=buffer; /* .. */ /* decShowNum(&num, "oops"); */ @@ -957,7 +1025,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string, /* result is the decFloat format number which gets the result of */ /* the conversion */ /* wider is the decFloatWider format number which will be narrowed */ -/* set is the context */ +/* set is the context */ /* returns result */ /* */ /* Narrowing can cause rounding, overflow, etc., but not Invalid */ @@ -968,7 +1036,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string, decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider, decContext *set) { bcdnum num; /* collects data for finishing */ - uByte bcdar[DECWPMAX]; /* room for wider coefficient */ + uByte bcdar[DECWPMAX]; /* room for wider coefficient */ uInt widerhi=DFWWORD(wider, 0); /* top word */ Int exp; @@ -979,7 +1047,7 @@ decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider, num.sign=widerhi&0x80000000; /* extract sign [DECFLOAT_Sign=Neg] */ /* decode the wider combination field to exponent */ - exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */ + exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */ /* if it is a special there's nothing to do unless sNaN; if it's */ /* finite then add the (wider) exponent continuation and unbias */ if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */ @@ -1001,7 +1069,7 @@ decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider, /* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ /* 0 otherwise) */ /* */ -/* No error is possible, and no status will be set. If df is a */ +/* No error is possible, and no status will be set. If df is a */ /* special value the array is set to zeros (for Infinity) or to the */ /* payload of a qNaN or sNaN. */ /* ------------------------------------------------------------------ */ @@ -1015,12 +1083,12 @@ Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) { } /* decFloatGetCoefficient */ /* ------------------------------------------------------------------ */ -/* decFloatGetExponent -- get unbiased exponent */ +/* decFloatGetExponent -- get unbiased exponent */ /* */ /* df is the decFloat from which to extract the exponent */ /* returns the exponent, q. */ /* */ -/* No error is possible, and no status will be set. If df is a */ +/* No error is possible, and no status will be set. If df is a */ /* special value the first seven bits of the decFloat are returned, */ /* left adjusted and with the first (sign) bit set to 0 (followed by */ /* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN). */ @@ -1034,11 +1102,11 @@ Int decFloatGetExponent(const decFloat *df) { /* decFloatSetCoefficient -- set coefficient from BCD8 */ /* */ /* df is the target decFloat (and source of exponent/special value) */ -/* bcdar holds DECPMAX digits to set the coefficient from, one */ +/* bcdar holds DECPMAX digits to set the coefficient from, one */ /* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ /* if df is a NaN; all are ignored if df is infinite. */ /* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ -/* returns df, which will be canonical */ +/* returns df, which will be canonical */ /* */ /* No error is possible, and no status will be set. */ /* ------------------------------------------------------------------ */ @@ -1060,18 +1128,18 @@ decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar, } /* decFloatSetCoefficient */ /* ------------------------------------------------------------------ */ -/* decFloatSetExponent -- set exponent or special value */ +/* decFloatSetExponent -- set exponent or special value */ /* */ /* df is the target decFloat (and source of coefficient/payload) */ /* set is the context for reporting status */ /* exp is the unbiased exponent, q, or a special value in the form */ /* returned by decFloatGetExponent */ -/* returns df, which will be canonical */ +/* returns df, which will be canonical */ /* */ -/* No error is possible, but Overflow or Underflow might occur. */ +/* No error is possible, but Overflow or Underflow might occur. */ /* ------------------------------------------------------------------ */ decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) { - uByte bcdcopy[DECPMAX]; /* for coefficient */ + uByte bcdcopy[DECPMAX]; /* for coefficient */ bcdnum num; /* work */ num.exponent=exp; num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */ @@ -1095,15 +1163,15 @@ uInt decFloatRadix(const decFloat *df) { } /* decFloatRadix */ /* ------------------------------------------------------------------ */ -/* decFloatShow -- printf a decFloat in hexadecimal and decimal */ -/* df is the decFloat to show */ +/* decFloatShow -- printf a decFloat in hexadecimal and decimal */ +/* df is the decFloat to show */ /* tag is a tag string displayed with the number */ /* */ /* This is a debug aid; the precise format of the string may change. */ /* ------------------------------------------------------------------ */ void decFloatShow(const decFloat *df, const char *tag) { char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */ - char buff[DECSTRING]; /* for value in decimal */ + char buff[DECSTRING]; /* for value in decimal */ Int i, j=0; for (i=0; i<DECBYTES; i++) { @@ -1126,7 +1194,7 @@ void decFloatShow(const decFloat *df, const char *tag) { /* */ /* df is the source decFloat */ /* exp will be set to the unbiased exponent, q, or to a special */ -/* value in the form returned by decFloatGetExponent */ +/* value in the form returned by decFloatGetExponent */ /* bcdar is where DECPMAX bytes will be written, one BCD digit in */ /* each byte (BCD8 encoding); if df is a NaN the first byte will */ /* be zero, and if it is infinite they will all be zero */ @@ -1156,7 +1224,7 @@ Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) { /* ------------------------------------------------------------------ */ /* decFloatToEngString -- conversion to numeric string, engineering */ /* */ -/* df is the decFloat format number to convert */ +/* df is the decFloat format number to convert */ /* string is the string where the result will be laid out */ /* */ /* string must be at least DECPMAX+9 characters (the worst case is */ @@ -1169,11 +1237,14 @@ char * decFloatToEngString(const decFloat *df, char *string){ uInt msd; /* coefficient MSD */ Int exp; /* exponent top two bits or full */ uInt comb; /* combination field */ - char *cstart; /* coefficient start */ + char *cstart; /* coefficient start */ char *c; /* output pointer in string */ char *s, *t; /* .. (source, target) */ Int pre, e; /* work */ const uByte *u; /* .. */ + uInt uiwork; /* for macros [one compiler needs */ + /* volatile here to avoid bug, but */ + /* that doubles execution time] */ /* Source words; macro handles endianness */ uInt sourhi=DFWORD(df, 0); /* word with sign */ @@ -1188,12 +1259,12 @@ char * decFloatToEngString(const decFloat *df, char *string){ c=string; /* where result will go */ if (((Int)sourhi)<0) *c++='-'; /* handle sign */ comb=sourhi>>26; /* sign+combination field */ - msd=DECCOMBMSD[comb]; /* decode the combination field */ - exp=DECCOMBEXP[comb]; /* .. */ + msd=DECCOMBMSD[comb]; /* decode the combination field */ + exp=DECCOMBEXP[comb]; /* .. */ if (EXPISSPECIAL(exp)) { /* special */ if (exp==DECFLOAT_Inf) { /* infinity */ - strcpy(c, "Inf"); + strcpy(c, "Inf"); strcpy(c+3, "inity"); return string; /* easy */ } @@ -1225,44 +1296,44 @@ char * decFloatToEngString(const decFloat *df, char *string){ /* are the three encoded BCD8 digits followed by a 1-byte length */ /* (significant digits, except that 000 has length 0). This allows */ /* us to left-align the first declet with non-zero content, then */ - /* the remaining ones are full 3-char length. Fixed-length copies */ + /* the remaining ones are full 3-char length. Fixed-length copies */ /* are used because variable-length memcpy causes a subroutine call */ - /* in at least two compilers. (The copies are length 4 for speed */ + /* in at least two compilers. (The copies are length 4 for speed */ /* and are safe because the last item in the array is of length */ /* three and has the length byte following.) */ #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ - if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \ + if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \ else if (*(u+3)) { \ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);} + UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);} #if DECPMAX==7 - dpd2char(sourhi>>10); /* declet 1 */ + dpd2char(sourhi>>10); /* declet 1 */ dpd2char(sourhi); /* declet 2 */ #elif DECPMAX==16 dpd2char(sourhi>>8); /* declet 1 */ dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ - dpd2char(sourlo>>20); /* declet 3 */ - dpd2char(sourlo>>10); /* declet 4 */ + dpd2char(sourlo>>20); /* declet 3 */ + dpd2char(sourlo>>10); /* declet 4 */ dpd2char(sourlo); /* declet 5 */ #elif DECPMAX==34 dpd2char(sourhi>>4); /* declet 1 */ dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ - dpd2char(sourmh>>16); /* declet 3 */ + dpd2char(sourmh>>16); /* declet 3 */ dpd2char(sourmh>>6); /* declet 4 */ dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ - dpd2char(sourml>>18); /* declet 6 */ + dpd2char(sourml>>18); /* declet 6 */ dpd2char(sourml>>8); /* declet 7 */ dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ - dpd2char(sourlo>>20); /* declet 9 */ - dpd2char(sourlo>>10); /* declet 10 */ + dpd2char(sourlo>>20); /* declet 9 */ + dpd2char(sourlo>>10); /* declet 10 */ dpd2char(sourlo); /* declet 11 */ #endif if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ - if (exp==0) { /* integer or NaN case -- easy */ + if (exp==0) { /* integer or NaN case -- easy */ *c='\0'; /* terminate */ return string; } @@ -1275,7 +1346,7 @@ char * decFloatToEngString(const decFloat *df, char *string){ if (exp>0 || pre<-5) { /* need exponential form */ e=pre-1; /* calculate E value */ pre=1; /* assume one digit before '.' */ - if (e!=0) { /* engineering: may need to adjust */ + if (e!=0) { /* engineering: may need to adjust */ Int adj; /* adjustment */ /* The C remainder operator is undefined for negative numbers, so */ /* a positive remainder calculation must be used here */ @@ -1310,8 +1381,8 @@ char * decFloatToEngString(const decFloat *df, char *string){ /* because there is still space for exponent */ s=dotat+ROUNDDOWN4(c-dotat); /* source */ t=s+1; /* target */ - /* open the gap */ - for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s); + /* open the gap [cannot use memcpy] */ + for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); *dotat='.'; c++; /* length increased by one */ } /* need dot? */ @@ -1321,24 +1392,24 @@ char * decFloatToEngString(const decFloat *df, char *string){ /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have E, but only for 0.00E+3 kind of case -- with plenty of spare space in this case */ - pre=-pre+2; /* gap width, including "0." */ + pre=-pre+2; /* gap width, including "0." */ t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ /* backoff if too far to the right */ if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ /* now shift the entire coefficient to the right, being careful not */ - /* to access to the left of string */ - for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s); + /* to access to the left of string [cannot use memcpy] */ + for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); /* for Quads and Singles there may be a character or two left... */ s+=3; /* where next would come from */ for(; s>=cstart; s--, t--) *(t+3)=*(s); /* now have fill 0. through 0.00000; use overlaps to avoid tests */ if (pre>=4) { - UINTAT(cstart+pre-4)=UINTAT("0000"); - UINTAT(cstart)=UINTAT("0.00"); + memcpy(cstart+pre-4, "0000", 4); + memcpy(cstart, "0.00", 4); } else { /* 2 or 3 */ *(cstart+pre-1)='0'; - USHORTAT(cstart)=USHORTAT("0."); + memcpy(cstart, "0.", 2); } c+=pre; /* to end */ } @@ -1346,7 +1417,7 @@ char * decFloatToEngString(const decFloat *df, char *string){ /* finally add the E-part, if needed; it will never be 0, and has */ /* a maximum length of 3 or 4 digits (asserted above) */ if (e!=0) { - USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */ + memcpy(c, "E+", 2); /* starts with E, assume + */ c++; if (e<0) { *c='-'; /* oops, need '-' */ @@ -1355,15 +1426,15 @@ char * decFloatToEngString(const decFloat *df, char *string){ c++; /* Three-character exponents are easy; 4-character a little trickier */ #if DECEMAXD<=3 - u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ + u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ /* copy fixed 4 characters [is safe], starting at non-zero */ /* and with character mask to convert BCD to char */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; + UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3); /* bump pointer appropriately */ #elif DECEMAXD==4 if (e<1000) { /* 3 (or fewer) digits case */ u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ + UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ c+=*(u+3); /* bump pointer appropriately */ } else { /* 4-digits */ @@ -1371,7 +1442,7 @@ char * decFloatToEngString(const decFloat *df, char *string){ Int rem=e-(1000*thou); /* e%1000 */ *c++=(char)('0'+(char)thou); /* the thousands digit */ u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ + UBFROMUI(c, UBTOUI(u)|CHARMASK);/* copy fixed 3+1 characters [is safe] */ c+=3; /* bump pointer, always 3 digits */ } #endif @@ -1386,7 +1457,7 @@ char * decFloatToEngString(const decFloat *df, char *string){ /* */ /* df is the source decFloat */ /* exp will be set to the unbiased exponent, q, or to a special */ -/* value in the form returned by decFloatGetExponent */ +/* value in the form returned by decFloatGetExponent */ /* packed is where DECPMAX nibbles will be written with the sign as */ /* final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */ /* of zero, and an infinity is all zeros. decDouble and decQuad */ @@ -1432,7 +1503,7 @@ Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) { /* ------------------------------------------------------------------ */ /* decFloatToString -- conversion to numeric string */ /* */ -/* df is the decFloat format number to convert */ +/* df is the decFloat format number to convert */ /* string is the string where the result will be laid out */ /* */ /* string must be at least DECPMAX+9 characters (the worst case is */ @@ -1445,11 +1516,14 @@ char * decFloatToString(const decFloat *df, char *string){ uInt msd; /* coefficient MSD */ Int exp; /* exponent top two bits or full */ uInt comb; /* combination field */ - char *cstart; /* coefficient start */ + char *cstart; /* coefficient start */ char *c; /* output pointer in string */ char *s, *t; /* .. (source, target) */ Int pre, e; /* work */ const uByte *u; /* .. */ + uInt uiwork; /* for macros [one compiler needs */ + /* volatile here to avoid bug, but */ + /* that doubles execution time] */ /* Source words; macro handles endianness */ uInt sourhi=DFWORD(df, 0); /* word with sign */ @@ -1464,10 +1538,14 @@ char * decFloatToString(const decFloat *df, char *string){ c=string; /* where result will go */ if (((Int)sourhi)<0) *c++='-'; /* handle sign */ comb=sourhi>>26; /* sign+combination field */ - msd=DECCOMBMSD[comb]; /* decode the combination field */ - exp=DECCOMBEXP[comb]; /* .. */ + msd=DECCOMBMSD[comb]; /* decode the combination field */ + exp=DECCOMBEXP[comb]; /* .. */ - if (EXPISSPECIAL(exp)) { /* special */ + if (!EXPISSPECIAL(exp)) { /* finite */ + /* complete exponent; top two bits are in place */ + exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ + } + else { /* IS special */ if (exp==DECFLOAT_Inf) { /* infinity */ strcpy(c, "Infinity"); return string; /* easy */ @@ -1487,9 +1565,6 @@ char * decFloatToString(const decFloat *df, char *string){ /* otherwise drop through to add integer; set correct exp etc. */ exp=0; msd=0; /* setup for following code */ } - else { /* complete exponent; top two bits are in place */ - exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ - } /* convert the digits of the significand to characters */ cstart=c; /* save start of coefficient */ @@ -1500,38 +1575,38 @@ char * decFloatToString(const decFloat *df, char *string){ /* are the three encoded BCD8 digits followed by a 1-byte length */ /* (significant digits, except that 000 has length 0). This allows */ /* us to left-align the first declet with non-zero content, then */ - /* the remaining ones are full 3-char length. Fixed-length copies */ + /* the remaining ones are full 3-char length. Fixed-length copies */ /* are used because variable-length memcpy causes a subroutine call */ - /* in at least two compilers. (The copies are length 4 for speed */ + /* in at least two compilers. (The copies are length 4 for speed */ /* and are safe because the last item in the array is of length */ /* three and has the length byte following.) */ #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ - if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \ + if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \ else if (*(u+3)) { \ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);} + UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);} #if DECPMAX==7 - dpd2char(sourhi>>10); /* declet 1 */ + dpd2char(sourhi>>10); /* declet 1 */ dpd2char(sourhi); /* declet 2 */ #elif DECPMAX==16 dpd2char(sourhi>>8); /* declet 1 */ dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ - dpd2char(sourlo>>20); /* declet 3 */ - dpd2char(sourlo>>10); /* declet 4 */ + dpd2char(sourlo>>20); /* declet 3 */ + dpd2char(sourlo>>10); /* declet 4 */ dpd2char(sourlo); /* declet 5 */ #elif DECPMAX==34 dpd2char(sourhi>>4); /* declet 1 */ dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ - dpd2char(sourmh>>16); /* declet 3 */ + dpd2char(sourmh>>16); /* declet 3 */ dpd2char(sourmh>>6); /* declet 4 */ dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ - dpd2char(sourml>>18); /* declet 6 */ + dpd2char(sourml>>18); /* declet 6 */ dpd2char(sourml>>8); /* declet 7 */ dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ - dpd2char(sourlo>>20); /* declet 9 */ - dpd2char(sourlo>>10); /* declet 10 */ + dpd2char(sourlo>>20); /* declet 9 */ + dpd2char(sourlo>>10); /* declet 10 */ dpd2char(sourlo); /* declet 11 */ #endif @@ -1556,12 +1631,13 @@ char * decFloatToString(const decFloat *df, char *string){ if (pre>0) { /* ddd.ddd (plain), perhaps with E */ char *dotat=cstart+pre; if (dotat<c) { /* if embedded dot needed... */ + /* [memmove is a disaster, here] */ /* move by fours; there must be space for junk at the end */ - /* because there is still space for exponent */ + /* because exponent is still possible */ s=dotat+ROUNDDOWN4(c-dotat); /* source */ t=s+1; /* target */ - /* open the gap */ - for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s); + /* open the gap [cannot use memcpy] */ + for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); *dotat='.'; c++; /* length increased by one */ } /* need dot? */ @@ -1569,10 +1645,10 @@ char * decFloatToString(const decFloat *df, char *string){ /* finally add the E-part, if needed; it will never be 0, and has */ /* a maximum length of 3 or 4 digits (asserted above) */ if (e!=0) { - USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */ + memcpy(c, "E+", 2); /* starts with E, assume + */ c++; if (e<0) { - *c='-'; /* oops, need '-' */ + *c='-'; /* oops, need '-' */ e=-e; /* uInt, please */ } c++; @@ -1581,21 +1657,21 @@ char * decFloatToString(const decFloat *df, char *string){ u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ /* copy fixed 4 characters [is safe], starting at non-zero */ /* and with character mask to convert BCD to char */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; + UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3); /* bump pointer appropriately */ #elif DECEMAXD==4 if (e<1000) { /* 3 (or fewer) digits case */ u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ + UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ c+=*(u+3); /* bump pointer appropriately */ } - else { /* 4-digits */ + else { /* 4-digits */ Int thou=((e>>3)*1049)>>17; /* e/1000 */ Int rem=e-(1000*thou); /* e%1000 */ *c++=(char)('0'+(char)thou); /* the thousands digit */ u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ - c+=3; /* bump pointer, always 3 digits */ + UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */ + c+=3; /* bump pointer, always 3 digits */ } #endif } @@ -1618,19 +1694,19 @@ char * decFloatToString(const decFloat *df, char *string){ /* backoff if too far to the right */ if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ /* now shift the entire coefficient to the right, being careful not */ - /* to access to the left of string */ - for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s); + /* to access to the left of string [cannot use memcpy] */ + for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); /* for Quads and Singles there may be a character or two left... */ - s+=3; /* where next would come from */ + s+=3; /* where next would come from */ for(; s>=cstart; s--, t--) *(t+3)=*(s); /* now have fill 0. through 0.00000; use overlaps to avoid tests */ if (pre>=4) { - UINTAT(cstart+pre-4)=UINTAT("0000"); - UINTAT(cstart)=UINTAT("0.00"); + memcpy(cstart+pre-4, "0000", 4); + memcpy(cstart, "0.00", 4); } else { /* 2 or 3 */ *(cstart+pre-1)='0'; - USHORTAT(cstart)=USHORTAT("0."); + memcpy(cstart, "0.", 2); } *(c+pre)='\0'; /* terminate */ return string; @@ -1665,7 +1741,7 @@ decFloatWider * decFloatToWider(const decFloat *source, decFloatWider *wider) { code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */ code|=DFWORD(source, 0)&0x80000000; /* add sign */ DFWWORD(wider, 0)=code; /* .. and place top word in wider */ - msd=GETMSD(source); /* get source coefficient MSD [0-9] */ + msd=GETMSD(source); /* get source coefficient MSD [0-9] */ } /* Copy the coefficient and clear any 'unused' words to left */ #if SINGLE @@ -1723,6 +1799,7 @@ decFloat * decFloatZero(decFloat *df){ void decShowNum(const bcdnum *num, const char *tag) { const char *csign="+"; /* sign character */ uByte *ub; /* work */ + uInt uiwork; /* for macros */ if (num->sign==DECFLOAT_Sign) csign="-"; printf(">%s> ", tag); @@ -1747,7 +1824,7 @@ decFloat * decFloatZero(decFloat *df){ if (e==0) *c++='0'; /* 0-length case */ else if (e<1000) { /* 3 (or fewer) digits case */ u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ + UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ c+=*(u+3); /* bump pointer appropriately */ } else { /* 4-digits */ @@ -1755,7 +1832,7 @@ decFloat * decFloatZero(decFloat *df){ Int rem=e-(1000*thou); /* e%1000 */ *c++=(char)('0'+(char)thou); /* the thousands digit */ u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ + UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */ c+=3; /* bump pointer, always 3 digits */ } *c='\0'; /* add terminator */ diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c index d2e3bed4397..b1d1cc4e47b 100644 --- a/libdecnumber/decContext.c +++ b/libdecnumber/decContext.c @@ -38,15 +38,13 @@ #include <string.h> /* for strcmp */ #include <stdio.h> /* for printf if DECCHECK */ #include "dconfig.h" /* for GCC definitions */ -#include "decContext.h" /* context and base types */ +#include "decContext.h" /* context and base types */ #include "decNumberLocal.h" /* decNumber local types, etc. */ -#if DECCHECK /* compile-time endian tester [assumes sizeof(Int)>1] */ static const Int mfcone=1; /* constant 1 */ -static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */ +static const Flag *mfctop=(const Flag *)&mfcone; /* -> top byte */ #define LITEND *mfctop /* named flag; 1=little-endian */ -#endif /* ------------------------------------------------------------------ */ /* round-for-reround digits */ @@ -64,7 +62,7 @@ const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000, /* */ /* context is the context structure to be queried */ /* mask indicates the bits to be cleared (the status bit that */ -/* corresponds to each 1 bit in the mask is cleared) */ +/* corresponds to each 1 bit in the mask is cleared) */ /* returns context */ /* */ /* No error is possible. */ @@ -80,9 +78,9 @@ decContext *decContextClearStatus(decContext *context, uInt mask) { /* context is the structure to be initialized */ /* kind selects the required set of default values, one of: */ /* DEC_INIT_BASE -- select ANSI X3-274 defaults */ -/* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */ -/* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */ -/* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */ +/* DEC_INIT_DECIMAL32 -- select IEEE 754 defaults, 32-bit */ +/* DEC_INIT_DECIMAL64 -- select IEEE 754 defaults, 64-bit */ +/* DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit */ /* For any other value a valid context is returned, but with */ /* Invalid_operation set in the status field. */ /* returns a context structure with the appropriate initial values. */ @@ -105,11 +103,11 @@ decContext * decContextDefault(decContext *context, Int kind) { break; case DEC_INIT_DECIMAL32: context->digits=7; /* digits */ - context->emax=96; /* Emax */ + context->emax=96; /* Emax */ context->emin=-95; /* Emin */ context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ - context->traps=0; /* no traps set */ - context->clamp=1; /* clamp exponents */ + context->traps=0; /* no traps set */ + context->clamp=1; /* clamp exponents */ #if DECSUBSET context->extended=1; /* set */ #endif @@ -119,8 +117,8 @@ decContext * decContextDefault(decContext *context, Int kind) { context->emax=384; /* Emax */ context->emin=-383; /* Emin */ context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ - context->traps=0; /* no traps set */ - context->clamp=1; /* clamp exponents */ + context->traps=0; /* no traps set */ + context->clamp=1; /* clamp exponents */ #if DECSUBSET context->extended=1; /* set */ #endif @@ -130,8 +128,8 @@ decContext * decContextDefault(decContext *context, Int kind) { context->emax=6144; /* Emax */ context->emin=-6143; /* Emin */ context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ - context->traps=0; /* no traps set */ - context->clamp=1; /* clamp exponents */ + context->traps=0; /* no traps set */ + context->clamp=1; /* clamp exponents */ #if DECSUBSET context->extended=1; /* set */ #endif @@ -142,15 +140,6 @@ decContext * decContextDefault(decContext *context, Int kind) { decContextSetStatus(context, DEC_Invalid_operation); /* trap */ } - #if DECCHECK - if (LITEND!=DECLITEND) { - const char *adj; - if (LITEND) adj="little"; - else adj="big"; - printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n", - DECLITEND, adj); - } - #endif return context;} /* decContextDefault */ /* ------------------------------------------------------------------ */ @@ -166,7 +155,7 @@ enum rounding decContextGetRounding(decContext *context) { } /* decContextGetRounding */ /* ------------------------------------------------------------------ */ -/* decContextGetStatus -- return current status */ +/* decContextGetStatus -- return current status */ /* */ /* context is the context structure to be queried */ /* returns status */ @@ -181,8 +170,8 @@ uInt decContextGetStatus(decContext *context) { /* decContextRestoreStatus -- restore bits in current status */ /* */ /* context is the context structure to be updated */ -/* newstatus is the source for the bits to be restored */ -/* mask indicates the bits to be restored (the status bit that */ +/* newstatus is the source for the bits to be restored */ +/* mask indicates the bits to be restored (the status bit that */ /* corresponds to each 1 bit in the mask is set to the value of */ /* the correspnding bit in newstatus) */ /* returns context */ @@ -252,7 +241,7 @@ decContext * decContextSetStatus(decContext *context, uInt status) { /* */ /* returns the context structure, unless the string is equal to */ /* DEC_Condition_MU or is not recognized. In these cases NULL is */ -/* returned. */ +/* returned. */ /* ------------------------------------------------------------------ */ decContext * decContextSetStatusFromString(decContext *context, const char *string) { @@ -303,7 +292,7 @@ decContext * decContextSetStatusFromString(decContext *context, /* */ /* returns the context structure, unless the string is equal to */ /* DEC_Condition_MU or is not recognized. In these cases NULL is */ -/* returned. */ +/* returned. */ /* ------------------------------------------------------------------ */ decContext * decContextSetStatusFromStringQuiet(decContext *context, const char *string) { @@ -356,11 +345,11 @@ decContext * decContextSetStatusQuiet(decContext *context, uInt status) { return context;} /* decContextSetStatusQuiet */ /* ------------------------------------------------------------------ */ -/* decContextStatusToString -- convert status flags to a string */ +/* decContextStatusToString -- convert status flags to a string */ /* */ /* context is a context with valid status field */ /* */ -/* returns a constant string describing the condition. If multiple */ +/* returns a constant string describing the condition. If multiple */ /* (or no) flags are set, a generic constant message is returned. */ /* ------------------------------------------------------------------ */ const char *decContextStatusToString(const decContext *context) { @@ -385,11 +374,41 @@ const char *decContextStatusToString(const decContext *context) { #if DECSUBSET if (status==DEC_Lost_digits ) return DEC_Condition_LD; #endif - if (status==0 ) return DEC_Condition_ZE; + if (status==0 ) return DEC_Condition_ZE; return DEC_Condition_MU; /* Multiple errors */ } /* decContextStatusToString */ /* ------------------------------------------------------------------ */ +/* decContextTestEndian -- test whether DECLITEND is set correctly */ +/* */ +/* quiet is 1 to suppress message; 0 otherwise */ +/* returns 0 if DECLITEND is correct */ +/* 1 if DECLITEND is incorrect and should be 1 */ +/* -1 if DECLITEND is incorrect and should be 0 */ +/* */ +/* A message is displayed if the return value is not 0 and quiet==0. */ +/* */ +/* No error is possible. */ +/* ------------------------------------------------------------------ */ +Int decContextTestEndian(Flag quiet) { + Int res=0; /* optimist */ + uInt dle=(uInt)DECLITEND; /* unsign */ + if (dle>1) dle=1; /* ensure 0 or 1 */ + + if (LITEND!=DECLITEND) { + const char *adj; + if (!quiet) { + if (LITEND) adj="little"; + else adj="big"; + printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n", + DECLITEND, adj); + } + res=(Int)LITEND-dle; + } + return res; + } /* decContextTestEndian */ + +/* ------------------------------------------------------------------ */ /* decContextTestSavedStatus -- test bits in saved status */ /* */ /* oldstatus is the status word to be tested */ diff --git a/libdecnumber/decContext.h b/libdecnumber/decContext.h index f80d03c50cf..70effd80083 100644 --- a/libdecnumber/decContext.h +++ b/libdecnumber/decContext.h @@ -34,7 +34,7 @@ /* */ /* Context variables must always have valid values: */ /* */ -/* status -- [any bits may be cleared, but not set, by user] */ +/* status -- [any bits may be cleared, but not set, by user] */ /* round -- must be one of the enumerated rounding modes */ /* */ /* The following variables are implied for fixed size formats (i.e., */ @@ -54,36 +54,42 @@ #define DECCONTEXT #define DECCNAME "decContext" /* Short name */ #define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */ - #define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */ + #define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */ - #include "gstdint.h" /* C99 standard integers */ + #if !defined(int32_t) + #include <stdint.h> /* C99 standard integers */ + #endif #include <stdio.h> /* for printf, etc. */ - #include <signal.h> /* for traps */ + #include <signal.h> /* for traps */ /* Extended flags setting -- set this to 0 to use only IEEE flags */ + #if !defined(DECEXTFLAG) #define DECEXTFLAG 1 /* 1=enable extended flags */ + #endif /* Conditional code flag -- set this to 0 for best performance */ + #if !defined(DECSUBSET) #define DECSUBSET 0 /* 1=enable subset arithmetic */ + #endif /* Context for operations, with associated constants */ enum rounding { DEC_ROUND_CEILING, /* round towards +infinity */ - DEC_ROUND_UP, /* round away from 0 */ + DEC_ROUND_UP, /* round away from 0 */ DEC_ROUND_HALF_UP, /* 0.5 rounds up */ DEC_ROUND_HALF_EVEN, /* 0.5 rounds to nearest even */ DEC_ROUND_HALF_DOWN, /* 0.5 rounds down */ DEC_ROUND_DOWN, /* round towards 0 (truncate) */ DEC_ROUND_FLOOR, /* round towards -infinity */ - DEC_ROUND_05UP, /* round for reround */ + DEC_ROUND_05UP, /* round for reround */ DEC_ROUND_MAX /* enum must be less than this */ }; #define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN; typedef struct { - int32_t digits; /* working precision */ - int32_t emax; /* maximum positive exponent */ - int32_t emin; /* minimum negative exponent */ + int32_t digits; /* working precision */ + int32_t emax; /* maximum positive exponent */ + int32_t emin; /* minimum negative exponent */ enum rounding round; /* rounding mode */ uint32_t traps; /* trap-enabler flags */ uint32_t status; /* status flags */ @@ -102,9 +108,9 @@ #define DEC_MIN_EMIN -999999999 #define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */ - /* Classifications for decimal numbers, aligned with 754r (note */ - /* that 'normal' and 'subnormal' are meaningful only with a */ - /* decContext or a fixed size format). */ + /* Classifications for decimal numbers, aligned with 754 (note that */ + /* 'normal' and 'subnormal' are meaningful only with a decContext */ + /* or a fixed size format). */ enum decClass { DEC_CLASS_SNAN, DEC_CLASS_QNAN, @@ -139,15 +145,15 @@ #define DEC_Division_impossible 0x00000004 #define DEC_Division_undefined 0x00000008 #define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */ - #define DEC_Inexact 0x00000020 - #define DEC_Invalid_context 0x00000040 + #define DEC_Inexact 0x00000020 + #define DEC_Invalid_context 0x00000040 #define DEC_Invalid_operation 0x00000080 #if DECSUBSET #define DEC_Lost_digits 0x00000100 #endif #define DEC_Overflow 0x00000200 - #define DEC_Clamped 0x00000400 - #define DEC_Rounded 0x00000800 + #define DEC_Clamped 0x00000400 + #define DEC_Rounded 0x00000800 #define DEC_Subnormal 0x00001000 #define DEC_Underflow 0x00002000 #else @@ -157,43 +163,43 @@ #define DEC_Division_impossible 0x00000010 #define DEC_Division_undefined 0x00000010 #define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */ - #define DEC_Inexact 0x00000001 - #define DEC_Invalid_context 0x00000010 + #define DEC_Inexact 0x00000001 + #define DEC_Invalid_context 0x00000010 #define DEC_Invalid_operation 0x00000010 #if DECSUBSET #define DEC_Lost_digits 0x00000000 #endif #define DEC_Overflow 0x00000008 - #define DEC_Clamped 0x00000000 - #define DEC_Rounded 0x00000000 + #define DEC_Clamped 0x00000000 + #define DEC_Rounded 0x00000000 #define DEC_Subnormal 0x00000000 #define DEC_Underflow 0x00000004 #endif - /* IEEE 854 groupings for the flags */ + /* IEEE 754 groupings for the flags */ /* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */ - /* are not in IEEE 854] */ - #define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero) + /* are not in IEEE 754] */ + #define DEC_IEEE_754_Division_by_zero (DEC_Division_by_zero) #if DECSUBSET - #define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits) + #define DEC_IEEE_754_Inexact (DEC_Inexact | DEC_Lost_digits) #else - #define DEC_IEEE_854_Inexact (DEC_Inexact) + #define DEC_IEEE_754_Inexact (DEC_Inexact) #endif - #define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \ + #define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax | \ DEC_Division_impossible | \ DEC_Division_undefined | \ DEC_Insufficient_storage | \ - DEC_Invalid_context | \ + DEC_Invalid_context | \ DEC_Invalid_operation) - #define DEC_IEEE_854_Overflow (DEC_Overflow) - #define DEC_IEEE_854_Underflow (DEC_Underflow) + #define DEC_IEEE_754_Overflow (DEC_Overflow) + #define DEC_IEEE_754_Underflow (DEC_Underflow) /* flags which are normally errors (result is qNaN, infinite, or 0) */ - #define DEC_Errors (DEC_IEEE_854_Division_by_zero | \ - DEC_IEEE_854_Invalid_operation | \ - DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow) + #define DEC_Errors (DEC_IEEE_754_Division_by_zero | \ + DEC_IEEE_754_Invalid_operation | \ + DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow) /* flags which cause a result to become qNaN */ - #define DEC_NaNs DEC_IEEE_854_Invalid_operation + #define DEC_NaNs DEC_IEEE_754_Invalid_operation /* flags which are normally for information only (finite results) */ #if DECSUBSET @@ -203,6 +209,13 @@ #define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact) #endif + /* IEEE 854 names (for compatibility with older decNumber versions) */ + #define DEC_IEEE_854_Division_by_zero DEC_IEEE_754_Division_by_zero + #define DEC_IEEE_854_Inexact DEC_IEEE_754_Inexact + #define DEC_IEEE_854_Invalid_operation DEC_IEEE_754_Invalid_operation + #define DEC_IEEE_854_Overflow DEC_IEEE_754_Overflow + #define DEC_IEEE_854_Underflow DEC_IEEE_754_Underflow + /* Name strings for the exceptional conditions */ #define DEC_Condition_CS "Conversion syntax" #define DEC_Condition_DZ "Division by zero" @@ -226,7 +239,7 @@ /* including terminator */ /* Initialization descriptors, used by decContextDefault */ - #define DEC_INIT_BASE 0 + #define DEC_INIT_BASE 0 #define DEC_INIT_DECIMAL32 32 #define DEC_INIT_DECIMAL64 64 #define DEC_INIT_DECIMAL128 128 @@ -251,6 +264,7 @@ extern decContext * decContextSetStatusFromStringQuiet(decContext *, const char *); extern decContext * decContextSetStatusQuiet(decContext *, uint32_t); extern const char * decContextStatusToString(const decContext *); + extern int32_t decContextTestEndian(uint8_t); extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t); extern uint32_t decContextTestStatus(decContext *, uint32_t); extern decContext * decContextZeroStatus(decContext *); diff --git a/libdecnumber/decDPD.h b/libdecnumber/decDPD.h index a4710d64391..87b35d038b8 100644 --- a/libdecnumber/decDPD.h +++ b/libdecnumber/decDPD.h @@ -30,10 +30,9 @@ /* ------------------------------------------------------------------------ */ /* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */ -/* [Automatically generated -- do not edit. 2007.05.05] */ +/* [Automatically generated -- do not edit. 2008.06.21] */ /* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ -/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */ +/* For details, see DPDecimal.html on the General Decimal Arithmetic page. */ #include "decDPDSymbols.h" @@ -43,9 +42,9 @@ /* uint16_t BIN2DPD[1000]; -- Bin -> DPD (999 => 2457) */ /* uint8_t BIN2CHAR[4001]; -- Bin -> CHAR (999 => '\3' '9' '9' '9') */ /* uint8_t BIN2BCD8[4000]; -- Bin -> bytes (999 => 9 9 9 3) */ -/* uint16_t DPD2BCD[1024]; -- DPD -> BCD (0x3FF => 0x999) */ +/* uint16_t DPD2BCD[1024]; -- DPD -> BCD (0x3FF => 0x999) */ /* uint16_t DPD2BIN[1024]; -- DPD -> BIN (0x3FF => 999) */ -/* uint32_t DPD2BINK[1024]; -- DPD -> BIN * 1000 (0x3FF => 999000) */ +/* uint32_t DPD2BINK[1024]; -- DPD -> BIN * 1000 (0x3FF => 999000) */ /* uint32_t DPD2BINM[1024]; -- DPD -> BIN * 1E+6 (0x3FF => 999000000) */ /* uint8_t DPD2BCD8[4096]; -- DPD -> bytes (x3FF => 9 9 9 3) */ /* */ @@ -53,10 +52,10 @@ /* in the table entry. BIN2CHAR entries are a single byte length (0 for */ /* value 0) followed by three digit characters; a trailing terminator is */ /* included to allow 4-char moves always. BIN2BCD8 and DPD2BCD8 entries */ -/* are similar with the three BCD8 digits followed by a one-byte length */ +/* are similar with the three BCD8 digits followed by a one-byte length */ /* (again, length=0 for value 0). */ /* */ -/* To use a table, its name, prefixed with DEC_, must be defined with a */ +/* To use a table, its name, prefixed with DEC_, must be defined with a */ /* value of 1 before this header file is included. For example: */ /* #define DEC_BCD2DPD 1 */ /* This mechanism allows software to only include tables that are needed. */ @@ -513,7 +512,7 @@ const uint16_t DPD2BIN[1024]={ 0, 1, 2, 3, 4, 5, 6, 7, #if defined(DEC_DPD2BINK) && DEC_DPD2BINK==1 && !defined(DECDPD2BINK) #define DECDPD2BINK -const uint32_t DPD2BINK[1024]={ 0, 1000, 2000, 3000, 4000, 5000, +const uint32_t DPD2BINK[1024]={ 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 80000, 81000, 800000, 801000, 880000, 881000, 10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000, 90000, 91000, 810000, 811000, 890000, 891000, 20000, 21000, 22000, 23000, @@ -621,24 +620,24 @@ const uint32_t DPD2BINK[1024]={ 0, 1000, 2000, 3000, 4000, 5000, #if defined(DEC_DPD2BINM) && DEC_DPD2BINM==1 && !defined(DECDPD2BINM) #define DECDPD2BINM -const uint32_t DPD2BINM[1024]={0, 1000000, 2000000, 3000000, 4000000, - 5000000, 6000000, 7000000, 8000000, 9000000, 80000000, 81000000, - 800000000, 801000000, 880000000, 881000000, 10000000, 11000000, 12000000, - 13000000, 14000000, 15000000, 16000000, 17000000, 18000000, 19000000, +const uint32_t DPD2BINM[1024]={0, 1000000, 2000000, 3000000, 4000000, + 5000000, 6000000, 7000000, 8000000, 9000000, 80000000, 81000000, + 800000000, 801000000, 880000000, 881000000, 10000000, 11000000, 12000000, + 13000000, 14000000, 15000000, 16000000, 17000000, 18000000, 19000000, 90000000, 91000000, 810000000, 811000000, 890000000, 891000000, 20000000, - 21000000, 22000000, 23000000, 24000000, 25000000, 26000000, 27000000, + 21000000, 22000000, 23000000, 24000000, 25000000, 26000000, 27000000, 28000000, 29000000, 82000000, 83000000, 820000000, 821000000, 808000000, - 809000000, 30000000, 31000000, 32000000, 33000000, 34000000, 35000000, - 36000000, 37000000, 38000000, 39000000, 92000000, 93000000, 830000000, - 831000000, 818000000, 819000000, 40000000, 41000000, 42000000, 43000000, - 44000000, 45000000, 46000000, 47000000, 48000000, 49000000, 84000000, - 85000000, 840000000, 841000000, 88000000, 89000000, 50000000, 51000000, - 52000000, 53000000, 54000000, 55000000, 56000000, 57000000, 58000000, - 59000000, 94000000, 95000000, 850000000, 851000000, 98000000, 99000000, - 60000000, 61000000, 62000000, 63000000, 64000000, 65000000, 66000000, + 809000000, 30000000, 31000000, 32000000, 33000000, 34000000, 35000000, + 36000000, 37000000, 38000000, 39000000, 92000000, 93000000, 830000000, + 831000000, 818000000, 819000000, 40000000, 41000000, 42000000, 43000000, + 44000000, 45000000, 46000000, 47000000, 48000000, 49000000, 84000000, + 85000000, 840000000, 841000000, 88000000, 89000000, 50000000, 51000000, + 52000000, 53000000, 54000000, 55000000, 56000000, 57000000, 58000000, + 59000000, 94000000, 95000000, 850000000, 851000000, 98000000, 99000000, + 60000000, 61000000, 62000000, 63000000, 64000000, 65000000, 66000000, 67000000, 68000000, 69000000, 86000000, 87000000, 860000000, 861000000, - 888000000, 889000000, 70000000, 71000000, 72000000, 73000000, 74000000, - 75000000, 76000000, 77000000, 78000000, 79000000, 96000000, 97000000, + 888000000, 889000000, 70000000, 71000000, 72000000, 73000000, 74000000, + 75000000, 76000000, 77000000, 78000000, 79000000, 96000000, 97000000, 870000000, 871000000, 898000000, 899000000, 100000000, 101000000, 102000000, 103000000, 104000000, 105000000, 106000000, 107000000, 108000000, 109000000, 180000000, 181000000, 900000000, 901000000, 980000000, 981000000, 110000000, diff --git a/libdecnumber/decDouble.c b/libdecnumber/decDouble.c index ba6a0af893b..030cc2b86cd 100644 --- a/libdecnumber/decDouble.c +++ b/libdecnumber/decDouble.c @@ -34,19 +34,19 @@ /* This module comprises decDouble operations (including conversions) */ /* ------------------------------------------------------------------ */ -#include "decContext.h" /* public includes */ +#include "decContext.h" /* public includes */ #include "decDouble.h" /* .. */ /* Constant mappings for shared code */ -#define DECPMAX DECDOUBLE_Pmax -#define DECEMIN DECDOUBLE_Emin -#define DECEMAX DECDOUBLE_Emax +#define DECPMAX DECDOUBLE_Pmax +#define DECEMIN DECDOUBLE_Emin +#define DECEMAX DECDOUBLE_Emax #define DECEMAXD DECDOUBLE_EmaxD #define DECBYTES DECDOUBLE_Bytes #define DECSTRING DECDOUBLE_String #define DECECONL DECDOUBLE_EconL -#define DECBIAS DECDOUBLE_Bias -#define DECLETS DECDOUBLE_Declets +#define DECBIAS DECDOUBLE_Bias +#define DECLETS DECDOUBLE_Declets #define DECQTINY (-DECDOUBLE_Bias) /* parameters of next-wider format */ #define DECWBYTES DECQUAD_Bytes @@ -55,100 +55,98 @@ #define DECWBIAS DECQUAD_Bias /* Type and function mappings for shared code */ -#define decFloat decDouble /* Type name */ -#define decFloatWider decQuad /* Type name */ +#define decFloat decDouble /* Type name */ +#define decFloatWider decQuad /* Type name */ /* Utilities and conversions (binary results, extractors, etc.) */ -#define decFloatFromBCD decDoubleFromBCD -#define decFloatFromInt32 decDoubleFromInt32 -#define decFloatFromPacked decDoubleFromPacked -#define decFloatFromString decDoubleFromString -#define decFloatFromUInt32 decDoubleFromUInt32 -#define decFloatFromWider decDoubleFromWider -#define decFloatGetCoefficient decDoubleGetCoefficient -#define decFloatGetExponent decDoubleGetExponent -#define decFloatSetCoefficient decDoubleSetCoefficient -#define decFloatSetExponent decDoubleSetExponent -#define decFloatShow decDoubleShow -#define decFloatToBCD decDoubleToBCD -#define decFloatToEngString decDoubleToEngString -#define decFloatToInt32 decDoubleToInt32 -#define decFloatToInt32Exact decDoubleToInt32Exact -#define decFloatToPacked decDoubleToPacked -#define decFloatToString decDoubleToString -#define decFloatToUInt32 decDoubleToUInt32 -#define decFloatToUInt32Exact decDoubleToUInt32Exact -#define decFloatToWider decDoubleToWider -#define decFloatZero decDoubleZero +#define decFloatFromBCD decDoubleFromBCD +#define decFloatFromInt32 decDoubleFromInt32 +#define decFloatFromPacked decDoubleFromPacked +#define decFloatFromPackedChecked decDoubleFromPackedChecked +#define decFloatFromString decDoubleFromString +#define decFloatFromUInt32 decDoubleFromUInt32 +#define decFloatFromWider decDoubleFromWider +#define decFloatGetCoefficient decDoubleGetCoefficient +#define decFloatGetExponent decDoubleGetExponent +#define decFloatSetCoefficient decDoubleSetCoefficient +#define decFloatSetExponent decDoubleSetExponent +#define decFloatShow decDoubleShow +#define decFloatToBCD decDoubleToBCD +#define decFloatToEngString decDoubleToEngString +#define decFloatToInt32 decDoubleToInt32 +#define decFloatToInt32Exact decDoubleToInt32Exact +#define decFloatToPacked decDoubleToPacked +#define decFloatToString decDoubleToString +#define decFloatToUInt32 decDoubleToUInt32 +#define decFloatToUInt32Exact decDoubleToUInt32Exact +#define decFloatToWider decDoubleToWider +#define decFloatZero decDoubleZero /* Computational (result is a decFloat) */ -#define decFloatAbs decDoubleAbs -#define decFloatAdd decDoubleAdd -#define decFloatAnd decDoubleAnd -#define decFloatDivide decDoubleDivide -#define decFloatDivideInteger decDoubleDivideInteger -#define decFloatFMA decDoubleFMA -#define decFloatInvert decDoubleInvert -#define decFloatLogB decDoubleLogB -#define decFloatMax decDoubleMax -#define decFloatMaxMag decDoubleMaxMag -#define decFloatMin decDoubleMin -#define decFloatMinMag decDoubleMinMag -#define decFloatMinus decDoubleMinus -#define decFloatMultiply decDoubleMultiply -#define decFloatNextMinus decDoubleNextMinus -#define decFloatNextPlus decDoubleNextPlus -#define decFloatNextToward decDoubleNextToward -#define decFloatOr decDoubleOr -#define decFloatPlus decDoublePlus -#define decFloatQuantize decDoubleQuantize -#define decFloatReduce decDoubleReduce -#define decFloatRemainder decDoubleRemainder -#define decFloatRemainderNear decDoubleRemainderNear -#define decFloatRotate decDoubleRotate -#define decFloatScaleB decDoubleScaleB -#define decFloatShift decDoubleShift -#define decFloatSubtract decDoubleSubtract -#define decFloatToIntegralValue decDoubleToIntegralValue -#define decFloatToIntegralExact decDoubleToIntegralExact -#define decFloatXor decDoubleXor +#define decFloatAbs decDoubleAbs +#define decFloatAdd decDoubleAdd +#define decFloatAnd decDoubleAnd +#define decFloatDivide decDoubleDivide +#define decFloatDivideInteger decDoubleDivideInteger +#define decFloatFMA decDoubleFMA +#define decFloatInvert decDoubleInvert +#define decFloatLogB decDoubleLogB +#define decFloatMax decDoubleMax +#define decFloatMaxMag decDoubleMaxMag +#define decFloatMin decDoubleMin +#define decFloatMinMag decDoubleMinMag +#define decFloatMinus decDoubleMinus +#define decFloatMultiply decDoubleMultiply +#define decFloatNextMinus decDoubleNextMinus +#define decFloatNextPlus decDoubleNextPlus +#define decFloatNextToward decDoubleNextToward +#define decFloatOr decDoubleOr +#define decFloatPlus decDoublePlus +#define decFloatQuantize decDoubleQuantize +#define decFloatReduce decDoubleReduce +#define decFloatRemainder decDoubleRemainder +#define decFloatRemainderNear decDoubleRemainderNear +#define decFloatRotate decDoubleRotate +#define decFloatScaleB decDoubleScaleB +#define decFloatShift decDoubleShift +#define decFloatSubtract decDoubleSubtract +#define decFloatToIntegralValue decDoubleToIntegralValue +#define decFloatToIntegralExact decDoubleToIntegralExact +#define decFloatXor decDoubleXor /* Comparisons */ -#define decFloatCompare decDoubleCompare -#define decFloatCompareSignal decDoubleCompareSignal -#define decFloatCompareTotal decDoubleCompareTotal -#define decFloatCompareTotalMag decDoubleCompareTotalMag +#define decFloatCompare decDoubleCompare +#define decFloatCompareSignal decDoubleCompareSignal +#define decFloatCompareTotal decDoubleCompareTotal +#define decFloatCompareTotalMag decDoubleCompareTotalMag /* Copies */ -#define decFloatCanonical decDoubleCanonical -#define decFloatCopy decDoubleCopy -#define decFloatCopyAbs decDoubleCopyAbs -#define decFloatCopyNegate decDoubleCopyNegate -#define decFloatCopySign decDoubleCopySign +#define decFloatCanonical decDoubleCanonical +#define decFloatCopy decDoubleCopy +#define decFloatCopyAbs decDoubleCopyAbs +#define decFloatCopyNegate decDoubleCopyNegate +#define decFloatCopySign decDoubleCopySign /* Non-computational */ -#define decFloatClass decDoubleClass -#define decFloatClassString decDoubleClassString -#define decFloatDigits decDoubleDigits -#define decFloatIsCanonical decDoubleIsCanonical -#define decFloatIsFinite decDoubleIsFinite -#define decFloatIsInfinite decDoubleIsInfinite -#define decFloatIsInteger decDoubleIsInteger -#define decFloatIsNaN decDoubleIsNaN -#define decFloatIsNormal decDoubleIsNormal -#define decFloatIsSignaling decDoubleIsSignaling -#define decFloatIsSignalling decDoubleIsSignalling -#define decFloatIsSigned decDoubleIsSigned -#define decFloatIsSubnormal decDoubleIsSubnormal -#define decFloatIsZero decDoubleIsZero -#define decFloatRadix decDoubleRadix -#define decFloatSameQuantum decDoubleSameQuantum -#define decFloatVersion decDoubleVersion - +#define decFloatClass decDoubleClass +#define decFloatClassString decDoubleClassString +#define decFloatDigits decDoubleDigits +#define decFloatIsCanonical decDoubleIsCanonical +#define decFloatIsFinite decDoubleIsFinite +#define decFloatIsInfinite decDoubleIsInfinite +#define decFloatIsInteger decDoubleIsInteger +#define decFloatIsNaN decDoubleIsNaN +#define decFloatIsNormal decDoubleIsNormal +#define decFloatIsSignaling decDoubleIsSignaling +#define decFloatIsSignalling decDoubleIsSignalling +#define decFloatIsSigned decDoubleIsSigned +#define decFloatIsSubnormal decDoubleIsSubnormal +#define decFloatIsZero decDoubleIsZero +#define decFloatRadix decDoubleRadix +#define decFloatSameQuantum decDoubleSameQuantum +#define decFloatVersion decDoubleVersion #include "decNumberLocal.h" /* local includes (need DECPMAX) */ #include "decCommon.c" /* non-arithmetic decFloat routines */ #include "decBasic.c" /* basic formats routines */ -/* Below here will move to shared file as completed */ - diff --git a/libdecnumber/decDouble.h b/libdecnumber/decDouble.h index 53fcf406bec..aa8d77d4b73 100644 --- a/libdecnumber/decDouble.h +++ b/libdecnumber/decDouble.h @@ -31,24 +31,22 @@ /* ------------------------------------------------------------------ */ /* decDouble.h -- Decimal 64-bit format module header */ /* ------------------------------------------------------------------ */ -/* Please see decFloats.h for an overview and documentation details. */ -/* ------------------------------------------------------------------ */ #if !defined(DECDOUBLE) #define DECDOUBLE - #define DECDOUBLENAME "decimalDouble" /* Short name */ + #define DECDOUBLENAME "decimalDouble" /* Short name */ #define DECDOUBLETITLE "Decimal 64-bit datum" /* Verbose name */ #define DECDOUBLEAUTHOR "Mike Cowlishaw" /* Who to blame */ /* parameters for decDoubles */ #define DECDOUBLE_Bytes 8 /* length */ #define DECDOUBLE_Pmax 16 /* maximum precision (digits) */ - #define DECDOUBLE_Emin -383 /* minimum adjusted exponent */ - #define DECDOUBLE_Emax 384 /* maximum adjusted exponent */ + #define DECDOUBLE_Emin -383 /* minimum adjusted exponent */ + #define DECDOUBLE_Emax 384 /* maximum adjusted exponent */ #define DECDOUBLE_EmaxD 3 /* maximum exponent digits */ - #define DECDOUBLE_Bias 398 /* bias for the exponent */ - #define DECDOUBLE_String 25 /* maximum string length, +1 */ + #define DECDOUBLE_Bias 398 /* bias for the exponent */ + #define DECDOUBLE_String 25 /* maximum string length, +1 */ #define DECDOUBLE_EconL 8 /* exponent continuation length */ #define DECDOUBLE_Declets 5 /* count of declets */ /* highest biased exponent (Elimit-1) */ @@ -58,11 +56,14 @@ #include "decContext.h" #include "decQuad.h" - /* The decDouble decimal 64-bit type, accessible by various types */ + /* The decDouble decimal 64-bit type, accessible by all sizes */ typedef union { - uint8_t bytes[DECDOUBLE_Bytes]; /* fields: 1, 5, 8, 50 bits */ + uint8_t bytes[DECDOUBLE_Bytes]; /* fields: 1, 5, 8, 50 bits */ uint16_t shorts[DECDOUBLE_Bytes/2]; - uint32_t words[DECDOUBLE_Bytes/4]; + uint32_t words[DECDOUBLE_Bytes/4]; + #if DECUSE64 + uint64_t longs[DECDOUBLE_Bytes/8]; + #endif } decDouble; /* ---------------------------------------------------------------- */ @@ -75,6 +76,7 @@ extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t); extern decDouble * decDoubleFromInt32(decDouble *, int32_t); extern decDouble * decDoubleFromPacked(decDouble *, int32_t, const uint8_t *); + extern decDouble * decDoubleFromPackedChecked(decDouble *, int32_t, const uint8_t *); extern decDouble * decDoubleFromString(decDouble *, const char *, decContext *); extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t); extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *); @@ -160,7 +162,8 @@ /* decNumber conversions; these are implemented as macros so as not */ /* to force a dependency on decimal64 and decNumber in decDouble. */ + /* decDoubleFromNumber returns a decimal64 * to avoid warnings. */ #define decDoubleToNumber(dq, dn) decimal64ToNumber((decimal64 *)(dq), dn) - #define decDoubleFromNumber(dq, dn, set) (decDouble *)decimal64FromNumber((decimal64 *)(dq), dn, set) + #define decDoubleFromNumber(dq, dn, set) decimal64FromNumber((decimal64 *)(dq), dn, set) #endif diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c index f9a624a1afa..ebc7cf0fb50 100644 --- a/libdecnumber/decNumber.c +++ b/libdecnumber/decNumber.c @@ -31,24 +31,35 @@ /* ------------------------------------------------------------------ */ /* Decimal Number arithmetic module */ /* ------------------------------------------------------------------ */ -/* This module comprises the routines for General Decimal Arithmetic */ -/* as defined in the specification which may be found on the */ -/* http://www2.hursley.ibm.com/decimal web pages. It implements both */ +/* This module comprises the routines for arbitrary-precision General */ +/* Decimal Arithmetic as defined in the specification which may be */ +/* found on the General Decimal Arithmetic pages. It implements both */ /* the full ('extended') arithmetic and the simpler ('subset') */ /* arithmetic. */ /* */ -/* Usage notes: */ +/* Usage notes: */ /* */ /* 1. This code is ANSI C89 except: */ /* */ -/* If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and */ +/* a) C99 line comments (double forward slash) are used. (Most C */ +/* compilers accept these. If yours does not, a simple script */ +/* can be used to convert them to ANSI C comments.) */ +/* */ +/* b) Types from C99 stdint.h are used. If you do not have this */ +/* header file, see the User's Guide section of the decNumber */ +/* documentation; this lists the necessary definitions. */ +/* */ +/* c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and */ /* uint64_t types may be used. To avoid these, set DECUSE64=0 */ /* and DECDPUN<=4 (see documentation). */ /* */ +/* The code also conforms to C99 restrictions; in particular, */ +/* strict aliasing rules are observed. */ +/* */ /* 2. The decNumber format which this library uses is optimized for */ /* efficient processing of relatively short numbers; in particular */ /* it allows the use of fixed sized structures and minimizes copy */ -/* and move operations. It does, however, support arbitrary */ +/* and move operations. It does, however, support arbitrary */ /* precision (up to 999,999,999 digits) and arbitrary exponent */ /* range (Emax in the range 0 through 999,999,999 and Emin in the */ /* range -999,999,999 through 0). Mathematical functions (for */ @@ -67,7 +78,7 @@ /* permitted). Other than that case, operands must not overlap. */ /* */ /* 5. Error handling: the type of the error is ORed into the status */ -/* flags in the current context (decContext structure). The */ +/* flags in the current context (decContext structure). The */ /* SIGFPE signal is then raised if the corresponding trap-enabler */ /* flag in the decContext is set (is 1). */ /* */ @@ -76,7 +87,7 @@ /* */ /* The result of any routine which returns a number will always */ /* be a valid number (which may be a special value, such as an */ -/* Infinity or NaN). */ +/* Infinity or NaN). */ /* */ /* 6. The decNumber format is not an exchangeable concrete */ /* representation as it comprises fields which may be machine- */ @@ -84,10 +95,10 @@ /* Canonical conversions to and from strings are provided; other */ /* conversions are available in separate modules. */ /* */ -/* 7. Normally, input operands are assumed to be valid. Set DECCHECK */ +/* 7. Normally, input operands are assumed to be valid. Set DECCHECK */ /* to 1 for extended operand checking (including NULL operands). */ /* Results are undefined if a badly-formed structure (or a NULL */ -/* pointer to a structure) is provided, though with DECCHECK */ +/* pointer to a structure) is provided, though with DECCHECK */ /* enabled the operator routines are protected against exceptions. */ /* (Except if the result pointer is NULL, which is unrecoverable.) */ /* */ @@ -98,7 +109,7 @@ /* */ /* 8. Subset arithmetic is available only if DECSUBSET is set to 1. */ /* ------------------------------------------------------------------ */ -/* Implementation notes for maintenance of this module: */ +/* Implementation notes for maintenance of this module: */ /* */ /* 1. Storage leak protection: Routines which use malloc are not */ /* permitted to use return for fastpath or error exits (i.e., */ @@ -115,7 +126,7 @@ /* 3. Setting status in the context must always be the very last */ /* action in a routine, as non-0 status may raise a trap and hence */ /* the call to set status may not return (if the handler uses long */ -/* jump). Therefore all cleanup must be done first. In general, */ +/* jump). Therefore all cleanup must be done first. In general, */ /* to achieve this status is accumulated and is only applied just */ /* before return by calling decContextSetStatus (via decStatus). */ /* */ @@ -127,9 +138,9 @@ /* */ /* 4. Exponent checking is minimized by allowing the exponent to */ /* grow outside its limits during calculations, provided that */ -/* the decFinalize function is called later. Multiplication and */ +/* the decFinalize function is called later. Multiplication and */ /* division, and intermediate calculations in exponentiation, */ -/* require more careful checks because of the risk of 31-bit */ +/* require more careful checks because of the risk of 31-bit */ /* overflow (the most negative valid exponent is -1999999997, for */ /* a 999999999-digit number with adjusted exponent of -999999999). */ /* */ @@ -151,18 +162,18 @@ /* is not useful for longer numbers because overflow of 32 bits */ /* would lead to 4 multiplies, which is almost as expensive as */ /* a divide (unless a floating-point or 64-bit multiply is */ -/* assumed to be available). */ +/* assumed to be available). */ /* */ -/* 8. Unusual abbreviations that may be used in the commentary: */ +/* 8. Unusual abbreviations that may be used in the commentary: */ /* lhs -- left hand side (operand, of an operation) */ -/* lsd -- least significant digit (of coefficient) */ +/* lsd -- least significant digit (of coefficient) */ /* lsu -- least significant Unit (of coefficient) */ /* msd -- most significant digit (of coefficient) */ /* msi -- most significant item (in an array) */ /* msu -- most significant Unit (of coefficient) */ /* rhs -- right hand side (operand, of an operation) */ -/* +ve -- positive */ -/* -ve -- negative */ +/* +ve -- positive */ +/* -ve -- negative */ /* ** -- raise to the power */ /* ------------------------------------------------------------------ */ @@ -178,25 +189,25 @@ /* Public lookup table used by the D2U macro */ const uByte d2utable[DECMAXD2U+1]=D2UTABLE; -#define DECVERB 1 /* set to 1 for verbose DECCHECK */ +#define DECVERB 1 /* set to 1 for verbose DECCHECK */ #define powers DECPOWERS /* old internal name */ /* Local constants */ #define DIVIDE 0x80 /* Divide operators */ #define REMAINDER 0x40 /* .. */ #define DIVIDEINT 0x20 /* .. */ -#define REMNEAR 0x10 /* .. */ -#define COMPARE 0x01 /* Compare operators */ -#define COMPMAX 0x02 /* .. */ -#define COMPMIN 0x03 /* .. */ +#define REMNEAR 0x10 /* .. */ +#define COMPARE 0x01 /* Compare operators */ +#define COMPMAX 0x02 /* .. */ +#define COMPMIN 0x03 /* .. */ #define COMPTOTAL 0x04 /* .. */ -#define COMPNAN 0x05 /* .. [NaN processing] */ -#define COMPSIG 0x06 /* .. [signaling COMPARE] */ +#define COMPNAN 0x05 /* .. [NaN processing] */ +#define COMPSIG 0x06 /* .. [signaling COMPARE] */ #define COMPMAXMAG 0x07 /* .. */ #define COMPMINMAG 0x08 /* .. */ -#define DEC_sNaN 0x40000000 /* local status: sNaN signal */ -#define BADINT (Int)0x80000000 /* most-negative Int; error indicator */ +#define DEC_sNaN 0x40000000 /* local status: sNaN signal */ +#define BADINT (Int)0x80000000 /* most-negative Int; error indicator */ /* Next two indicate an integer >= 10**6, and its parity (bottom bit) */ #define BIGEVEN (Int)0x80000002 #define BIGODD (Int)0x80000003 @@ -262,7 +273,7 @@ static Int decShiftToLeast(Unit *, Int, Int); static Int decShiftToMost(Unit *, Int, Int); static void decStatus(decNumber *, uInt, decContext *); static void decToString(const decNumber *, char[], Flag); -static decNumber * decTrim(decNumber *, decContext *, Flag, Int *); +static decNumber * decTrim(decNumber *, decContext *, Flag, Flag, Int *); static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int, Unit *, Int); static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int); @@ -302,7 +313,7 @@ uInt decAllocBytes=0; /* count of bytes allocated */ #if DECCHECK /* Optional checking routines. Enabling these means that decNumber */ /* and decContext operands to operator routines are checked for */ -/* correctness. This roughly doubles the execution time of the */ +/* correctness. This roughly doubles the execution time of the */ /* fastest routines (and adds 600+ bytes), so should not normally be */ /* used in 'production'. */ /* decCheckInexact is used to check that inexact results have a full */ @@ -382,7 +393,7 @@ Int decNumberToInt32(const decNumber *dn, decContext *set) { Int d; /* work */ const Unit *up; /* .. */ uInt hi=0, lo; /* .. */ - up=dn->lsu; /* -> lsu */ + up=dn->lsu; /* -> lsu */ lo=*up; /* get 1 to 9 digits */ #if DECDPUN>1 /* split to higher */ hi=lo/10; @@ -418,7 +429,7 @@ uInt decNumberToUInt32(const decNumber *dn, decContext *set) { Int d; /* work */ const Unit *up; /* .. */ uInt hi=0, lo; /* .. */ - up=dn->lsu; /* -> lsu */ + up=dn->lsu; /* -> lsu */ lo=*up; /* get 1 to 9 digits */ #if DECDPUN>1 /* split to higher */ hi=lo/10; @@ -437,7 +448,7 @@ uInt decNumberToUInt32(const decNumber *dn, decContext *set) { } /* decNumberToUInt32 */ /* ------------------------------------------------------------------ */ -/* to-scientific-string -- conversion to numeric string */ +/* to-scientific-string -- conversion to numeric string */ /* to-engineering-string -- conversion to numeric string */ /* */ /* decNumberToString(dn, string); */ @@ -464,30 +475,30 @@ char * decNumberToEngString(const decNumber *dn, char *string){ /* to-number -- conversion from numeric string */ /* */ /* decNumberFromString -- convert string to decNumber */ -/* dn -- the number structure to fill */ +/* dn -- the number structure to fill */ /* chars[] -- the string to convert ('\0' terminated) */ /* set -- the context used for processing any error, */ /* determining the maximum precision available */ /* (set.digits), determining the maximum and minimum */ /* exponent (set.emax and set.emin), determining if */ -/* extended values are allowed, and checking the */ +/* extended values are allowed, and checking the */ /* rounding mode if overflow occurs or rounding is */ /* needed. */ /* */ /* The length of the coefficient and the size of the exponent are */ /* checked by this routine, so the correct error (Underflow or */ -/* Overflow) can be reported or rounding applied, as necessary. */ +/* Overflow) can be reported or rounding applied, as necessary. */ /* */ /* If bad syntax is detected, the result will be a quiet NaN. */ /* ------------------------------------------------------------------ */ decNumber * decNumberFromString(decNumber *dn, const char chars[], decContext *set) { Int exponent=0; /* working exponent [assume 0] */ - uByte bits=0; /* working flags [assume +ve] */ + uByte bits=0; /* working flags [assume +ve] */ Unit *res; /* where result will be built */ Unit resbuff[SD2U(DECBUFFER+9)];/* local buffer in case need temporary */ /* [+9 allows for ln() constants] */ - Unit *allocres=NULL; /* -> allocated result, iff allocated */ + Unit *allocres=NULL; /* -> allocated result, iff allocated */ Int d=0; /* count of digits found in decimal part */ const char *dotchar=NULL; /* where dot was found */ const char *cfirst=chars; /* -> first character of decimal part */ @@ -507,7 +518,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], do { /* status & malloc protection */ for (c=chars;; c++) { /* -> input character */ - if (*c>='0' && *c<='9') { /* test for Arabic digit */ + if (*c>='0' && *c<='9') { /* test for Arabic digit */ last=c; d++; /* count of real digits */ continue; /* still in decimal part */ @@ -537,7 +548,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], if (!set->extended) break; /* hopeless */ #endif /* Infinities and NaNs are possible, here */ - if (dotchar!=NULL) break; /* .. unless had a dot */ + if (dotchar!=NULL) break; /* .. unless had a dot */ decNumberZero(dn); /* be optimistic */ if (decBiStr(c, "infinity", "INFINITY") || decBiStr(c, "inf", "INF")) { @@ -548,7 +559,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], /* a NaN expected */ /* 2003.09.10 NaNs are now permitted to have a sign */ dn->bits=bits | DECNAN; /* assume simple NaN */ - if (*c=='s' || *c=='S') { /* looks like an sNaN */ + if (*c=='s' || *c=='S') { /* looks like an sNaN */ c++; dn->bits=bits | DECSNAN; } @@ -578,7 +589,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], if (d>set->digits) break; } /* too many digits? */ /* good; drop through to convert the integer to coefficient */ - status=0; /* syntax is OK */ + status=0; /* syntax is OK */ bits=dn->bits; /* for copy-back */ } /* last==NULL */ @@ -613,14 +624,14 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], /* [up to 1999999999 is OK, for example 1E-1000000998] */ } if (nege) exponent=-exponent; /* was negative */ - status=0; /* is OK */ + status=0; /* is OK */ } /* stuff after digits */ /* Here when whole string has been inspected; syntax is good */ /* cfirst->first digit (never dot), last->last digit (ditto) */ /* strip leading zeros/dot [leave final 0 if all 0's] */ - if (*cfirst=='0') { /* [cfirst has stepped over .] */ + if (*cfirst=='0') { /* [cfirst has stepped over .] */ for (c=cfirst; c<last; c++, cfirst++) { if (*c=='.') continue; /* ignore dots */ if (*c!='0') break; /* non-zero found */ @@ -637,7 +648,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], /* Handle decimal point... */ if (dotchar!=NULL && dotchar<last) /* non-trailing '.' found? */ - exponent-=(last-dotchar); /* adjust exponent */ + exponent-=(last-dotchar); /* adjust exponent */ /* [we can now ignore the .] */ /* OK, the digits string is good. Assemble in the decNumber, or in */ @@ -703,7 +714,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], } } /* decNumberShow(dn); */ - } while(0); /* [for break] */ + } while(0); /* [for break] */ if (allocres!=NULL) free(allocres); /* drop any storage used */ if (status!=0) decStatus(dn, status, set); @@ -721,7 +732,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], /* */ /* res is C, the result. C may be A */ /* rhs is A */ -/* set is the context */ +/* set is the context */ /* */ /* See also decNumberCopyAbs for a quiet bitwise version of this. */ /* C must have space for set->digits digits. */ @@ -739,7 +750,7 @@ decNumber * decNumberAbs(decNumber *res, const decNumber *rhs, #endif decNumberZero(&dzero); /* set 0 */ - dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ + dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status); if (status!=0) decStatus(res, status, set); #if DECCHECK @@ -756,7 +767,7 @@ decNumber * decNumberAbs(decNumber *res, const decNumber *rhs, /* res is C, the result. C may be A and/or B (e.g., X=X+X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -851,7 +862,7 @@ decNumber * decNumberAnd(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for one digit (or NaN). */ /* ------------------------------------------------------------------ */ @@ -871,7 +882,7 @@ decNumber * decNumberCompare(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for one digit (or NaN). */ /* ------------------------------------------------------------------ */ @@ -891,10 +902,10 @@ decNumber * decNumberCompareSignal(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for one digit; the result will always be one of */ -/* -1, 0, or 1. */ +/* -1, 0, or 1. */ /* ------------------------------------------------------------------ */ decNumber * decNumberCompareTotal(decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set) { @@ -912,10 +923,10 @@ decNumber * decNumberCompareTotal(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for one digit; the result will always be one of */ -/* -1, 0, or 1. */ +/* -1, 0, or 1. */ /* ------------------------------------------------------------------ */ decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set) { @@ -944,7 +955,7 @@ decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs, a=allocbufa; /* use the allocated space */ } decNumberCopy(a, lhs); /* copy content */ - a->bits&=~DECNEG; /* .. and clear the sign */ + a->bits&=~DECNEG; /* .. and clear the sign */ lhs=a; /* use copy from here on */ } if (decNumberIsNegative(rhs)) { /* rhs<0 */ @@ -958,11 +969,11 @@ decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs, b=allocbufb; /* use the allocated space */ } decNumberCopy(b, rhs); /* copy content */ - b->bits&=~DECNEG; /* .. and clear the sign */ + b->bits&=~DECNEG; /* .. and clear the sign */ rhs=b; /* use copy from here on */ } decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status); - } while(0); /* end protected */ + } while(0); /* end protected */ if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */ if (allocbufb!=NULL) free(allocbufb); /* .. */ @@ -978,7 +989,7 @@ decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X/X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -994,14 +1005,14 @@ decNumber * decNumberDivide(decNumber *res, const decNumber *lhs, } /* decNumberDivide */ /* ------------------------------------------------------------------ */ -/* decNumberDivideInteger -- divide and return integer quotient */ +/* decNumberDivideInteger -- divide and return integer quotient */ /* */ /* This computes C = A # B, where # is the integer divide operator */ /* */ /* res is C, the result. C may be A and/or B (e.g., X=X#X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -1032,7 +1043,7 @@ decNumber * decNumberDivideInteger(decNumber *res, const decNumber *lhs, /* */ /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */ /* almost always be correctly rounded, but may be up to 1 ulp in */ -/* error in rare cases. */ +/* error in rare cases. */ /* ------------------------------------------------------------------ */ /* This is a wrapper for decExpOp which can handle the slightly wider */ /* (double) range needed by Ln (which has to be able to calculate */ @@ -1065,7 +1076,7 @@ decNumber * decNumberExp(decNumber *res, const decNumber *rhs, } #endif decExpOp(res, rhs, set, &status); - } while(0); /* end protected */ + } while(0); /* end protected */ #if DECSUBSET if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */ @@ -1087,7 +1098,7 @@ decNumber * decNumberExp(decNumber *res, const decNumber *rhs, /* lhs is A */ /* rhs is B */ /* fhs is C [far hand side] */ -/* set is the context */ +/* set is the context */ /* */ /* Mathematical function restrictions apply (see above); a NaN is */ /* returned with Invalid_operation if a restriction is violated. */ @@ -1146,7 +1157,7 @@ decNumber * decNumberFMA(decNumber *res, const decNumber *lhs, /* Note sNaN has to go through addOp to shorten payload if */ /* necessary */ if ((status&DEC_Invalid_operation)!=0) { - if (!(status&DEC_sNaN)) { /* but be true invalid */ + if (!(status&DEC_sNaN)) { /* but be true invalid */ decNumberZero(res); /* acc not yet set */ res->bits=DECNAN; break; @@ -1156,12 +1167,12 @@ decNumber * decNumberFMA(decNumber *res, const decNumber *lhs, } #if DECCHECK else { /* multiply was OK */ - if (status!=0) printf("Status=%08lx after FMA multiply\n", status); + if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status); } #endif /* add the third operand and result -> res, and all is done */ decAddOp(res, acc, fhs, set, 0, &status); - } while(0); /* end protected */ + } while(0); /* end protected */ if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */ if (status!=0) decStatus(res, status, set); @@ -1206,7 +1217,7 @@ decNumber * decNumberInvert(decNumber *res, const decNumber *rhs, msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */ for (; uc<=msuc; ua++, uc++) { /* Unit loop */ Unit a; /* extract unit */ - Int i, j; /* work */ + Int i, j; /* work */ if (ua>msua) a=0; else a=*ua; *uc=0; /* can now write back */ @@ -1252,7 +1263,7 @@ decNumber * decNumberInvert(decNumber *res, const decNumber *rhs, /* */ /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */ /* almost always be correctly rounded, but may be up to 1 ulp in */ -/* error in rare cases. */ +/* error in rare cases. */ /* ------------------------------------------------------------------ */ /* This is a wrapper for decLnOp which can handle the slightly wider */ /* (+11) range needed by Ln, Log10, etc. (which may have to be able */ @@ -1287,7 +1298,7 @@ decNumber * decNumberLn(decNumber *res, const decNumber *rhs, } /* extended=0 */ #endif decLnOp(res, rhs, set, &status); - } while(0); /* end protected */ + } while(0); /* end protected */ #if DECSUBSET if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */ @@ -1301,7 +1312,7 @@ decNumber * decNumberLn(decNumber *res, const decNumber *rhs, } /* decNumberLn */ /* ------------------------------------------------------------------ */ -/* decNumberLogB - get adjusted exponent, by 754r rules */ +/* decNumberLogB - get adjusted exponent, by 754 rules */ /* */ /* This computes C = adjustedexponent(A) */ /* */ @@ -1336,9 +1347,9 @@ decNumber * decNumberLogB(decNumber *res, const decNumber *rhs, if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status); else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs); else if (decNumberIsZero(rhs)) { - decNumberZero(res); /* prepare for Infinity */ + decNumberZero(res); /* prepare for Infinity */ res->bits=DECNEG|DECINF; /* -Infinity */ - status|=DEC_Division_by_zero; /* as per 754r */ + status|=DEC_Division_by_zero; /* as per 754 */ } else { /* finite non-zero */ Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */ @@ -1352,7 +1363,7 @@ decNumber * decNumberLogB(decNumber *res, const decNumber *rhs, /* ------------------------------------------------------------------ */ /* decNumberLog10 -- logarithm in base 10 */ /* */ -/* This computes C = log10(A) */ +/* This computes C = log10(A) */ /* */ /* res is C, the result. C may be A */ /* rhs is A */ @@ -1371,13 +1382,13 @@ decNumber * decNumberLogB(decNumber *res, const decNumber *rhs, /* */ /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */ /* almost always be correctly rounded, but may be up to 1 ulp in */ -/* error in rare cases. */ +/* error in rare cases. */ /* ------------------------------------------------------------------ */ /* This calculates ln(A)/ln(10) using appropriate precision. For */ /* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the */ /* requested digits and t is the number of digits in the exponent */ -/* (maximum 6). For ln(10) it is p + 3; this is often handled by the */ -/* fastpath in decLnOp. The final division is done to the requested */ +/* (maximum 6). For ln(10) it is p + 3; this is often handled by the */ +/* fastpath in decLnOp. The final division is done to the requested */ /* precision. */ /* ------------------------------------------------------------------ */ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs, @@ -1444,7 +1455,7 @@ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs, decNumberFromInt32(w, w->exponent); residue=0; decCopyFit(res, w, set, &residue, &status); /* copy & round */ - decFinish(res, set, &residue, &status); /* cleanup/set flags */ + decFinish(res, set, &residue, &status); /* cleanup/set flags */ break; } /* not a power of 10 */ } /* not a candidate for exact */ @@ -1501,7 +1512,7 @@ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs, aset.digits=set->digits; /* for final divide */ decDivideOp(res, a, b, &aset, DIVIDE, &status); /* into result */ - } while(0); /* [for break] */ + } while(0); /* [for break] */ if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */ if (allocbufb!=NULL) free(allocbufb); /* .. */ @@ -1519,12 +1530,12 @@ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs, /* ------------------------------------------------------------------ */ /* decNumberMax -- compare two Numbers and return the maximum */ /* */ -/* This computes C = A ? B, returning the maximum by 754R rules */ +/* This computes C = A ? B, returning the maximum by 754 rules */ /* */ /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -1542,12 +1553,12 @@ decNumber * decNumberMax(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ /* decNumberMaxMag -- compare and return the maximum by magnitude */ /* */ -/* This computes C = A ? B, returning the maximum by 754R rules */ +/* This computes C = A ? B, returning the maximum by 754 rules */ /* */ /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -1565,12 +1576,12 @@ decNumber * decNumberMaxMag(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ /* decNumberMin -- compare two Numbers and return the minimum */ /* */ -/* This computes C = A ? B, returning the minimum by 754R rules */ +/* This computes C = A ? B, returning the minimum by 754 rules */ /* */ /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -1588,12 +1599,12 @@ decNumber * decNumberMin(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ /* decNumberMinMag -- compare and return the minimum by magnitude */ /* */ -/* This computes C = A ? B, returning the minimum by 754R rules */ +/* This computes C = A ? B, returning the minimum by 754 rules */ /* */ /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -1615,7 +1626,7 @@ decNumber * decNumberMinMag(decNumber *res, const decNumber *lhs, /* */ /* res is C, the result. C may be A */ /* rhs is A */ -/* set is the context */ +/* set is the context */ /* */ /* See also decNumberCopyNegate for a quiet bitwise version of this. */ /* C must have space for set->digits digits. */ @@ -1632,7 +1643,7 @@ decNumber * decNumberMinus(decNumber *res, const decNumber *rhs, #endif decNumberZero(&dzero); /* make 0 */ - dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ + dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ decAddOp(res, &dzero, rhs, set, DECNEG, &status); if (status!=0) decStatus(res, status, set); #if DECCHECK @@ -1642,15 +1653,15 @@ decNumber * decNumberMinus(decNumber *res, const decNumber *rhs, } /* decNumberMinus */ /* ------------------------------------------------------------------ */ -/* decNumberNextMinus -- next towards -Infinity */ +/* decNumberNextMinus -- next towards -Infinity */ /* */ /* This computes C = A - infinitesimal, rounded towards -Infinity */ /* */ /* res is C, the result. C may be A */ /* rhs is A */ -/* set is the context */ +/* set is the context */ /* */ -/* This is a generalization of 754r NextDown. */ +/* This is a generalization of 754 NextDown. */ /* ------------------------------------------------------------------ */ decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs, decContext *set) { @@ -1684,9 +1695,9 @@ decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs, /* */ /* res is C, the result. C may be A */ /* rhs is A */ -/* set is the context */ +/* set is the context */ /* */ -/* This is a generalization of 754r NextUp. */ +/* This is a generalization of 754 NextUp. */ /* ------------------------------------------------------------------ */ decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs, decContext *set) { @@ -1718,14 +1729,15 @@ decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs, /* decNumberNextToward -- next towards rhs */ /* */ /* This computes C = A +/- infinitesimal, rounded towards */ -/* +/-Infinity in the direction of B, as per 754r nextafter rules */ +/* +/-Infinity in the direction of B, as per 754-1985 nextafter */ +/* modified during revision but dropped from 754-2008. */ /* */ /* res is C, the result. C may be A or B. */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ -/* This is a generalization of 754r NextAfter. */ +/* This is a generalization of 754-1985 NextAfter. */ /* ------------------------------------------------------------------ */ decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set) { @@ -1747,27 +1759,27 @@ decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs, if (result==0) decNumberCopySign(res, lhs, rhs); /* easy */ else { /* differ: need NextPlus or NextMinus */ uByte sub; /* add or subtract */ - if (result<0) { /* lhs<rhs, do nextplus */ + if (result<0) { /* lhs<rhs, do nextplus */ /* -Infinity is the special case */ if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) { decSetMaxValue(res, set); res->bits=DECNEG; /* negative */ - return res; /* there is no status to set */ + return res; /* there is no status to set */ } workset.round=DEC_ROUND_CEILING; sub=0; /* add, please */ } /* plus */ - else { /* lhs>rhs, do nextminus */ + else { /* lhs>rhs, do nextminus */ /* +Infinity is the special case */ if ((lhs->bits&(DECINF|DECNEG))==DECINF) { decSetMaxValue(res, set); - return res; /* there is no status to set */ + return res; /* there is no status to set */ } workset.round=DEC_ROUND_FLOOR; sub=DECNEG; /* subtract, please */ } /* minus */ decNumberZero(&dtiny); /* start with 0 */ - dtiny.lsu[0]=1; /* make number that is .. */ + dtiny.lsu[0]=1; /* make number that is .. */ dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */ decAddOp(res, lhs, &dtiny, &workset, sub, &status); /* + or - */ /* turn off exceptions if the result is a normal number */ @@ -1856,7 +1868,7 @@ decNumber * decNumberOr(decNumber *res, const decNumber *lhs, /* */ /* res is C, the result. C may be A */ /* rhs is A */ -/* set is the context */ +/* set is the context */ /* */ /* See also decNumberCopy for a quiet bitwise version of this. */ /* C must have space for set->digits digits. */ @@ -1874,7 +1886,7 @@ decNumber * decNumberPlus(decNumber *res, const decNumber *rhs, #endif decNumberZero(&dzero); /* make 0 */ - dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ + dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ decAddOp(res, &dzero, rhs, set, 0, &status); if (status!=0) decStatus(res, status, set); #if DECCHECK @@ -1891,7 +1903,7 @@ decNumber * decNumberPlus(decNumber *res, const decNumber *rhs, /* res is C, the result. C may be A and/or B (e.g., X=X+X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -1914,7 +1926,7 @@ decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X**X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* */ @@ -1930,7 +1942,7 @@ decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs, /* */ /* The final result is rounded according to the context; it will */ /* almost always be correctly rounded, but may be up to 1 ulp in */ -/* error in rare cases. */ +/* error in rare cases. */ /* ------------------------------------------------------------------ */ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set) { @@ -1953,7 +1965,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, Flag seenbit; /* seen a bit while powering */ Int residue=0; /* rounding residue */ uInt status=0; /* accumulators */ - uByte bits=0; /* result sign if errors */ + uByte bits=0; /* result sign if errors */ decContext aset; /* working context */ decNumber dnOne; /* work value 1... */ /* local accumulator buffer [a decNumber, with digits+elength+1 digits] */ @@ -1993,7 +2005,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, if (decNumberIsNegative(lhs) /* lhs<0 */ && !decNumberIsZero(lhs)) /* .. */ status|=DEC_Invalid_operation; - else { /* lhs >=0 */ + else { /* lhs >=0 */ decNumberZero(&dnOne); /* set up 1 */ dnOne.lsu[0]=1; decNumberCompare(dac, lhs, &dnOne, set); /* lhs ? 1 */ @@ -2020,14 +2032,14 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, /* Original rhs may be an integer that fits and is in range */ n=decGetInt(rhs); if (n!=BADINT) { /* it is an integer */ - rhsint=1; /* record the fact for 1**n */ + rhsint=1; /* record the fact for 1**n */ isoddint=(Flag)n&1; /* [works even if big] */ if (n!=BIGEVEN && n!=BIGODD) /* can use integer path? */ useint=1; /* looks good */ } if (decNumberIsNegative(lhs) /* -x .. */ - && isoddint) bits=DECNEG; /* .. to an odd power */ + && isoddint) bits=DECNEG; /* .. to an odd power */ /* handle LHS infinity */ if (decNumberIsInfinite(lhs)) { /* [NaNs already handled] */ @@ -2060,7 +2072,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, uByte rbits=rhs->bits; /* save */ if (rbits & DECNEG) { /* was a 0**(-n) */ #if DECSUBSET - if (!set->extended) { /* [bad if subset] */ + if (!set->extended) { /* [bad if subset] */ status|=DEC_Invalid_operation; break;} #endif @@ -2089,7 +2101,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, aset.clamp=0; /* and no concrete format */ /* calculate the result using exp(ln(lhs)*rhs), which can */ - /* all be done into the accumulator, dac. The precision needed */ + /* all be done into the accumulator, dac. The precision needed */ /* is enough to contain the full information in the lhs (which */ /* is the total digits, including exponent), or the requested */ /* precision, if larger, + 4; 6 is used for the exponent */ @@ -2146,7 +2158,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, if (!rhsint) { /* add padding */ Int shift=set->digits-1; dac->digits=decShiftToMost(dac->lsu, 1, shift); - dac->exponent=-shift; /* make 1.0000... */ + dac->exponent=-shift; /* make 1.0000... */ status|=DEC_Inexact|DEC_Rounded; /* deemed inexact */ } } @@ -2164,7 +2176,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, /* if a negative power the constant 1 is needed, and if not subset */ /* invert the lhs now rather than inverting the result later */ if (decNumberIsNegative(rhs)) { /* was a **-n [hence digits>0] */ - decNumber *inv=invbuff; /* asssume use fixed buffer */ + decNumber *inv=invbuff; /* asssume use fixed buffer */ decNumberCopy(&dnOne, dac); /* dnOne=1; [needed now or later] */ #if DECSUBSET if (set->extended) { /* need to calculate 1/lhs */ @@ -2197,13 +2209,13 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, } /* [the following two lines revealed an optimizer bug in a C++ */ /* compiler, with symptom: 5**3 -> 25, when n=n+n was used] */ - n=n<<1; /* move next bit to testable position */ + n=n<<1; /* move next bit to testable position */ if (n<0) { /* top bit is set */ seenbit=1; /* OK, significant bit seen */ decMultiplyOp(dac, dac, lhs, &aset, &status); /* dac=dac*x */ } if (i==31) break; /* that was the last bit */ - if (!seenbit) continue; /* no need to square 1 */ + if (!seenbit) continue; /* no need to square 1 */ decMultiplyOp(dac, dac, dac, &aset, &status); /* dac=dac*dac [square] */ } /*i*/ /* 32 bits */ @@ -2242,9 +2254,9 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, decCopyFit(res, dac, set, &residue, &status); decFinish(res, set, &residue, &status); /* final cleanup */ #if DECSUBSET - if (!set->extended) decTrim(res, set, 0, &dropped); /* trailing zeros */ + if (!set->extended) decTrim(res, set, 0, 1, &dropped); /* trailing zeros */ #endif - } while(0); /* end protected */ + } while(0); /* end protected */ if (allocdac!=NULL) free(allocdac); /* drop any storage used */ if (allocinv!=NULL) free(allocinv); /* .. */ @@ -2270,7 +2282,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A or B */ /* lhs is A, the number to adjust */ /* rhs is B, the number with exponent to match */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* */ @@ -2288,11 +2300,11 @@ decNumber * decNumberQuantize(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ /* decNumberReduce -- remove trailing zeros */ /* */ -/* This computes C = 0 + A, and normalizes the result */ +/* This computes C = 0 + A, and normalizes the result */ /* */ /* res is C, the result. C may be A */ /* rhs is A */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -2309,7 +2321,7 @@ decNumber * decNumberReduce(decNumber *res, const decNumber *rhs, #endif uInt status=0; /* as usual */ Int residue=0; /* as usual */ - Int dropped; /* work */ + Int dropped; /* work */ #if DECCHECK if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; @@ -2337,8 +2349,9 @@ decNumber * decNumberReduce(decNumber *res, const decNumber *rhs, /* reduce result to the requested length and copy to result */ decCopyFit(res, rhs, set, &residue, &status); /* copy & round */ decFinish(res, set, &residue, &status); /* cleanup/set flags */ - decTrim(res, set, 1, &dropped); /* normalize in place */ - } while(0); /* end protected */ + decTrim(res, set, 1, 0, &dropped); /* normalize in place */ + /* [may clamp] */ + } while(0); /* end protected */ #if DECSUBSET if (allocrhs !=NULL) free(allocrhs); /* .. */ @@ -2358,7 +2371,7 @@ decNumber * decNumberReduce(decNumber *res, const decNumber *rhs, /* res is C, the result. C may be A or B */ /* lhs is A, the number to adjust */ /* rhs is B, the requested exponent */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* */ @@ -2381,7 +2394,7 @@ decNumber * decNumberRescale(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X%X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -2404,7 +2417,7 @@ decNumber * decNumberRemainder(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X%X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -2425,15 +2438,15 @@ decNumber * decNumberRemainderNear(decNumber *res, const decNumber *lhs, /* This computes C = A rot B (in base ten and rotating set->digits */ /* digits). */ /* */ -/* res is C, the result. C may be A and/or B (e.g., X=XrotX) */ +/* res is C, the result. C may be A and/or B (e.g., X=XrotX) */ /* lhs is A */ /* rhs is B, the number of digits to rotate (-ve to right) */ -/* set is the context */ +/* set is the context */ /* */ /* The digits of the coefficient of A are rotated to the left (if B */ /* is positive) or to the right (if B is negative) without adjusting */ /* the exponent or the sign of A. If lhs->digits is less than */ -/* set->digits the coefficient is padded with zeros on the left */ +/* set->digits the coefficient is padded with zeros on the left */ /* before the rotate. Any leading zeros in the result are removed */ /* as usual. */ /* */ @@ -2473,10 +2486,10 @@ decNumber * decNumberRotate(decNumber *res, const decNumber *lhs, && !decNumberIsInfinite(res)) { /* lhs was infinite */ /* left-rotate to do; 0 < rotate < set->digits */ uInt units, shift; /* work */ - uInt msudigits; /* digits in result msu */ + uInt msudigits; /* digits in result msu */ Unit *msu=res->lsu+D2U(res->digits)-1; /* current msu */ Unit *msumax=res->lsu+D2U(set->digits)-1; /* rotation msu */ - for (msu++; msu<=msumax; msu++) *msu=0; /* ensure high units=0 */ + for (msu++; msu<=msumax; msu++) *msu=0; /* ensure high units=0 */ res->digits=set->digits; /* now full-length */ msudigits=MSUDIGITS(res->digits); /* actual digits in msu */ @@ -2544,7 +2557,7 @@ decNumber * decNumberRotate(decNumber *res, const decNumber *lhs, /* (reversing is easy and fast) */ decReverse(res->lsu+units, msumax); /* left part */ decReverse(res->lsu, res->lsu+units-1); /* right part */ - decReverse(res->lsu, msumax); /* whole */ + decReverse(res->lsu, msumax); /* whole */ } /* whole units to rotate */ /* the rotation may have left an undetermined number of zeros */ /* on the left, so true length needs to be calculated */ @@ -2559,7 +2572,7 @@ decNumber * decNumberRotate(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ /* decNumberSameQuantum -- test for equal exponents */ /* */ -/* res is the result number, which will contain either 0 or 1 */ +/* res is the result number, which will contain either 0 or 1 */ /* lhs is a number to test */ /* rhs is the second (usually a pattern) */ /* */ @@ -2586,15 +2599,15 @@ decNumber * decNumberSameQuantum(decNumber *res, const decNumber *lhs, } /* decNumberSameQuantum */ /* ------------------------------------------------------------------ */ -/* decNumberScaleB -- multiply by a power of 10 */ +/* decNumberScaleB -- multiply by a power of 10 */ /* */ -/* This computes C = A x 10**B where B is an integer (q=0) with */ +/* This computes C = A x 10**B where B is an integer (q=0) with */ /* maximum magnitude 2*(emax+digits) */ /* */ /* res is C, the result. C may be A or B */ /* lhs is A, the number to adjust */ /* rhs is B, the requested power of ten to use */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* */ @@ -2604,7 +2617,7 @@ decNumber * decNumberScaleB(decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set) { Int reqexp; /* requested exponent change [B] */ uInt status=0; /* accumulator */ - Int residue; /* work */ + Int residue; /* work */ #if DECCHECK if (decCheckOperands(res, lhs, rhs, set)) return res; @@ -2644,7 +2657,7 @@ decNumber * decNumberScaleB(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X<<X) */ /* lhs is A */ /* rhs is B, the number of digits to shift (-ve to right) */ -/* set is the context */ +/* set is the context */ /* */ /* The digits of the coefficient of A are shifted to the left (if B */ /* is positive) or to the right (if B is negative) without adjusting */ @@ -2675,8 +2688,8 @@ decNumber * decNumberShift(decNumber *res, const decNumber *lhs, else { /* both numeric, rhs is an integer */ shift=decGetInt(rhs); /* [cannot fail] */ if (shift==BADINT /* something bad .. */ - || shift==BIGODD || shift==BIGEVEN /* .. very big .. */ - || abs(shift)>set->digits) /* .. or out of range */ + || shift==BIGODD || shift==BIGEVEN /* .. very big .. */ + || abs(shift)>set->digits) /* .. or out of range */ status=DEC_Invalid_operation; else { /* rhs is OK */ decNumberCopy(res, lhs); @@ -2744,27 +2757,27 @@ decNumber * decNumberShift(decNumber *res, const decNumber *lhs, /* if x < 0 then */ /* assert false */ /* else */ -/* result 0 */ +/* result 0 */ /* end if */ /* end if */ -/* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */ +/* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */ /* var e := getexp(x) % exponent part of x */ /* var approx : real */ -/* if e mod 2 = 0 then */ +/* if e mod 2 = 0 then */ /* approx := .259 + .819 * f % approx to root of f */ -/* else */ +/* else */ /* f := f/l0 % adjustments */ -/* e := e + 1 % for odd */ -/* approx := .0819 + 2.59 * f % exponent */ +/* e := e + 1 % for odd */ +/* approx := .0819 + 2.59 * f % exponent */ /* end if */ /* */ /* var p:= 3 */ /* const maxp := currentprecision + 2 */ -/* loop */ +/* loop */ /* p := min(2*p - 2, maxp) % p = 4,6,10, . . . , maxp */ /* precision p */ -/* approx := .5 * (approx + f/approx) */ -/* exit when p = maxp */ +/* approx := .5 * (approx + f/approx) */ +/* exit when p = maxp */ /* end loop */ /* */ /* % approx is now within 1 ulp of the properly rounded square root */ @@ -2794,11 +2807,11 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, Int workp; /* working precision */ Int residue=0; /* rounding residue */ uInt status=0, ignore=0; /* status accumulators */ - uInt rstatus; /* .. */ + uInt rstatus; /* .. */ Int exp; /* working exponent */ Int ideal; /* ideal (preferred) exponent */ Int needbytes; /* work */ - Int dropped; /* .. */ + Int dropped; /* .. */ #if DECSUBSET decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */ @@ -2849,9 +2862,9 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, } /* calculate the ideal (preferred) exponent [floor(exp/2)] */ - /* [We would like to write: ideal=rhs->exponent>>1, but this */ + /* [It would be nicer to write: ideal=rhs->exponent>>1, but this */ /* generates a compiler warning. Generated code is the same.] */ - ideal=(rhs->exponent&~1)/2; /* target */ + ideal=(rhs->exponent&~1)/2; /* target */ /* handle zeros */ if (ISZERO(rhs)) { @@ -2876,6 +2889,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, /* b -- intermediate temporary result (same size as a) */ /* if any is too long for local storage, then allocate */ workp=MAXI(set->digits+1, rhs->digits); /* actual rounding precision */ + workp=MAXI(workp, 7); /* at least 7 for low cases */ maxp=workp+2; /* largest working precision */ needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit); @@ -2891,7 +2905,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, if (needbytes>(Int)sizeof(bufa)) { /* [same applies to b] */ allocbufa=(decNumber *)malloc(needbytes); allocbufb=(decNumber *)malloc(needbytes); - if (allocbufa==NULL || allocbufb==NULL) { /* hopeless */ + if (allocbufa==NULL || allocbufb==NULL) { /* hopeless */ status|=DEC_Insufficient_storage; break;} a=allocbufa; /* use the allocated spaces */ @@ -2905,6 +2919,8 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, /* set up working context */ decContextDefault(&workset, DEC_INIT_DECIMAL64); + workset.emax=DEC_MAX_EMAX; + workset.emin=DEC_MIN_EMIN; /* [Until further notice, no error is possible and status bits */ /* (Rounded, etc.) should be ignored, not accumulated.] */ @@ -2913,7 +2929,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, workset.digits=workp; /* p for initial calculation */ t->bits=0; t->digits=3; a->bits=0; a->digits=3; - if ((exp & 1)==0) { /* even exponent */ + if ((exp & 1)==0) { /* even exponent */ /* Set t=0.259, a=0.819 */ t->exponent=-3; a->exponent=-3; @@ -2945,6 +2961,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2; #endif } + decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */ decAddOp(a, a, t, &workset, 0, &ignore); /* ..+t */ /* [a is now the initial approximation for sqrt(f), calculated with */ @@ -2956,16 +2973,14 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, t->lsu[0]=5; /* .. */ t->exponent=-1; /* .. */ workset.digits=3; /* initial p */ - for (;;) { + for (; workset.digits<maxp;) { /* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */ - workset.digits=workset.digits*2-2; - if (workset.digits>maxp) workset.digits=maxp; + workset.digits=MINI(workset.digits*2-2, maxp); /* a = 0.5 * (a + f/a) */ /* [calculated at p then rounded to currentprecision] */ decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a */ - decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */ - decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */ - if (a->digits==maxp) break; /* have required digits */ + decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */ + decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */ } /* loop */ /* Here, 0.1 <= a < 1 [Hull], and a has maxp digits */ @@ -2974,8 +2989,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, /* correctly */ approxset=*set; /* get emin, emax, etc. */ approxset.round=DEC_ROUND_HALF_EVEN; - a->exponent+=exp/2; /* set correct exponent */ - + a->exponent+=exp/2; /* set correct exponent */ rstatus=0; /* clear status */ residue=0; /* .. and accumulator */ decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */ @@ -2993,7 +3007,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, status|=(rstatus & ~(DEC_Rounded|DEC_Inexact)); /* Carry out the Hull correction */ - a->exponent-=exp/2; /* back to 0.1->1 */ + a->exponent-=exp/2; /* back to 0.1->1 */ /* a is now at final precision and within 1 ulp of the properly */ /* rounded square root of f; to ensure proper rounding, compare */ @@ -3035,18 +3049,18 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, /* estimation are irrelevant, so status was not accumulated] */ /* Here, 0.1 <= a < 1 (still), so adjust back */ - a->exponent+=exp/2; /* set correct exponent */ + a->exponent+=exp/2; /* set correct exponent */ /* count droppable zeros [after any subnormal rounding] by */ /* trimming a copy */ decNumberCopy(b, a); - decTrim(b, set, 1, &dropped); /* [drops trailing zeros] */ + decTrim(b, set, 1, 1, &dropped); /* [drops trailing zeros] */ - /* Set Inexact and Rounded. The answer can only be exact if */ - /* it is short enough so that squaring it could fit in workp digits, */ - /* and it cannot have trailing zeros due to clamping, so these are */ - /* the only (relatively rare) conditions a careful check is needed */ - if (b->digits*2-1 > workp && !set->clamp) { /* cannot fit */ + /* Set Inexact and Rounded. The answer can only be exact if */ + /* it is short enough so that squaring it could fit in workp */ + /* digits, so this is the only (relatively rare) condition that */ + /* a careful check is needed */ + if (b->digits*2-1 > workp) { /* cannot fit */ status|=DEC_Inexact|DEC_Rounded; } else { /* could be exact/unrounded */ @@ -3058,12 +3072,19 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, else { /* plausible */ decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); /* b ? rhs */ if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; /* not equal */ - else { /* is Exact */ + else { /* is Exact */ /* here, dropped is the count of trailing zeros in 'a' */ /* use closest exponent to ideal... */ - Int todrop=ideal-a->exponent; /* most that can be dropped */ + Int todrop=ideal-a->exponent; /* most that can be dropped */ if (todrop<0) status|=DEC_Rounded; /* ideally would add 0s */ else { /* unrounded */ + /* there are some to drop, but emax may not allow all */ + Int maxexp=set->emax-set->digits+1; + Int maxdrop=maxexp-a->exponent; + if (todrop>maxdrop && set->clamp) { /* apply clamping */ + todrop=maxdrop; + status|=DEC_Clamped; + } if (dropped<todrop) { /* clamp to those available */ todrop=dropped; status|=DEC_Clamped; @@ -3093,11 +3114,11 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, } decNumberCopy(res, a); /* a is now the result */ - } while(0); /* end protected */ + } while(0); /* end protected */ - if (allocbuff!=NULL) free(allocbuff); /* drop any storage used */ - if (allocbufa!=NULL) free(allocbufa); /* .. */ - if (allocbufb!=NULL) free(allocbufb); /* .. */ + if (allocbuff!=NULL) free(allocbuff); /* drop any storage used */ + if (allocbufa!=NULL) free(allocbufa); /* .. */ + if (allocbufb!=NULL) free(allocbufb); /* .. */ #if DECSUBSET if (allocrhs !=NULL) free(allocrhs); /* .. */ #endif @@ -3116,7 +3137,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs, /* res is C, the result. C may be A and/or B (e.g., X=X-X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* */ /* C must have space for set->digits digits. */ /* ------------------------------------------------------------------ */ @@ -3138,7 +3159,7 @@ decNumber * decNumberSubtract(decNumber *res, const decNumber *lhs, /* */ /* res is the result */ /* rhs is input number */ -/* set is the context */ +/* set is the context */ /* */ /* res must have space for any value of rhs. */ /* */ @@ -3173,9 +3194,9 @@ decNumber * decNumberToIntegralExact(decNumber *res, const decNumber *rhs, if (rhs->exponent>=0) return decNumberCopy(res, rhs); /* that was easy, but if negative exponent there is work to do... */ workset=*set; /* clone rounding, etc. */ - workset.digits=rhs->digits; /* no length rounding */ + workset.digits=rhs->digits; /* no length rounding */ workset.traps=0; /* no traps */ - decNumberZero(&dn); /* make a number with exponent 0 */ + decNumberZero(&dn); /* make a number with exponent 0 */ decNumberQuantize(res, rhs, &dn, &workset); status|=workset.status; } @@ -3269,9 +3290,9 @@ decNumber * decNumberXor(decNumber *res, const decNumber *lhs, /* ================================================================== */ /* ------------------------------------------------------------------ */ -/* decNumberClass -- return the decClass of a decNumber */ +/* decNumberClass -- return the decClass of a decNumber */ /* dn -- the decNumber to test */ -/* set -- the context to use for Emin */ +/* set -- the context to use for Emin */ /* returns the decClass enum */ /* ------------------------------------------------------------------ */ enum decClass decNumberClass(const decNumber *dn, decContext *set) { @@ -3347,7 +3368,7 @@ decNumber * decNumberCopy(decNumber *dest, const decNumber *src) { const Unit *smsup, *s; /* work */ Unit *d; /* .. */ /* memcpy for the remaining Units would be safe as they cannot */ - /* overlap. However, this explicit loop is faster in short cases. */ + /* overlap. However, this explicit loop is faster in short cases. */ d=dest->lsu+1; /* -> first destination */ smsup=src->lsu+D2U(src->digits); /* -> source msu+1 */ for (s=src->lsu+1; s<smsup; s++, d++) *d=*s; @@ -3400,7 +3421,7 @@ decNumber * decNumberCopyNegate(decNumber *res, const decNumber *rhs) { /* ------------------------------------------------------------------ */ /* decNumberCopySign -- quiet copy and set sign operator */ /* */ -/* This sets C = A with the sign of B */ +/* This sets C = A with the sign of B */ /* */ /* res is C, the result. C may be A */ /* lhs is A */ @@ -3424,7 +3445,7 @@ decNumber * decNumberCopySign(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ /* decNumberGetBCD -- get the coefficient in BCD8 */ -/* dn is the source decNumber */ +/* dn is the source decNumber */ /* bcd is the uInt array that will receive dn->digits BCD bytes, */ /* most-significant at offset 0 */ /* returns bcd */ @@ -3432,14 +3453,14 @@ decNumber * decNumberCopySign(decNumber *res, const decNumber *lhs, /* bcd must have at least dn->digits bytes. No error is possible; if */ /* dn is a NaN or Infinite, digits must be 1 and the coefficient 0. */ /* ------------------------------------------------------------------ */ -uByte * decNumberGetBCD(const decNumber *dn, uint8_t *bcd) { +uByte * decNumberGetBCD(const decNumber *dn, uByte *bcd) { uByte *ub=bcd+dn->digits-1; /* -> lsd */ const Unit *up=dn->lsu; /* Unit pointer, -> lsu */ #if DECDPUN==1 /* trivial simple copy */ for (; ub>=bcd; ub--, up++) *ub=*up; - #else /* chopping needed */ - uInt u=*up; /* work */ + #else /* chopping needed */ + uInt u=*up; /* work */ uInt cut=DECDPUN; /* downcounter through unit */ for (; ub>=bcd; ub--) { *ub=(uByte)(u%10); /* [*6554 trick inhibits, here] */ @@ -3456,11 +3477,11 @@ uByte * decNumberGetBCD(const decNumber *dn, uint8_t *bcd) { /* ------------------------------------------------------------------ */ /* decNumberSetBCD -- set (replace) the coefficient from BCD8 */ -/* dn is the target decNumber */ +/* dn is the target decNumber */ /* bcd is the uInt array that will source n BCD bytes, most- */ /* significant at offset 0 */ /* n is the number of digits in the source BCD array (bcd) */ -/* returns dn */ +/* returns dn */ /* */ /* dn must have space for at least n digits. No error is possible; */ /* if dn is a NaN, or Infinite, or is to become a zero, n must be 1 */ @@ -3472,7 +3493,7 @@ decNumber * decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) { #if DECDPUN==1 /* trivial simple copy */ for (; ub<bcd+n; ub++, up--) *up=*ub; - #else /* some assembly needed */ + #else /* some assembly needed */ /* calculate how many digits in msu, and hence first cut */ Int cut=MSUDIGITS(n); /* [faster than remainder] */ for (;up>=dn->lsu; up--) { /* each Unit from msu */ @@ -3481,14 +3502,14 @@ decNumber * decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) { cut=DECDPUN; /* next Unit has all digits */ } #endif - dn->digits=n; /* set digit count */ + dn->digits=n; /* set digit count */ return dn; } /* decNumberSetBCD */ /* ------------------------------------------------------------------ */ /* decNumberIsNormal -- test normality of a decNumber */ /* dn is the decNumber to test */ -/* set is the context to use for Emin */ +/* set is the context to use for Emin */ /* returns 1 if |dn| is finite and >=Nmin, 0 otherwise */ /* ------------------------------------------------------------------ */ Int decNumberIsNormal(const decNumber *dn, decContext *set) { @@ -3500,7 +3521,7 @@ Int decNumberIsNormal(const decNumber *dn, decContext *set) { if (decNumberIsSpecial(dn)) return 0; /* not finite */ if (decNumberIsZero(dn)) return 0; /* not non-zero */ - ae=dn->exponent+dn->digits-1; /* adjusted exponent */ + ae=dn->exponent+dn->digits-1; /* adjusted exponent */ if (ae<set->emin) return 0; /* is subnormal */ return 1; } /* decNumberIsNormal */ @@ -3508,7 +3529,7 @@ Int decNumberIsNormal(const decNumber *dn, decContext *set) { /* ------------------------------------------------------------------ */ /* decNumberIsSubnormal -- test subnormality of a decNumber */ /* dn is the decNumber to test */ -/* set is the context to use for Emin */ +/* set is the context to use for Emin */ /* returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise */ /* ------------------------------------------------------------------ */ Int decNumberIsSubnormal(const decNumber *dn, decContext *set) { @@ -3520,7 +3541,7 @@ Int decNumberIsSubnormal(const decNumber *dn, decContext *set) { if (decNumberIsSpecial(dn)) return 0; /* not finite */ if (decNumberIsZero(dn)) return 0; /* not non-zero */ - ae=dn->exponent+dn->digits-1; /* adjusted exponent */ + ae=dn->exponent+dn->digits-1; /* adjusted exponent */ if (ae<set->emin) return 1; /* is subnormal */ return 0; } /* decNumberIsSubnormal */ @@ -3529,19 +3550,20 @@ Int decNumberIsSubnormal(const decNumber *dn, decContext *set) { /* decNumberTrim -- remove insignificant zeros */ /* */ /* dn is the number to trim */ -/* returns dn */ +/* returns dn */ /* */ /* All fields are updated as required. This is a utility operation, */ -/* so special values are unchanged and no error is possible. */ +/* so special values are unchanged and no error is possible. The */ +/* zeros are removed unconditionally. */ /* ------------------------------------------------------------------ */ decNumber * decNumberTrim(decNumber *dn) { - Int dropped; /* work */ + Int dropped; /* work */ decContext set; /* .. */ #if DECCHECK if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn; #endif decContextDefault(&set, DEC_INIT_BASE); /* clamp=0 */ - return decTrim(dn, &set, 0, &dropped); + return decTrim(dn, &set, 0, 1, &dropped); } /* decNumberTrim */ /* ------------------------------------------------------------------ */ @@ -3557,7 +3579,7 @@ const char * decNumberVersion(void) { /* decNumberZero -- set a number to 0 */ /* */ /* dn is the number to set, with space for one digit */ -/* returns dn */ +/* returns dn */ /* */ /* No error is possible. */ /* ------------------------------------------------------------------ */ @@ -3582,7 +3604,7 @@ decNumber * decNumberZero(decNumber *dn) { /* ------------------------------------------------------------------ */ /* decToString -- lay out a number into a string */ /* */ -/* dn is the number to lay out */ +/* dn is the number to lay out */ /* string is where to lay out the number */ /* eng is 1 if Engineering, 0 if Scientific */ /* */ @@ -3596,7 +3618,7 @@ decNumber * decNumberZero(decNumber *dn) { /* If DECCHECK is enabled the string "?" is returned if a number is */ /* invalid. */ static void decToString(const decNumber *dn, char *string, Flag eng) { - Int exp=dn->exponent; /* local copy */ + Int exp=dn->exponent; /* local copy */ Int e; /* E-part value */ Int pre; /* digits before the '.' */ Int cut; /* for counting digits in a Unit */ @@ -3616,7 +3638,7 @@ static void decToString(const decNumber *dn, char *string, Flag eng) { } if (dn->bits&DECSPECIAL) { /* Is a special value */ if (decNumberIsInfinite(dn)) { - strcpy(c, "Inf"); + strcpy(c, "Inf"); strcpy(c+3, "inity"); return;} /* a NaN */ @@ -3636,7 +3658,7 @@ static void decToString(const decNumber *dn, char *string, Flag eng) { cut=MSUDIGITS(dn->digits); /* [faster than remainder] */ cut--; /* power of ten for digit */ - if (exp==0) { /* simple integer [common fastpath] */ + if (exp==0) { /* simple integer [common fastpath] */ for (;up>=dn->lsu; up--) { /* each Unit from msu */ u=*up; /* contains DECDPUN digits to lay out */ for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow); @@ -3649,7 +3671,7 @@ static void decToString(const decNumber *dn, char *string, Flag eng) { pre=dn->digits+exp; /* digits before '.' */ e=0; /* no E */ if ((exp>0) || (pre<-5)) { /* need exponential form */ - e=exp+dn->digits-1; /* calculate E value */ + e=exp+dn->digits-1; /* calculate E value */ pre=1; /* assume one digit before '.' */ if (eng && (e!=0)) { /* engineering: may need to adjust */ Int adj; /* adjustment */ @@ -3682,14 +3704,14 @@ static void decToString(const decNumber *dn, char *string, Flag eng) { Int n=pre; for (; pre>0; pre--, c++, cut--) { if (cut<0) { /* need new Unit */ - if (up==dn->lsu) break; /* out of input digits (pre>digits) */ + if (up==dn->lsu) break; /* out of input digits (pre>digits) */ up--; cut=DECDPUN-1; u=*up; } TODIGIT(u, cut, c, pow); } - if (n<dn->digits) { /* more to come, after '.' */ + if (n<dn->digits) { /* more to come, after '.' */ *c='.'; c++; for (;; c++, cut--) { if (cut<0) { /* need new Unit */ @@ -3709,7 +3731,7 @@ static void decToString(const decNumber *dn, char *string, Flag eng) { for (; pre<0; pre++, c++) *c='0'; /* add any 0's after '.' */ for (; ; c++, cut--) { if (cut<0) { /* need new Unit */ - if (up==dn->lsu) break; /* out of input digits */ + if (up==dn->lsu) break; /* out of input digits */ up--; cut=DECDPUN-1; u=*up; @@ -3718,11 +3740,11 @@ static void decToString(const decNumber *dn, char *string, Flag eng) { } } - /* Finally add the E-part, if needed. It will never be 0, has a + /* Finally add the E-part, if needed. It will never be 0, has a base maximum and minimum of +999999999 through -999999999, but could range down to -1999999998 for anormal numbers */ if (e!=0) { - Flag had=0; /* 1=had non-zero */ + Flag had=0; /* 1=had non-zero */ *c='E'; c++; *c='+'; c++; /* assume positive */ u=e; /* .. */ @@ -3750,7 +3772,7 @@ static void decToString(const decNumber *dn, char *string, Flag eng) { /* res is C, the result. C may be A and/or B (e.g., X=X+X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* negate is DECNEG if rhs should be negated, or 0 otherwise */ /* status accumulates status for the caller */ /* */ @@ -3758,9 +3780,9 @@ static void decToString(const decNumber *dn, char *string, Flag eng) { /* Inexact in status must be 0 for correct Exact zero sign in result */ /* ------------------------------------------------------------------ */ /* If possible, the coefficient is calculated directly into C. */ -/* However, if: */ +/* However, if: */ /* -- a digits+1 calculation is needed because the numbers are */ -/* unaligned and span more than set->digits digits */ +/* unaligned and span more than set->digits digits */ /* -- a carry to digits+1 digits looks possible */ /* -- C is the same as A or B, and the result would destructively */ /* overlap the A or B coefficient */ @@ -3794,7 +3816,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, Unit accbuff[SD2U(DECBUFFER*2+20)]; /* local buffer [*2+20 reduces many */ /* allocations when called from */ /* other operations, notable exp] */ - Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */ + Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */ Int reqdigits=set->digits; /* local copy; requested DIGITS */ Int padding; /* work */ @@ -3839,7 +3861,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, else bits=(rhs->bits^negate) & DECNEG;/* RHS must be Infinity */ bits|=DECINF; decNumberZero(res); - res->bits=bits; /* set +/- infinity */ + res->bits=bits; /* set +/- infinity */ } /* an infinity */ break; } @@ -3857,7 +3879,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, #endif /* exponent will be the lower of the two */ adjust=lexp-res->exponent; /* adjustment needed [if -ve] */ - if (ISZERO(res)) { /* both 0: special IEEE 854 rules */ + if (ISZERO(res)) { /* both 0: special IEEE 754 rules */ if (adjust<0) res->exponent=lexp; /* set exponent */ /* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */ if (diffsign) { @@ -3893,7 +3915,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, /* exponent will be the lower of the two */ /* [0-0 case handled above] */ adjust=rexp-res->exponent; /* adjustment needed [if -ve] */ - if (adjust<0) { /* 0-padding needed */ + if (adjust<0) { /* 0-padding needed */ if ((res->digits-adjust)>set->digits) { adjust=res->digits-set->digits; /* to fit exactly */ *status|=DEC_Rounded; /* [but exact] */ @@ -3954,7 +3976,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, /* other) padding with up to DIGITS-1 trailing zeros may be */ /* needed; then apply rounding (as exotic rounding modes may be */ /* affected by the residue). */ - rhsshift=0; /* rhs shift to left (padding) in Units */ + rhsshift=0; /* rhs shift to left (padding) in Units */ bits=lhs->bits; /* assume sign is that of LHS */ mult=1; /* likely multiplier */ @@ -3980,13 +4002,13 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, /* for residue use the relative sign indication... */ Int shift=reqdigits-rhs->digits; /* left shift needed */ residue=1; /* residue for rounding */ - if (diffsign) residue=-residue; /* signs differ */ + if (diffsign) residue=-residue; /* signs differ */ /* copy, shortening if necessary */ decCopyFit(res, rhs, set, &residue, status); /* if it was already shorter, then need to pad with zeros */ if (shift>0) { res->digits=decShiftToMost(res->lsu, res->digits, shift); - res->exponent-=shift; /* adjust the exponent. */ + res->exponent-=shift; /* adjust the exponent. */ } /* flip the result sign if unswapped and rhs was negated */ if (!swapped) res->bits^=negate; @@ -4111,7 +4133,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG; /* sign - */ else res->bits&=~DECNEG; /* sign + */ } - } while(0); /* end protected */ + } while(0); /* end protected */ if (allocacc!=NULL) free(allocacc); /* drop any storage used */ #if DECSUBSET @@ -4132,8 +4154,8 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, /* res is C, the result. C may be A and/or B (e.g., X=X/X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ -/* op is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively. */ +/* set is the context */ +/* op is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively. */ /* status is the usual accumulator */ /* */ /* C must have space for set->digits digits. */ @@ -4148,7 +4170,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, /* */ /* Prepare operands and handle special values */ /* Test for x/0 and then 0/x */ -/* Exp =Exp1 - Exp2 */ +/* Exp =Exp1 - Exp2 */ /* Exp =Exp +len(var1) -len(var2) */ /* Sign=Sign1 * Sign2 */ /* Pad accumulator (Var1) to double-length with 0's (pad1) */ @@ -4160,7 +4182,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, /* this_unit=0 */ /* Do forever */ /* compare numbers */ -/* if <0 then leave inner_loop */ +/* if <0 then leave inner_loop */ /* if =0 then (* quick exit without subtract *) do */ /* this_unit=this_unit+1; output this_unit */ /* leave outer_loop; end */ @@ -4168,7 +4190,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, /* If same then tops2=msu2pair -- {units 1&2 of var2} */ /* else tops2=msu2plus -- {0, unit 1 of var2} */ /* tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */ -/* mult=tops1/tops2 -- Good and safe guess at divisor */ +/* mult=tops1/tops2 -- Good and safe guess at divisor */ /* if mult=0 then mult=1 */ /* this_unit=this_unit+mult */ /* subtract */ @@ -4180,7 +4202,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs, /* exp=exp-1 */ /* end outer_loop */ /* exp=exp+1 -- set the proper exponent */ -/* if have=0 then generate answer=0 */ +/* if have=0 then generate answer=0 */ /* Return (Result is defined by Var1) */ /* */ /* ------------------------------------------------------------------ */ @@ -4200,15 +4222,15 @@ static decNumber * decDivideOp(decNumber *res, #endif Unit accbuff[SD2U(DECBUFFER+DECDPUN+10)]; /* local buffer */ Unit *acc=accbuff; /* -> accumulator array for result */ - Unit *allocacc=NULL; /* -> allocated buffer, iff allocated */ + Unit *allocacc=NULL; /* -> allocated buffer, iff allocated */ Unit *accnext; /* -> where next digit will go */ Int acclength; /* length of acc needed [Units] */ Int accunits; /* count of units accumulated */ Int accdigits; /* count of digits accumulated */ - Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)*sizeof(Unit)]; /* buffer for var1 */ + Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)]; /* buffer for var1 */ Unit *var1=varbuff; /* -> var1 array for long subtraction */ - Unit *varalloc=NULL; /* -> allocated buffer, iff used */ + Unit *varalloc=NULL; /* -> allocated buffer, iff used */ Unit *msu1; /* -> msu of var1 */ const Unit *var2; /* -> var2 array */ @@ -4283,7 +4305,7 @@ static decNumber * decDivideOp(decNumber *res, /* result is [finished clone of] lhs */ decCopyFit(res, lhs, set, &residue, status); } - else { /* a division */ + else { /* a division */ decNumberZero(res); res->bits=bits; /* set +/- zero */ /* for DIVIDEINT the exponent is always 0. For DIVIDE, result */ @@ -4332,7 +4354,7 @@ static decNumber * decDivideOp(decNumber *res, decNumberZero(res); /* integer 0 */ res->bits=bits; /* sign as computed */ } - else { /* a remainder */ + else { /* a remainder */ exponent=rhs->exponent; /* [save in case overwrite] */ decNumberCopy(res, lhs); /* [zeros always fit] */ if (exponent<res->exponent) res->exponent=exponent; /* use lower */ @@ -4425,8 +4447,8 @@ static decNumber * decDivideOp(decNumber *res, for (; target>=var1; target--) *target=0; /* rhs (var2) is left-aligned with var1 at the start */ - var2ulen=var1units; /* rhs logical length (units) */ - var2units=D2U(rhs->digits); /* rhs actual length (units) */ + var2ulen=var1units; /* rhs logical length (units) */ + var2units=D2U(rhs->digits); /* rhs actual length (units) */ var2=rhs->lsu; /* -> rhs array */ msu2=var2+var2units-1; /* -> msu of var2 [never changes] */ /* now set up the variables which will be used for estimating the */ @@ -4450,7 +4472,7 @@ static decNumber * decDivideOp(decNumber *res, for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++; /* Now, if doing an integer divide or remainder, ensure that */ - /* the result will be Unit-aligned. To do this, shift the var1 */ + /* the result will be Unit-aligned. To do this, shift the var1 */ /* accumulator towards least if need be. (It's much easier to */ /* do this now than to reassemble the residue afterwards, if */ /* doing a remainder.) Also ensure the exponent is not negative. */ @@ -4463,7 +4485,7 @@ static decNumber * decDivideOp(decNumber *res, else cut=DECDPUN-exponent%DECDPUN; decShiftToLeast(var1, var1units, cut); exponent+=cut; /* maintain numerical value */ - var1initpad-=cut; /* .. and reduce padding */ + var1initpad-=cut; /* .. and reduce padding */ /* clean any most-significant units which were just emptied */ for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0; } /* align */ @@ -4478,7 +4500,7 @@ static decNumber * decDivideOp(decNumber *res, } /* ---- start the long-division loops ------------------------------ */ - accunits=0; /* no units accumulated yet */ + accunits=0; /* no units accumulated yet */ accdigits=0; /* .. or digits */ accnext=acc+acclength-1; /* -> msu of acc [NB: allows digits+1] */ for (;;) { /* outer forever loop */ @@ -4508,7 +4530,7 @@ static decNumber * decDivideOp(decNumber *res, /* reach here if var1 and var2 are identical; subtraction */ /* would increase digit by one, and the residue will be 0 so */ /* the calculation is done; leave the loop with residue=0. */ - thisunit++; /* as though subtracted */ + thisunit++; /* as though subtracted */ *var1=0; /* set var1 to 0 */ var1units=1; /* .. */ break; /* from inner */ @@ -4525,7 +4547,7 @@ static decNumber * decDivideOp(decNumber *res, } if (mult==0) mult=1; /* must always be at least 1 */ /* subtraction needed; var1 is > var2 */ - thisunit=(Unit)(thisunit+mult); /* accumulate */ + thisunit=(Unit)(thisunit+mult); /* accumulate */ /* subtract var1-var2, into var1; only the overlap needs */ /* processing, as this is an in-place calculation */ shift=var2ulen-var2units; @@ -4546,7 +4568,7 @@ static decNumber * decDivideOp(decNumber *res, /* The next unit has been calculated in full; unless it's a */ /* leading zero, add to acc */ - if (accunits!=0 || thisunit!=0) { /* is first or non-zero */ + if (accunits!=0 || thisunit!=0) { /* is first or non-zero */ *accnext=thisunit; /* store in accumulator */ /* account exactly for the new digits */ if (accunits==0) { @@ -4556,7 +4578,7 @@ static decNumber * decDivideOp(decNumber *res, else accdigits+=DECDPUN; accunits++; /* update count */ accnext--; /* ready for next */ - if (accdigits>reqdigits) break; /* have enough digits */ + if (accdigits>reqdigits) break; /* have enough digits */ } /* if the residue is zero, the operation is done (unless divide */ @@ -4609,7 +4631,7 @@ static decNumber * decDivideOp(decNumber *res, if ((lsu-QUOT10(lsu, drop+1) *powers[drop+1])!=0) break; /* found non-0 digit */ #else - if (lsu%powers[drop+1]!=0) break; /* found non-0 digit */ + if (lsu%powers[drop+1]!=0) break; /* found non-0 digit */ #endif exponent++; } @@ -4637,11 +4659,11 @@ static decNumber * decDivideOp(decNumber *res, Unit *quotlsu; /* for save */ Int quotdigits; /* .. */ - bits=lhs->bits; /* remainder sign is always as lhs */ + bits=lhs->bits; /* remainder sign is always as lhs */ /* Fastpath when residue is truly 0 is worthwhile [and */ /* simplifies the code below] */ - if (*var1==0 && var1units==1) { /* residue is 0 */ + if (*var1==0 && var1units==1) { /* residue is 0 */ Int exp=lhs->exponent; /* save min(exponents) */ if (rhs->exponent<exp) exp=rhs->exponent; decNumberZero(res); /* 0 coefficient */ @@ -4672,7 +4694,7 @@ static decNumber * decDivideOp(decNumber *res, accdigits=decGetDigits(var1, var1units); accunits=D2U(accdigits); - exponent=lhs->exponent; /* exponent is smaller of lhs & rhs */ + exponent=lhs->exponent; /* exponent is smaller of lhs & rhs */ if (rhs->exponent<exponent) exponent=rhs->exponent; /* Now correct the result if doing remainderNear; if it */ @@ -4720,7 +4742,7 @@ static decNumber * decDivideOp(decNumber *res, if (quotdigits>DECDPUN) { if (*up!=DECDPUNMAX) break;/* non-nines */ } - else { /* this is the last Unit */ + else { /* this is the last Unit */ if (*up==powers[quotdigits]-1) allnines=1; break; } @@ -4731,9 +4753,9 @@ static decNumber * decDivideOp(decNumber *res, *status|=DEC_Division_impossible; break;} - /* rem-rhs is needed; the sign will invert. Again, var1 */ + /* rem-rhs is needed; the sign will invert. Again, var1 */ /* can safely be used for the working Units array. */ - exp=rhs->exponent-exponent; /* RHS padding needed */ + exp=rhs->exponent-exponent; /* RHS padding needed */ /* Calculate units and remainder from exponent. */ expunits=exp/DECDPUN; exprem=exp%DECDPUN; @@ -4761,9 +4783,9 @@ static decNumber * decDivideOp(decNumber *res, #if DECSUBSET /* If a divide then strip trailing zeros if subset [after round] */ - if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, &dropped); + if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped); #endif - } while(0); /* end protected */ + } while(0); /* end protected */ if (varalloc!=NULL) free(varalloc); /* drop any storage used */ if (allocacc!=NULL) free(allocacc); /* .. */ @@ -4782,7 +4804,7 @@ static decNumber * decDivideOp(decNumber *res, /* res is C, the result. C may be A and/or B (e.g., X=X*X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ +/* set is the context */ /* status is the usual accumulator */ /* */ /* C must have space for set->digits digits. */ @@ -4800,13 +4822,13 @@ static decNumber * decDivideOp(decNumber *res, /* The fastpath version lumps units together into 8-digit or 9-digit */ /* chunks, and also uses a lazy carry strategy to minimise expensive */ /* 64-bit divisions. The chunks are then broken apart again into */ -/* units for continuing processing. Despite this overhead, the */ +/* units for continuing processing. Despite this overhead, the */ /* fastpath can speed up some 16-digit operations by 10x (and much */ /* more for higher-precision calculations). */ /* */ /* A buffer always has to be used for the accumulator; in the */ /* fastpath, buffers are also always needed for the chunked copies of */ -/* of the operand coefficients. */ +/* of the operand coefficients. */ /* Static buffers are larger than needed just for multiply, to allow */ /* for calls from other operations (notably exp). */ /* ------------------------------------------------------------------ */ @@ -4817,10 +4839,10 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, Int accunits; /* Units of accumulator in use */ Int exponent; /* work */ Int residue=0; /* rounding residue */ - uByte bits; /* result sign */ + uByte bits; /* result sign */ Unit *acc; /* -> accumulator Unit array */ Int needbytes; /* size calculator */ - void *allocacc=NULL; /* -> allocated accumulator, iff allocated */ + void *allocacc=NULL; /* -> allocated accumulator, iff allocated */ Unit accbuff[SD2U(DECBUFFER*4+1)]; /* buffer (+1 for DECBUFFER==0, */ /* *4 for calls from other operations) */ const Unit *mer, *mermsup; /* work */ @@ -4852,19 +4874,19 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, /* [allocacc is shared for both paths, as only one will run] */ uLong *zacc=zaccbuff; /* -> accumulator array for exact result */ #if DECDPUN==1 - Int zoff; /* accumulator offset */ + Int zoff; /* accumulator offset */ #endif uInt *lip, *rip; /* item pointers */ - uInt *lmsi, *rmsi; /* most significant items */ - Int ilhs, irhs, iacc; /* item counts in the arrays */ - Int lazy; /* lazy carry counter */ + uInt *lmsi, *rmsi; /* most significant items */ + Int ilhs, irhs, iacc; /* item counts in the arrays */ + Int lazy; /* lazy carry counter */ uLong lcarry; /* uLong carry */ uInt carry; /* carry (NB not uLong) */ - Int count; /* work */ + Int count; /* work */ const Unit *cup; /* .. */ Unit *up; /* .. */ uLong *lp; /* .. */ - Int p; /* .. */ + Int p; /* .. */ #endif #if DECSUBSET @@ -4921,10 +4943,10 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, #endif /* [following code does not require input rounding] */ - #if FASTMUL /* fastpath can be used */ + #if FASTMUL /* fastpath can be used */ /* use the fast path if there are enough digits in the shorter */ /* operand to make the setup and takedown worthwhile */ - #define NEEDTWO (DECDPUN*2) /* within two decUnitAddSub calls */ + #define NEEDTWO (DECDPUN*2) /* within two decUnitAddSub calls */ if (rhs->digits>NEEDTWO) { /* use fastpath... */ /* calculate the number of elements in each array */ ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; /* [ceiling] */ @@ -4944,7 +4966,7 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, /* Allocating the accumulator space needs a special case when */ /* DECDPUN=1 because when converting the accumulator to Units */ /* after the multiplication each 8-byte item becomes 9 1-byte */ - /* units. Therefore iacc extra bytes are needed at the front */ + /* units. Therefore iacc extra bytes are needed at the front */ /* (rounded up to a multiple of 8 bytes), and the uLong */ /* accumulator starts offset the appropriate number of units */ /* to the right to avoid overwrite during the unchunking. */ @@ -4960,7 +4982,7 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, *status|=DEC_Insufficient_storage; break;} - acc=(Unit *)zacc; /* -> target Unit array */ + acc=(Unit *)zacc; /* -> target Unit array */ #if DECDPUN==1 zacc+=zoff; /* start uLong accumulator to right */ #endif @@ -5022,12 +5044,12 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); /* [inline] */ } *(lp+1)+=carry; /* add to item above [inline] */ - *lp-=((uLong)FASTBASE*carry); /* [inline] */ + *lp-=((uLong)FASTBASE*carry); /* [inline] */ } /* carry resolution */ } /* rip loop */ /* The multiplication is complete; time to convert back into */ - /* units. This can be done in-place in the accumulator and in */ + /* units. This can be done in-place in the accumulator and in */ /* 32-bit operations, because carries were resolved after the */ /* final add. This needs N-1 divides and multiplies for */ /* each item in the accumulator (which will become up to N */ @@ -5096,7 +5118,7 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, /* There can be a 31-bit wrap in calculating the exponent. */ /* This can only happen if both input exponents are negative and */ - /* both their magnitudes are large. If there was a wrap, set a */ + /* both their magnitudes are large. If there was a wrap, set a */ /* safe very negative exponent, from which decFinalize() will */ /* raise a hard underflow shortly. */ exponent=lhs->exponent+rhs->exponent; /* calculate exponent */ @@ -5108,7 +5130,7 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, /* Set the coefficient. If any rounding, residue records */ decSetCoeff(res, set, acc, res->digits, &residue, status); decFinish(res, set, &residue, status); /* final cleanup */ - } while(0); /* end protected */ + } while(0); /* end protected */ if (allocacc!=NULL) free(allocacc); /* drop any storage used */ #if DECSUBSET @@ -5137,13 +5159,13 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, /* Restrictions: */ /* */ /* digits, emax, and -emin in the context must be less than */ -/* 2*DEC_MAX_MATH (1999998), and the rhs must be within these */ +/* 2*DEC_MAX_MATH (1999998), and the rhs must be within these */ /* bounds or a zero. This is an internal routine, so these */ /* restrictions are contractual and not enforced. */ /* */ /* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */ /* almost always be correctly rounded, but may be up to 1 ulp in */ -/* error in rare cases. */ +/* error in rare cases. */ /* */ /* Finite results will always be full precision and Inexact, except */ /* when A is a zero or -Infinity (giving 1 or 0 respectively). */ @@ -5162,11 +5184,11 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, /* The error analysis in Hull & Abrham's paper applies except for the */ /* round-off error accumulation during the series evaluation. This */ /* code does not precalculate the number of iterations and so cannot */ -/* use Horner's scheme. Instead, the accumulation is done at double- */ +/* use Horner's scheme. Instead, the accumulation is done at double- */ /* precision, which ensures that the additions of the terms are exact */ /* and do not accumulate round-off (and any round-off errors in the */ /* terms themselves move 'to the right' faster than they can */ -/* accumulate). This code also extends the calculation by allowing, */ +/* accumulate). This code also extends the calculation by allowing, */ /* in the spirit of other decNumber operators, the input to be more */ /* precise than the result (the precision used is based on the more */ /* precise of the input or requested result). */ @@ -5189,7 +5211,7 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, /* more for smaller values. */ /* */ /* The leverage that can be applied in this way is severely */ -/* limited by the cost of the raise-to-the power at the end, */ +/* limited by the cost of the raise-to-the power at the end, */ /* which dominates when the number of iterations is small (less */ /* than ten) or when rhs is short. As an example, the adjustment */ /* x**10,000,000 needs 31 multiplications, all but one full-width. */ @@ -5274,7 +5296,7 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, *d->lsu=4; /* set 4 .. */ d->exponent=-set->digits; /* * 10**(-d) */ if (decNumberIsNegative(rhs)) d->exponent--; /* negative case */ - comp=decCompare(d, rhs, 1); /* signless compare */ + comp=decCompare(d, rhs, 1); /* signless compare */ if (comp==BADINT) { *status|=DEC_Insufficient_storage; break;} @@ -5327,18 +5349,18 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, /* front" effect. */ Int lever=MINI(8-h, maxlever); /* leverage attainable */ Int use=-rhs->digits-lever; /* exponent to use for RHS */ - h+=lever; /* apply leverage selected */ + h+=lever; /* apply leverage selected */ if (h<0) { /* clamp */ - use+=h; /* [may end up subnormal] */ + use+=h; /* [may end up subnormal] */ h=0; } /* Take a copy of RHS if it needs normalization (true whenever x>=1) */ if (rhs->exponent!=use) { - decNumber *newrhs=bufr; /* assume will fit on stack */ + decNumber *newrhs=bufr; /* assume will fit on stack */ needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit); if (needbytes>sizeof(bufr)) { /* need malloc space */ allocrhs=(decNumber *)malloc(needbytes); - if (allocrhs==NULL) { /* hopeless -- abandon */ + if (allocrhs==NULL) { /* hopeless -- abandon */ *status|=DEC_Insufficient_storage; break;} newrhs=allocrhs; /* use the allocated space */ @@ -5354,7 +5376,7 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, /* third term by setting the term variable t=x, the accumulator */ /* a=1, and the divisor d=2. */ - /* First determine the working precision. From Hull & Abrham */ + /* First determine the working precision. From Hull & Abrham */ /* this is set->digits+h+2. However, if x is 'over-precise' we */ /* need to allow for all its digits to potentially participate */ /* (consider an x where all the excess digits are 9s) so in */ @@ -5411,7 +5433,7 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, /* only the status from the accumulation is interesting */ /* [but it should remain unchanged after first add] */ decAddOp(a, a, t, &aset, 0, status); /* a=a+t */ - decMultiplyOp(t, t, x, &tset, &ignore); /* t=t*x */ + decMultiplyOp(t, t, x, &tset, &ignore); /* t=t*x */ decDivideOp(t, t, d, &tset, DIVIDE, &ignore); /* t=t/d */ /* the iteration ends when the term cannot affect the result, */ /* if rounded to p digits, which is when its value is smaller */ @@ -5426,7 +5448,7 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, /* just a sanity check; comment out test to show always */ if (iterations>p+3) printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n", - iterations, *status, p, x->digits); + (LI)iterations, (LI)*status, (LI)p, (LI)x->digits); #endif } /* h<=8 */ @@ -5445,13 +5467,13 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, /* abandon if have had overflow or terminal underflow */ if (*status & (DEC_Overflow|DEC_Underflow)) { /* interesting? */ if (*status&DEC_Overflow || ISZERO(t)) break;} - n=n<<1; /* move next bit to testable position */ + n=n<<1; /* move next bit to testable position */ if (n<0) { /* top bit is set */ seenbit=1; /* OK, have a significant bit */ decMultiplyOp(t, t, a, &aset, status); /* acc=acc*x */ } if (i==31) break; /* that was the last bit */ - if (!seenbit) continue; /* no need to square 1 */ + if (!seenbit) continue; /* no need to square 1 */ decMultiplyOp(t, t, t, &aset, status); /* acc=acc*acc [square] */ } /*i*/ /* 32 bits */ /* decNumberShow(t); */ @@ -5464,7 +5486,7 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, aset.digits=set->digits; /* [use default rounding] */ decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */ decFinish(res, set, &residue, status); /* cleanup/set flags */ - } while(0); /* end protected */ + } while(0); /* end protected */ if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */ if (allocbufa!=NULL) free(allocbufa); /* .. */ @@ -5489,16 +5511,16 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, /* where x is truncated (NB) into the range 10 through 99, */ /* and then c = k>>2 and e = k&3. */ /* ------------------------------------------------------------------ */ -const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208, - 6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312, - 5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032, +const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208, + 6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312, + 5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032, 39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629, 29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837, 22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321, 15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717, - 10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801, - 5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254, - 10130, 6046, 20055}; + 10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801, + 5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254, + 10130, 6046, 20055}; /* ------------------------------------------------------------------ */ /* decLnOp -- effect natural logarithm */ @@ -5526,7 +5548,7 @@ const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208, /* */ /* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */ /* almost always be correctly rounded, but may be up to 1 ulp in */ -/* error in rare cases. */ +/* error in rare cases. */ /* ------------------------------------------------------------------ */ /* The result is calculated using Newton's method, with each */ /* iteration calculating a' = a + x * exp(-a) - 1. See, for example, */ @@ -5538,7 +5560,7 @@ const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208, /* */ /* Implementation notes: */ /* */ -/* 1. This is separated out as decLnOp so it can be called from */ +/* 1. This is separated out as decLnOp so it can be called from */ /* other Mathematical functions (e.g., Log 10) with a wider range */ /* than normal. In particular, it can handle the slightly wider */ /* (+9+2) range needed by a power function. */ @@ -5631,7 +5653,7 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs, break;} } /* integer and short */ - /* Determine the working precision. This is normally the */ + /* Determine the working precision. This is normally the */ /* requested precision + 2, with a minimum of 9. However, if */ /* the rhs is 'over-precise' then allow for all its digits to */ /* potentially participate (consider an rhs where all the excess */ @@ -5684,7 +5706,7 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs, decCopyFit(b, rhs, &aset, &residue, &ignore); /* copy & shorten */ b->exponent=0; /* make integer */ t=decGetInt(b); /* [cannot fail] */ - if (t<10) t=X10(t); /* adjust single-digit b */ + if (t<10) t=X10(t); /* adjust single-digit b */ t=LNnn[t-10]; /* look up ln(b) */ decNumberFromInt32(b, t>>2); /* b=ln(b) coefficient */ b->exponent=-(t&3)-3; /* set exponent */ @@ -5713,13 +5735,13 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs, /* [initially 9 as then the sequence starts 7+2, 16+2, and */ /* 34+2, which is ideal for standard-sized numbers] */ aset.digits=pp; /* working context */ - bset.digits=pp+rhs->digits; /* wider context */ + bset.digits=pp+rhs->digits; /* wider context */ for (;;) { /* iterate */ #if DECCHECK iterations++; - if (iterations>24) break; /* consider 9 * 2**24 */ + if (iterations>24) break; /* consider 9 * 2**24 */ #endif - /* calculate the adjustment (exp(-a)*x-1) into b. This is a */ + /* calculate the adjustment (exp(-a)*x-1) into b. This is a */ /* catastrophic subtraction but it really is the difference */ /* from 1 that is of interest. */ /* Use the internal entry point to Exp as it allows the double */ @@ -5728,7 +5750,7 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs, decExpOp(b, a, &bset, &ignore); /* b=exp(-a) */ a->bits^=DECNEG; /* restore sign of a */ /* now multiply by rhs and subtract 1, at the wider precision */ - decMultiplyOp(b, b, rhs, &bset, &ignore); /* b=b*rhs */ + decMultiplyOp(b, b, rhs, &bset, &ignore); /* b=b*rhs */ decAddOp(b, b, &numone, &bset, DECNEG, &ignore); /* b=b-1 */ /* the iteration ends when the adjustment cannot affect the */ @@ -5766,7 +5788,7 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs, /* just a sanity check; remove the test to show always */ if (iterations>24) printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n", - iterations, *status, p, rhs->digits); + (LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits); #endif /* Copy and round the result to res */ @@ -5775,7 +5797,7 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs, aset.digits=set->digits; /* [use default rounding] */ decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */ decFinish(res, set, &residue, status); /* cleanup/set flags */ - } while(0); /* end protected */ + } while(0); /* end protected */ if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */ if (allocbufb!=NULL) free(allocbufb); /* .. */ @@ -5788,14 +5810,14 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs, /* */ /* This computes C = op(A, B), where op adjusts the coefficient */ /* of C (by rounding or shifting) such that the exponent (-scale) */ -/* of C has the value B or matches the exponent of B. */ +/* of C has the value B or matches the exponent of B. */ /* The numerical value of C will equal A, except for the effects of */ /* any rounding that occurred. */ /* */ /* res is C, the result. C may be A or B */ /* lhs is A, the number to adjust */ /* rhs is B, the requested exponent */ -/* set is the context */ +/* set is the context */ /* quant is 1 for quantize or 0 for rescale */ /* status is the status accumulator (this can be called without */ /* risk of control loss) */ @@ -5814,7 +5836,7 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs, #endif const decNumber *inrhs=rhs; /* save original rhs */ Int reqdigits=set->digits; /* requested DIGITS */ - Int reqexp; /* requested exponent [-scale] */ + Int reqexp; /* requested exponent [-scale] */ Int residue=0; /* rounding residue */ Int etiny=set->emin-(reqdigits-1); @@ -5904,7 +5926,7 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs, if (res->exponent>reqexp) { /* re-check needed, e.g., for quantize(0.9999, 0.001) under */ /* set->digits==3 */ - if (res->digits==reqdigits) { /* cannot shift by 1 */ + if (res->digits==reqdigits) { /* cannot shift by 1 */ *status&=~(DEC_Inexact | DEC_Rounded); /* [clean these] */ *status|=DEC_Invalid_operation; break; @@ -5937,9 +5959,9 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs, } else { decFinalize(res, set, &residue, status); /* set subnormal flags */ - *status&=~DEC_Underflow; /* suppress Underflow [754r] */ + *status&=~DEC_Underflow; /* suppress Underflow [as per 754] */ } - } while(0); /* end protected */ + } while(0); /* end protected */ #if DECSUBSET if (allocrhs!=NULL) free(allocrhs); /* drop any storage used */ @@ -5956,26 +5978,26 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs, /* result of a comparison unless one or both */ /* operands is a NaN (in which case a NaN results) */ /* COMPSIG -- as COMPARE except that a quiet NaN raises */ -/* Invalid operation. */ +/* Invalid operation. */ /* COMPMAX -- returns the larger of the operands, using the */ -/* 754r maxnum operation */ +/* 754 maxnum operation */ /* COMPMAXMAG -- ditto, comparing absolute values */ -/* COMPMIN -- the 754r minnum operation */ +/* COMPMIN -- the 754 minnum operation */ /* COMPMINMAG -- ditto, comparing absolute values */ -/* COMTOTAL -- returns the signum (as a number) giving the */ -/* result of a comparison using 754r total ordering */ +/* COMTOTAL -- returns the signum (as a number) giving the */ +/* result of a comparison using 754 total ordering */ /* */ /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ /* lhs is A */ /* rhs is B */ -/* set is the context */ -/* op is the operation flag */ +/* set is the context */ +/* op is the operation flag */ /* status is the usual accumulator */ /* */ /* C must have space for one digit for COMPARE or set->digits for */ -/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG. */ +/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG. */ /* ------------------------------------------------------------------ */ -/* The emphasis here is on speed for common cases, and avoiding */ +/* The emphasis here is on speed for common cases, and avoiding */ /* coefficient comparison if possible. */ /* ------------------------------------------------------------------ */ decNumber * decCompareOp(decNumber *res, const decNumber *lhs, @@ -5986,7 +6008,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs, decNumber *allocrhs=NULL; /* .., rhs */ #endif Int result=0; /* default result value */ - uByte merged; /* work */ + uByte merged; /* work */ #if DECCHECK if (decCheckOperands(res, lhs, rhs, set)) return res; @@ -6026,7 +6048,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs, /* This assumes sNaN (even just one) leads to NaN. */ merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN); if (merged) { /* a NaN bit set */ - if (op==COMPARE); /* result will be NaN */ + if (op==COMPARE); /* result will be NaN */ else if (op==COMPSIG) /* treat qNaN as sNaN */ *status|=DEC_Invalid_operation | DEC_sNaN; else if (op==COMPTOTAL) { /* total ordering, always finite */ @@ -6049,7 +6071,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs, else if (merged & DECSNAN); /* sNaN -> qNaN */ else { /* here if MIN or MAX and one or two quiet NaNs */ - /* min or max -- 754r rules ignore single NaN */ + /* min or max -- 754 rules ignore single NaN */ if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) { /* just one NaN; force choice to be the non-NaN operand */ op=COMPMAX; @@ -6065,7 +6087,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs, /* have numbers */ if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1); else result=decCompare(lhs, rhs, 0); /* sign matters */ - } while(0); /* end protected */ + } while(0); /* end protected */ if (result==BADINT) *status|=DEC_Insufficient_storage; /* rare */ else { @@ -6091,7 +6113,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs, /* choose the operand for the result */ const decNumber *choice; if (result==0) { /* operands are numerically equal */ - /* choose according to sign then exponent (see 754r) */ + /* choose according to sign then exponent (see 754) */ uByte slhs=(lhs->bits & DECNEG); uByte srhs=(rhs->bits & DECNEG); #if DECSUBSET @@ -6110,7 +6132,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs, else result=-1; /* [if equal, use lhs, technically identical] */ } - else { /* both positive */ + else { /* both positive */ if (lhs->exponent>rhs->exponent) result=+1; else result=-1; /* [ditto] */ @@ -6145,7 +6167,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ static Int decCompare(const decNumber *lhs, const decNumber *rhs, Flag abs) { - Int result; /* result value */ + Int result; /* result value */ Int sigr; /* rhs signum */ Int compare; /* work */ @@ -6186,7 +6208,7 @@ static Int decCompare(const decNumber *lhs, const decNumber *rhs, compare=decUnitCompare(lhs->lsu, D2U(lhs->digits), rhs->lsu, D2U(rhs->digits), rhs->exponent-lhs->exponent); - if (compare!=BADINT) compare*=result; /* comparison succeeded */ + if (compare!=BADINT) compare*=result; /* comparison succeeded */ return compare; } /* decCompare */ @@ -6195,7 +6217,7 @@ static Int decCompare(const decNumber *lhs, const decNumber *rhs, /* */ /* This routine compares A ? B*10**E where A and B are unit arrays */ /* A is a plain integer */ -/* B has an exponent of E (which must be non-negative) */ +/* B has an exponent of E (which must be non-negative) */ /* */ /* Arg1 is A first Unit (lsu) */ /* Arg2 is A length in Units */ @@ -6205,18 +6227,18 @@ static Int decCompare(const decNumber *lhs, const decNumber *rhs, /* */ /* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */ /* (the only possible failure is an allocation error, which can */ -/* only occur if E!=0) */ +/* only occur if E!=0) */ /* ------------------------------------------------------------------ */ static Int decUnitCompare(const Unit *a, Int alength, const Unit *b, Int blength, Int exp) { Unit *acc; /* accumulator for result */ Unit accbuff[SD2U(DECBUFFER*2+1)]; /* local buffer */ - Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */ - Int accunits, need; /* units in use or needed for acc */ + Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */ + Int accunits, need; /* units in use or needed for acc */ const Unit *l, *r, *u; /* work */ Int expunits, exprem, result; /* .. */ - if (exp==0) { /* aligned; fastpath */ + if (exp==0) { /* aligned; fastpath */ if (alength>blength) return 1; if (alength<blength) return -1; /* same number of units in both -- need unit-by-unit compare */ @@ -6229,7 +6251,7 @@ static Int decUnitCompare(const Unit *a, Int alength, return 0; /* all units match */ } /* aligned */ - /* Unaligned. If one is >1 unit longer than the other, padded */ + /* Unaligned. If one is >1 unit longer than the other, padded */ /* approximately, then can return easily */ if (alength>blength+(Int)D2U(exp)) return 1; if (alength+1<blength+(Int)D2U(exp)) return -1; @@ -6276,7 +6298,7 @@ static Int decUnitCompare(const Unit *a, Int alength, /* A may be shorter or longer than B. */ /* */ /* Leading zeros are not removed after a calculation. The result is */ -/* either the same length as the longer of A and B (adding any */ +/* either the same length as the longer of A and B (adding any */ /* shift), or one Unit longer than that (if a Unit carry occurred). */ /* */ /* A and B content are not altered unless C is also A or B. */ @@ -6315,10 +6337,10 @@ static Int decUnitAddSub(const Unit *a, Int alength, const Unit *b, Int blength, Int bshift, Unit *c, Int m) { const Unit *alsu=a; /* A lsu [need to remember it] */ - Unit *clsu=c; /* C ditto */ + Unit *clsu=c; /* C ditto */ Unit *minC; /* low water mark for C */ Unit *maxC; /* high water mark for C */ - eInt carry=0; /* carry integer (could be Long) */ + eInt carry=0; /* carry integer (could be Long) */ Int add; /* work */ #if DECDPUN<=4 /* myriadal, millenary, etc. */ Int est; /* estimated quotient */ @@ -6378,7 +6400,7 @@ static Int decUnitAddSub(const Unit *a, Int alength, carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ est=(((ueInt)carry>>11)*53687)>>18; *c=(Unit)(carry-est*(DECDPUNMAX+1)); - carry=est-(DECDPUNMAX+1); /* correctly negative */ + carry=est-(DECDPUNMAX+1); /* correctly negative */ if (*c<DECDPUNMAX+1) continue; /* was OK */ carry++; *c-=DECDPUNMAX+1; @@ -6396,7 +6418,7 @@ static Int decUnitAddSub(const Unit *a, Int alength, carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ est=(((ueInt)carry>>3)*16777)>>21; *c=(Unit)(carry-est*(DECDPUNMAX+1)); - carry=est-(DECDPUNMAX+1); /* correctly negative */ + carry=est-(DECDPUNMAX+1); /* correctly negative */ if (*c<DECDPUNMAX+1) continue; /* was OK */ carry++; *c-=DECDPUNMAX+1; @@ -6412,7 +6434,7 @@ static Int decUnitAddSub(const Unit *a, Int alength, carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ est=QUOT10(carry, DECDPUN); *c=(Unit)(carry-est*(DECDPUNMAX+1)); - carry=est-(DECDPUNMAX+1); /* correctly negative */ + carry=est-(DECDPUNMAX+1); /* correctly negative */ #else /* remainder operator is undefined if negative, so must test */ if ((ueInt)carry<(DECDPUNMAX+1)*2) { /* fastpath carry +1 */ @@ -6465,7 +6487,7 @@ static Int decUnitAddSub(const Unit *a, Int alength, carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ est=(((ueInt)carry>>11)*53687)>>18; *c=(Unit)(carry-est*(DECDPUNMAX+1)); - carry=est-(DECDPUNMAX+1); /* correctly negative */ + carry=est-(DECDPUNMAX+1); /* correctly negative */ if (*c<DECDPUNMAX+1) continue; /* was OK */ carry++; *c-=DECDPUNMAX+1; @@ -6483,7 +6505,7 @@ static Int decUnitAddSub(const Unit *a, Int alength, carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ est=(((ueInt)carry>>3)*16777)>>21; *c=(Unit)(carry-est*(DECDPUNMAX+1)); - carry=est-(DECDPUNMAX+1); /* correctly negative */ + carry=est-(DECDPUNMAX+1); /* correctly negative */ if (*c<DECDPUNMAX+1) continue; /* was OK */ carry++; *c-=DECDPUNMAX+1; @@ -6498,7 +6520,7 @@ static Int decUnitAddSub(const Unit *a, Int alength, carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ est=QUOT10(carry, DECDPUN); *c=(Unit)(carry-est*(DECDPUNMAX+1)); - carry=est-(DECDPUNMAX+1); /* correctly negative */ + carry=est-(DECDPUNMAX+1); /* correctly negative */ #else if ((ueInt)carry<(DECDPUNMAX+1)*2){ /* fastpath carry 1 */ *c=(Unit)(carry-(DECDPUNMAX+1)); @@ -6556,8 +6578,9 @@ static Int decUnitAddSub(const Unit *a, Int alength, /* dn is the number to trim or normalize */ /* set is the context to use to check for clamp */ /* all is 1 to remove all trailing zeros, 0 for just fraction ones */ +/* noclamp is 1 to unconditional (unclamped) trim */ /* dropped returns the number of discarded trailing zeros */ -/* returns dn */ +/* returns dn */ /* */ /* If clamp is set in the context then the number of zeros trimmed */ /* may be limited if the exponent is high. */ @@ -6565,8 +6588,8 @@ static Int decUnitAddSub(const Unit *a, Int alength, /* so special values are unchanged and no error is possible. */ /* ------------------------------------------------------------------ */ static decNumber * decTrim(decNumber *dn, decContext *set, Flag all, - Int *dropped) { - Int d, exp; /* work */ + Flag noclamp, Int *dropped) { + Int d, exp; /* work */ uInt cut; /* .. */ Unit *up; /* -> current Unit */ @@ -6595,7 +6618,7 @@ static decNumber * decTrim(decNumber *dn, decContext *set, Flag all, if (*up%powers[cut]!=0) break; /* found non-0 digit */ #endif /* have a trailing 0 */ - if (!all) { /* trimming */ + if (!all) { /* trimming */ /* [if exp>0 then all trailing 0s are significant for trim] */ if (exp<=0) { /* if digit might be significant */ if (exp==0) break; /* then quit */ @@ -6611,7 +6634,7 @@ static decNumber * decTrim(decNumber *dn, decContext *set, Flag all, if (d==0) return dn; /* none to drop */ /* may need to limit drop if clamping */ - if (set->clamp) { + if (set->clamp && !noclamp) { Int maxd=set->emax-set->digits+1-dn->exponent; if (maxd<=0) return dn; /* nothing possible */ if (d>maxd) d=maxd; @@ -6656,7 +6679,7 @@ static void decReverse(Unit *ulo, Unit *uhi) { /* returns the new length of the integer in the array, in digits */ /* */ /* No overflow is permitted (that is, the uar array must be known to */ -/* be large enough to hold the result, after shifting). */ +/* be large enough to hold the result, after shifting). */ /* ------------------------------------------------------------------ */ static Int decShiftToMost(Unit *uar, Int digits, Int shift) { Unit *target, *source, *first; /* work */ @@ -6672,8 +6695,8 @@ static Int decShiftToMost(Unit *uar, Int digits, Int shift) { next=0; /* all paths */ source=uar+D2U(digits)-1; /* where msu comes from */ target=source+D2U(shift); /* where upper part of first cut goes */ - cut=DECDPUN-MSUDIGITS(shift); /* where to slice */ - if (cut==0) { /* unit-boundary case */ + cut=DECDPUN-MSUDIGITS(shift); /* where to slice */ + if (cut==0) { /* unit-boundary case */ for (; source>=uar; source--, target--) *target=*source; } else { @@ -6704,14 +6727,14 @@ static Int decShiftToMost(Unit *uar, Int digits, Int shift) { /* ------------------------------------------------------------------ */ /* decShiftToLeast -- shift digits in array towards least significant */ /* */ -/* uar is the array */ +/* uar is the array */ /* units is length of the array, in units */ /* shift is the number of digits to remove from the lsu end; it */ /* must be zero or positive and <= than units*DECDPUN. */ /* */ /* returns the new length of the integer in the array, in units */ /* */ -/* Removed digits are discarded (lost). Units not required to hold */ +/* Removed digits are discarded (lost). Units not required to hold */ /* the final result are unchanged. */ /* ------------------------------------------------------------------ */ static Int decShiftToLeast(Unit *uar, Int units, Int shift) { @@ -6774,11 +6797,11 @@ static Int decShiftToLeast(Unit *uar, Int units, Int shift) { /* lostDigits and other status may be set by this. */ /* */ /* Since the input is an operand, it must not be modified. */ -/* Instead, return an allocated decNumber, rounded as required. */ +/* Instead, return an allocated decNumber, rounded as required. */ /* It is the caller's responsibility to free the allocated storage. */ /* */ /* If no storage is available then the result cannot be used, so NULL */ -/* is returned. */ +/* is returned. */ /* ------------------------------------------------------------------ */ static decNumber *decRoundOperand(const decNumber *dn, decContext *set, uInt *status) { @@ -6810,7 +6833,7 @@ static decNumber *decRoundOperand(const decNumber *dn, decContext *set, /* dest is the target decNumber */ /* src is the source decNumber */ /* set is the context [used for length (digits) and rounding mode] */ -/* residue is the residue accumulator */ +/* residue is the residue accumulator */ /* status contains the current status to be updated */ /* */ /* (dest==src is allowed and will be a no-op if fits) */ @@ -6826,20 +6849,20 @@ static void decCopyFit(decNumber *dest, const decNumber *src, /* ------------------------------------------------------------------ */ /* decSetCoeff -- set the coefficient of a number */ /* */ -/* dn is the number whose coefficient array is to be set. */ +/* dn is the number whose coefficient array is to be set. */ /* It must have space for set->digits digits */ /* set is the context [for size] */ /* lsu -> lsu of the source coefficient [may be dn->lsu] */ /* len is digits in the source coefficient [may be dn->digits] */ -/* residue is the residue accumulator. This has values as in */ +/* residue is the residue accumulator. This has values as in */ /* decApplyRound, and will be unchanged unless the */ /* target size is less than len. In this case, the */ /* coefficient is truncated and the residue is updated to */ -/* reflect the previous residue and the dropped digits. */ -/* status is the status accumulator, as usual */ +/* reflect the previous residue and the dropped digits. */ +/* status is the status accumulator, as usual */ /* */ /* The coefficient may already be in the number, or it can be an */ -/* external intermediate array. If it is in the number, lsu must == */ +/* external intermediate array. If it is in the number, lsu must == */ /* dn->lsu and len must == dn->digits. */ /* */ /* Note that the coefficient length (len) may be < set->digits, and */ @@ -6860,7 +6883,7 @@ static void decCopyFit(decNumber *dest, const decNumber *src, /* ------------------------------------------------------------------ */ /* mapping array: maps 0-9 to canonical residues, so that a residue */ /* can be adjusted in the range [-1, +1] and achieve correct rounding */ -/* 0 1 2 3 4 5 6 7 8 9 */ +/* 0 1 2 3 4 5 6 7 8 9 */ static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7}; static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, Int len, Int *residue, uInt *status) { @@ -6875,7 +6898,7 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, discard=len-set->digits; /* digits to discard */ if (discard<=0) { /* no digits are being discarded */ - if (dn->lsu!=lsu) { /* copy needed */ + if (dn->lsu!=lsu) { /* copy needed */ /* copy the coefficient array to the result number; no shift needed */ count=len; /* avoids D2U */ up=lsu; @@ -6890,7 +6913,7 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, /* some digits must be discarded ... */ dn->exponent+=discard; /* maintain numerical value */ - *status|=DEC_Rounded; /* accumulate Rounded status */ + *status|=DEC_Rounded; /* accumulate Rounded status */ if (*residue>1) *residue=1; /* previous residue now to right, so reduce */ if (discard>len) { /* everything, +1, is being discarded */ @@ -6904,7 +6927,7 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, } } if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude */ - *dn->lsu=0; /* coefficient will now be 0 */ + *dn->lsu=0; /* coefficient will now be 0 */ dn->digits=1; /* .. */ return; } /* total discard */ @@ -6924,12 +6947,12 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, /* here up -> Unit with first discarded digit */ cut=discard-(count-DECDPUN)-1; - if (cut==DECDPUN-1) { /* unit-boundary case (fast) */ + if (cut==DECDPUN-1) { /* unit-boundary case (fast) */ Unit half=(Unit)powers[DECDPUN]>>1; /* set residue directly */ if (*up>=half) { if (*up>half) *residue=7; - else *residue+=5; /* add sticky bit */ + else *residue+=5; /* add sticky bit */ } else { /* <half */ if (*up!=0) *residue=3; /* [else is 0, leave as sticky bit] */ @@ -6940,7 +6963,7 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, } else { /* shift to least */ count=set->digits; /* now digits to end up with */ - dn->digits=count; /* set the new length */ + dn->digits=count; /* set the new length */ up++; /* move to next */ /* on unit boundary, so shift-down copy loop is simple */ for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN) @@ -6952,7 +6975,7 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, uInt discard1; /* first discarded digit */ uInt quot, rem; /* for divisions */ if (cut==0) quot=*up; /* is at bottom of unit */ - else /* cut>0 */ { /* it's not at bottom of unit */ + else /* cut>0 */ { /* it's not at bottom of unit */ #if DECDPUN<=4 quot=QUOT10(*up, cut); rem=*up-quot*powers[cut]; @@ -6985,7 +7008,7 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, } else { /* shift to least needed */ count=set->digits; /* now digits to end up with */ - dn->digits=count; /* set the new length */ + dn->digits=count; /* set the new length */ /* shift-copy the coefficient array to the result number */ for (target=dn->lsu; ; target++) { *target=(Unit)quot; @@ -7014,7 +7037,7 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, /* ------------------------------------------------------------------ */ /* decApplyRound -- apply pending rounding to a number */ /* */ -/* dn is the number, with space for set->digits digits */ +/* dn is the number, with space for set->digits digits */ /* set is the context [for size and rounding mode] */ /* residue indicates pending rounding, being any accumulated */ /* guard and sticky information. It may be: */ @@ -7023,14 +7046,14 @@ static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, /* 1-4: rounding digit is <5 and >0 */ /* 0: the coefficient is exact */ /* -1: as 1, but the hidden digits are subtractive, that */ -/* is, of the opposite sign to dn. In this case the */ +/* is, of the opposite sign to dn. In this case the */ /* coefficient must be non-0. This case occurs when */ /* subtracting a small number (which can be reduced to */ /* a sticky bit); see decAddOp. */ -/* status is the status accumulator, as usual */ +/* status is the status accumulator, as usual */ /* */ /* This routine applies rounding while keeping the length of the */ -/* coefficient constant. The exponent and status are unchanged */ +/* coefficient constant. The exponent and status are unchanged */ /* except if: */ /* */ /* -- the coefficient was increased and is all nines (in which */ @@ -7125,7 +7148,7 @@ static void decApplyRound(decNumber *dn, decContext *set, Int residue, if (bump==0) return; /* no action required */ /* Simply use decUnitAddSub unless bumping up and the number is */ - /* all nines. In this special case set to 100... explicitly */ + /* all nines. In this special case set to 100... explicitly */ /* and adjust the exponent by one (as otherwise could overflow */ /* the array) */ /* Similarly handle all-nines result if bumping down. */ @@ -7139,12 +7162,12 @@ static void decApplyRound(decNumber *dn, decContext *set, Int residue, /* here if it, too, is all nines */ *up=(Unit)powers[count-1]; /* here 999 -> 100 etc. */ for (up=up-1; up>=dn->lsu; up--) *up=0; /* others all to 0 */ - dn->exponent++; /* and bump exponent */ + dn->exponent++; /* and bump exponent */ /* [which, very rarely, could cause Overflow...] */ if ((dn->exponent+dn->digits)>set->emax+1) { decSetOverflow(dn, set, status); } - return; /* done */ + return; /* done */ } /* a full unit to check, with more to come */ if (*up!=DECDPUNMAX) break; /* not still 9s */ @@ -7161,11 +7184,11 @@ static void decApplyRound(decNumber *dn, decContext *set, Int residue, /* this is the last Unit (the msu) */ if (*up!=powers[count-1]) break; /* not 100.. */ /* here if have the 1000... case */ - sup=up; /* save msu pointer */ + sup=up; /* save msu pointer */ *up=(Unit)powers[count]-1; /* here 100 in msu -> 999 */ /* others all to all-nines, too */ for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1; - dn->exponent--; /* and bump exponent */ + dn->exponent--; /* and bump exponent */ /* iff the number was at the subnormal boundary (exponent=etiny) */ /* then the exponent is now out of range, so it will in fact get */ @@ -7181,7 +7204,7 @@ static void decApplyRound(decNumber *dn, decContext *set, Int residue, dn->exponent++; *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded; } - return; /* done */ + return; /* done */ } /* a full unit to check, with more to come */ @@ -7200,7 +7223,7 @@ static void decApplyRound(decNumber *dn, decContext *set, Int residue, /* decFinish -- finish processing a number */ /* */ /* dn is the number */ -/* set is the context */ +/* set is the context */ /* residue is the rounding accumulator (as in decApplyRound) */ /* status is the accumulator */ /* */ @@ -7237,14 +7260,14 @@ static void decFinish(decNumber *dn, decContext *set, Int *residue, /* decFinalize -- final check, clamp, and round of a number */ /* */ /* dn is the number */ -/* set is the context */ +/* set is the context */ /* residue is the rounding accumulator (as in decApplyRound) */ /* status is the status accumulator */ /* */ /* This finishes off the current number by checking for subnormal */ /* results, applying any pending rounding, checking for overflow, */ /* and applying any clamping. */ -/* Underflow and overflow conditions are raised as appropriate. */ +/* Underflow and overflow conditions are raised as appropriate. */ /* All fields are updated as required. */ /* ------------------------------------------------------------------ */ static void decFinalize(decNumber *dn, decContext *set, Int *residue, @@ -7272,12 +7295,12 @@ static void decFinalize(decNumber *dn, decContext *set, Int *residue, nmin.lsu[0]=1; nmin.exponent=set->emin; comp=decCompare(dn, &nmin, 1); /* (signless compare) */ - if (comp==BADINT) { /* oops */ + if (comp==BADINT) { /* oops */ *status|=DEC_Insufficient_storage; /* abandon... */ return; } if (*residue<0 && comp==0) { /* neg residue and dn==Nmin */ - decApplyRound(dn, set, *residue, status); /* might force down */ + decApplyRound(dn, set, *residue, status); /* might force down */ decSetSubnormal(dn, set, residue, status); return; } @@ -7306,27 +7329,27 @@ static void decFinalize(decNumber *dn, decContext *set, Int *residue, dn->digits=decShiftToMost(dn->lsu, dn->digits, shift); } dn->exponent-=shift; /* adjust the exponent to match */ - *status|=DEC_Clamped; /* and record the dirty deed */ + *status|=DEC_Clamped; /* and record the dirty deed */ return; } /* decFinalize */ /* ------------------------------------------------------------------ */ /* decSetOverflow -- set number to proper overflow value */ /* */ -/* dn is the number (used for sign [only] and result) */ +/* dn is the number (used for sign [only] and result) */ /* set is the context [used for the rounding mode, etc.] */ /* status contains the current status to be updated */ /* */ /* This sets the sign of a number and sets its value to either */ /* Infinity or the maximum finite value, depending on the sign of */ -/* dn and the rounding mode, following IEEE 854 rules. */ +/* dn and the rounding mode, following IEEE 754 rules. */ /* ------------------------------------------------------------------ */ static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) { Flag needmax=0; /* result is maximum finite value */ uByte sign=dn->bits&DECNEG; /* clean and save sign bit */ if (ISZERO(dn)) { /* zero does not overflow magnitude */ - Int emax=set->emax; /* limit value */ + Int emax=set->emax; /* limit value */ if (set->clamp) emax-=set->digits-1; /* lower if clamping */ if (dn->exponent>emax) { /* clamp required */ dn->exponent=emax; @@ -7360,7 +7383,7 @@ static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) { } /* decSetOverflow */ /* ------------------------------------------------------------------ */ -/* decSetMaxValue -- set number to +Nmax (maximum normal value) */ +/* decSetMaxValue -- set number to +Nmax (maximum normal value) */ /* */ /* dn is the number to set */ /* set is the context [used for digits and emax] */ @@ -7403,7 +7426,6 @@ static void decSetMaxValue(decNumber *dn, decContext *set) { /* ------------------------------------------------------------------ */ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue, uInt *status) { - Int dnexp; /* saves original exponent */ decContext workset; /* work */ Int etiny, adjust; /* .. */ @@ -7448,15 +7470,14 @@ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue, /* adjust>0, so need to rescale the result so exponent becomes Etiny */ /* [this code is similar to that in rescale] */ - dnexp=dn->exponent; /* save exponent */ - workset=*set; /* clone rounding, etc. */ + workset=*set; /* clone rounding, etc. */ workset.digits=dn->digits-adjust; /* set requested length */ - workset.emin-=adjust; /* and adjust emin to match */ + workset.emin-=adjust; /* and adjust emin to match */ /* [note that the latter can be <1, here, similar to Rescale case] */ decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status); decApplyRound(dn, &workset, *residue, status); - /* Use 754R/854 default rule: Underflow is set iff Inexact */ + /* Use 754 default rule: Underflow is set iff Inexact */ /* [independent of whether trapped] */ if (*status&DEC_Inexact) *status|=DEC_Underflow; @@ -7597,14 +7618,14 @@ static Int decGetInt(const decNumber *dn) { /* ------------------------------------------------------------------ */ /* decDecap -- decapitate the coefficient of a number */ /* */ -/* dn is the number to be decapitated */ +/* dn is the number to be decapitated */ /* drop is the number of digits to be removed from the left of dn; */ -/* this must be <= dn->digits (if equal, the coefficient is */ +/* this must be <= dn->digits (if equal, the coefficient is */ /* set to 0) */ /* */ /* Returns dn; dn->digits will be <= the initial digits less drop */ -/* (after removing drop digits there may be leading zero digits */ -/* which will also be removed). Only dn->lsu and dn->digits change. */ +/* (after removing drop digits there may be leading zero digits */ +/* which will also be removed). Only dn->lsu and dn->digits change. */ /* ------------------------------------------------------------------ */ static decNumber *decDecap(decNumber *dn, Int drop) { Unit *msu; /* -> target cut point */ @@ -7704,13 +7725,13 @@ static decNumber * decNaNs(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ /* decStatus -- apply non-zero status */ /* */ -/* dn is the number to set if error */ +/* dn is the number to set if error */ /* status contains the current status (not yet in context) */ /* set is the context */ /* */ /* If the status is an error status, the number is set to a NaN, */ /* unless the error was an overflow, divide-by-zero, or underflow, */ -/* in which case the number will have already been set. */ +/* in which case the number will have already been set. */ /* */ /* The context status is then updated with the new status. Note that */ /* this may raise a signal, so control may never return from this */ @@ -7732,7 +7753,7 @@ static void decStatus(decNumber *dn, uInt status, decContext *set) { /* ------------------------------------------------------------------ */ /* decGetDigits -- count digits in a Units array */ /* */ -/* uar is the Unit array holding the number (this is often an */ +/* uar is the Unit array holding the number (this is often an */ /* accumulator of some sort) */ /* len is the length of the array in units [>=1] */ /* */ @@ -7743,7 +7764,7 @@ static void decStatus(decNumber *dn, uInt status, decContext *set) { /* ------------------------------------------------------------------ */ /* This may be called twice during some operations. */ static Int decGetDigits(Unit *uar, Int len) { - Unit *up=uar+(len-1); /* -> msu */ + Unit *up=uar+(len-1); /* -> msu */ Int digits=(len-1)*DECDPUN+1; /* possible digits excluding msu */ #if DECDPUN>4 uInt const *pow; /* work */ @@ -7763,7 +7784,7 @@ static Int decGetDigits(Unit *uar, Int len) { if (*up<10) break; /* is 1-9 */ digits++; #if DECDPUN>2 /* not done yet */ - if (*up<100) break; /* is 10-99 */ + if (*up<100) break; /* is 10-99 */ digits++; #if DECDPUN>3 /* not done yet */ if (*up<1000) break; /* is 100-999 */ @@ -7813,7 +7834,7 @@ void decNumberShow(const decNumber *dn) { } /* now carefully display the coefficient */ - up=dn->lsu+D2U(dn->digits)-1; /* msu */ + up=dn->lsu+D2U(dn->digits)-1; /* msu */ printf("%ld", (LI)*up); for (up=up-1; up>=dn->lsu; up--) { u=*up; @@ -7837,7 +7858,7 @@ void decNumberShow(const decNumber *dn) { /* ------------------------------------------------------------------ */ /* decDumpAr -- display a unit array [debug/check aid] */ /* name is a single-character tag name */ -/* ar is the array to display */ +/* ar is the array to display */ /* len is the length of the array in Units */ /* ------------------------------------------------------------------ */ static void decDumpAr(char name, const Unit *ar, Int len) { @@ -7880,7 +7901,7 @@ static void decDumpAr(char name, const Unit *ar, Int len) { /* rhs is the second (may be DECUNUSED) */ /* set is the context (may be DECUNCONT) */ /* returns 0 if both operands, and the context are clean, or 1 */ -/* otherwise (in which case the context will show an error, */ +/* otherwise (in which case the context will show an error, */ /* unless NULL). Note that res is not cleaned; caller should */ /* handle this so res=NULL case is safe. */ /* The caller is expected to abandon immediately if 1 is returned. */ @@ -7917,7 +7938,7 @@ static Flag decCheckOperands(decNumber *res, const decNumber *lhs, if (set!=DECUNCONT) decContextSetStatus(set, DEC_Invalid_operation); if (res!=DECUNRESU && res!=NULL) { decNumberZero(res); - res->bits=DECNAN; /* qNaN */ + res->bits=DECNAN; /* qNaN */ } } return bad; @@ -7933,7 +7954,7 @@ static Flag decCheckOperands(decNumber *res, const decNumber *lhs, /* ------------------------------------------------------------------ */ static Flag decCheckNumber(const decNumber *dn) { const Unit *up; /* work */ - uInt maxuint; /* .. */ + uInt maxuint; /* .. */ Int ae, d, digits; /* .. */ Int emin, emax; /* .. */ @@ -8004,7 +8025,7 @@ static Flag decCheckNumber(const decNumber *dn) { /* check the exponent. Note that input operands can have exponents */ /* which are out of the set->emin/set->emax and set->digits range */ /* (just as they can have more digits than set->digits). */ - ae=dn->exponent+dn->digits-1; /* adjusted exponent */ + ae=dn->exponent+dn->digits-1; /* adjusted exponent */ emax=DECNUMMAXE; emin=DECNUMMINE; digits=DECNUMMAXP; @@ -8060,7 +8081,7 @@ static void decCheckInexact(const decNumber *dn, decContext *set) { /* */ /* Semantics is the same as the stdlib malloc routine, but bytes */ /* allocated are accounted for globally, and corruption fences are */ -/* added before and after the 'actual' storage. */ +/* added before and after the 'actual' storage. */ /* ------------------------------------------------------------------ */ /* This routine allocates storage with an extra twelve bytes; 8 are */ /* at the start and hold: */ @@ -8070,17 +8091,16 @@ static void decCheckInexact(const decNumber *dn, decContext *set) { /* ------------------------------------------------------------------ */ static void *decMalloc(size_t n) { uInt size=n+12; /* true size */ - void *alloc; /* -> allocated storage */ - uInt *j; /* work */ - uByte *b, *b0; /* .. */ + void *alloc; /* -> allocated storage */ + uByte *b, *b0; /* work */ + uInt uiwork; /* for macros */ alloc=malloc(size); /* -> allocated storage */ - if (alloc==NULL) return NULL; /* out of strorage */ + if (alloc==NULL) return NULL; /* out of strorage */ b0=(uByte *)alloc; /* as bytes */ decAllocBytes+=n; /* account for storage */ - j=(uInt *)alloc; /* -> first four bytes */ - *j=n; /* save n */ - /* printf(" alloc ++ dAB: %ld (%d)\n", decAllocBytes, n); */ + UBFROMUI(alloc, n); /* save n */ + /* printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n); */ for (b=b0+4; b<b0+8; b++) *b=DECFENCE; for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE; return b0+8; /* -> play area */ @@ -8099,20 +8119,20 @@ static void *decMalloc(size_t n) { /* is, offset by 8). */ /* ------------------------------------------------------------------ */ static void decFree(void *alloc) { - uInt *j, n; /* pointer, original length */ + uInt n; /* original length */ uByte *b, *b0; /* work */ + uInt uiwork; /* for macros */ if (alloc==NULL) return; /* allowed; it's a nop */ b0=(uByte *)alloc; /* as bytes */ b0-=8; /* -> true start of storage */ - j=(uInt *)b0; /* -> first four bytes */ - n=*j; /* lift */ + n=UBTOUI(b0); /* lift length */ for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE) printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b, - b-b0-8, (Int)b0); + b-b0-8, (LI)b0); for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE) printf("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n", *b, - b-b0-8, (Int)b0, n); + b-b0-8, (LI)b0, (LI)n); free(b0); /* drop the storage */ decAllocBytes-=n; /* account for storage */ /* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n); */ diff --git a/libdecnumber/decNumber.h b/libdecnumber/decNumber.h index 0a9fdced8b3..72dbdaf46b3 100644 --- a/libdecnumber/decNumber.h +++ b/libdecnumber/decNumber.h @@ -46,7 +46,7 @@ #define DECNEG 0x80 /* Sign; 1=negative, 0=positive or zero */ #define DECINF 0x40 /* 1=Infinity */ #define DECNAN 0x20 /* 1=NaN */ - #define DECSNAN 0x10 /* 1=sNaN */ + #define DECSNAN 0x10 /* 1=sNaN */ /* The remaining bits are reserved; they must be 0 */ #define DECSPECIAL (DECINF|DECNAN|DECSNAN) /* any special value */ @@ -124,7 +124,7 @@ uint8_t * decNumberGetBCD(const decNumber *, uint8_t *); decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t); - /* Operators and elementary functions */ + /* Operators and elementary functions */ decNumber * decNumberAbs(decNumber *, const decNumber *, decContext *); decNumber * decNumberAdd(decNumber *, const decNumber *, const decNumber *, decContext *); decNumber * decNumberAnd(decNumber *, const decNumber *, const decNumber *, decContext *); @@ -185,7 +185,7 @@ /* Macros for testing decNumber *dn */ #define decNumberIsCanonical(dn) (1) /* All decNumbers are saintly */ - #define decNumberIsFinite(dn) (((dn)->bits&DECSPECIAL)==0) + #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) diff --git a/libdecnumber/decNumberLocal.h b/libdecnumber/decNumberLocal.h index f1568f725e1..c31b50db245 100644 --- a/libdecnumber/decNumberLocal.h +++ b/libdecnumber/decNumberLocal.h @@ -31,42 +31,48 @@ /* ------------------------------------------------------------------ */ /* decNumber package local type, tuning, and macro definitions */ /* ------------------------------------------------------------------ */ -/* This header file is included by all modules in the decNumber */ +/* This header file is included by all modules in the decNumber */ /* library, and contains local type definitions, tuning parameters, */ -/* etc. It should not need to be used by application programs. */ +/* etc. It should not need to be used by application programs. */ /* decNumber.h or one of decDouble (etc.) must be included first. */ /* ------------------------------------------------------------------ */ #if !defined(DECNUMBERLOC) #define DECNUMBERLOC - #define DECVERSION "decNumber 3.53" /* Package Version [16 max.] */ + #define DECVERSION "decNumber 3.61" /* Package Version [16 max.] */ #define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */ #include <stdlib.h> /* for abs */ #include <string.h> /* for memset, strcpy */ - #include "dconfig.h" /* for WORDS_BIGENDIAN */ /* Conditional code flag -- set this to match hardware platform */ - /* 1=little-endian, 0=big-endian */ - #if WORDS_BIGENDIAN - #define DECLITEND 0 - #else - #define DECLITEND 1 + #if !defined(DECLITEND) + #define DECLITEND 1 /* 1=little-endian, 0=big-endian */ #endif /* Conditional code flag -- set this to 1 for best performance */ + #if !defined(DECUSE64) #define DECUSE64 1 /* 1=use int64s, 0=int32 & smaller only */ + #endif /* Conditional check flags -- set these to 0 for best performance */ + #if !defined(DECCHECK) #define DECCHECK 0 /* 1 to enable robust checking */ + #endif + #if !defined(DECALLOC) #define DECALLOC 0 /* 1 to enable memory accounting */ + #endif + #if !defined(DECTRACE) #define DECTRACE 0 /* 1 to trace certain internals, etc. */ + #endif /* Tuning parameter for decNumber (arbitrary precision) module */ + #if !defined(DECBUFFER) #define DECBUFFER 36 /* Size basis for local buffers. This */ /* should be a common maximum precision */ /* rounded up to a multiple of 4; must */ /* be zero or positive. */ + #endif /* ---------------------------------------------------------------- */ /* Definitions for all modules (general-purpose) */ @@ -76,33 +82,33 @@ /* not use int or long directly. */ #define Flag uint8_t #define Byte int8_t - #define uByte uint8_t - #define Short int16_t + #define uByte uint8_t + #define Short int16_t #define uShort uint16_t #define Int int32_t #define uInt uint32_t #define Unit decNumberUnit #if DECUSE64 #define Long int64_t - #define uLong uint64_t + #define uLong uint64_t #endif /* Development-use definitions */ typedef long int LI; /* for printf arguments only */ #define DECNOINT 0 /* 1 to check no internal use of 'int' */ + /* or stdint types */ #if DECNOINT /* if these interfere with your C includes, do not set DECNOINT */ - #define int ? /* enable to ensure that plain C 'int' */ - #define long ?? /* .. or 'long' types are not used */ + #define int ? /* enable to ensure that plain C 'int' */ + #define long ?? /* .. or 'long' types are not used */ #endif /* Shared lookup tables */ extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */ extern const uInt DECPOWERS[10]; /* powers of ten table */ /* The following are included from decDPD.h */ -#include "decDPDSymbols.h" - extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */ - extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */ + extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */ + extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */ extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */ extern const uInt DPD2BINM[1024]; /* DPD -> 0-999000000 */ extern const uByte DPD2BCD8[4096]; /* DPD -> ddd + len */ @@ -111,32 +117,42 @@ /* LONGMUL32HI -- set w=(u*v)>>32, where w, u, and v are uInts */ /* (that is, sets w to be the high-order word of the 64-bit result; */ - /* the low-order word is simply u*v.) */ + /* the low-order word is simply u*v.) */ /* This version is derived from Knuth via Hacker's Delight; */ - /* it seems to optimize better than some others tried */ + /* it seems to optimize better than some others tried */ #define LONGMUL32HI(w, u, v) { \ - uInt u0, u1, v0, v1, w0, w1, w2, t; \ + uInt u0, u1, v0, v1, w0, w1, w2, t; \ u0=u & 0xffff; u1=u>>16; \ v0=v & 0xffff; v1=v>>16; \ w0=u0*v0; \ - t=u1*v0 + (w0>>16); \ + t=u1*v0 + (w0>>16); \ w1=t & 0xffff; w2=t>>16; \ w1=u0*v1 + w1; \ (w)=u1*v1 + w2 + (w1>>16);} /* ROUNDUP -- round an integer up to a multiple of n */ #define ROUNDUP(i, n) ((((i)+(n)-1)/n)*n) + #define ROUNDUP4(i) (((i)+3)&~3) /* special for n=4 */ /* ROUNDDOWN -- round an integer down to a multiple of n */ #define ROUNDDOWN(i, n) (((i)/n)*n) - #define ROUNDDOWN4(i) ((i)&~3) /* special for n=4 */ + #define ROUNDDOWN4(i) ((i)&~3) /* special for n=4 */ + + /* References to multi-byte sequences under different sizes; these */ + /* require locally declared variables, but do not violate strict */ + /* aliasing or alignment (as did the UINTAT simple cast to uInt). */ + /* Variables needed are uswork, uiwork, etc. [so do not use at same */ + /* level in an expression, e.g., UBTOUI(x)==UBTOUI(y) may fail]. */ - /* References to multi-byte sequences under different sizes */ - /* Refer to a uInt from four bytes starting at a char* or uByte*, */ - /* etc. */ - #define UINTAT(b) (*((uInt *)(b))) - #define USHORTAT(b) (*((uShort *)(b))) - #define UBYTEAT(b) (*((uByte *)(b))) + /* Return a uInt, etc., from bytes starting at a char* or uByte* */ + #define UBTOUS(b) (memcpy((void *)&uswork, b, 2), uswork) + #define UBTOUI(b) (memcpy((void *)&uiwork, b, 4), uiwork) + + /* Store a uInt, etc., into bytes starting at a char* or uByte*. */ + /* Returns i, evaluated, for convenience; has to use uiwork because */ + /* i may be an expression. */ + #define UBFROMUS(b, i) (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork) + #define UBFROMUI(b, i) (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork) /* X10 and X100 -- multiply integer i by 10 or 100 */ /* [shifts are usually faster than multiply; could be conditional] */ @@ -149,7 +165,7 @@ /* Useful constants */ #define BILLION 1000000000 /* 10**9 */ - /* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC */ + /* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC */ #define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0') @@ -172,7 +188,7 @@ #error Minimum exponent mismatch #endif - /* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN */ + /* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN */ /* digits, and D2UTABLE -- the initializer for the D2U table */ #if DECDPUN==1 #define DECDPUNMAX 9 @@ -253,7 +269,7 @@ /* D2N -- return the number of decNumber structs that would be */ /* needed to contain that number of digits (and the initial */ /* decNumber struct) safely. Note that one Unit is included in the */ - /* initial structure. Used for allocating space that is aligned on */ + /* initial structure. Used for allocating space that is aligned on */ /* a decNumber struct boundary. */ #define D2N(d) \ ((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber)) @@ -261,7 +277,7 @@ /* TODIGIT -- macro to remove the leading digit from the unsigned */ /* integer u at column cut (counting from the right, LSD=0) and */ /* place it as an ASCII character into the character pointed to by */ - /* c. Note that cut must be <= 9, and the maximum value for u is */ + /* c. Note that cut must be <= 9, and the maximum value for u is */ /* 2,000,000,000 (as is needed for negative exponents of */ /* subnormals). The unsigned integer pow is used as a temporary */ /* variable. */ @@ -274,7 +290,7 @@ pow/=2; \ if ((u)>=pow) {(u)-=pow; *(c)+=4;} \ pow/=2; \ - } \ + } \ if ((u)>=pow) {(u)-=pow; *(c)+=2;} \ pow/=2; \ if ((u)>=pow) {(u)-=pow; *(c)+=1;} \ @@ -289,9 +305,9 @@ /* number, whose coefficient is a string of bcd8 uBytes */ typedef struct { uByte *msd; /* -> most significant digit */ - uByte *lsd; /* -> least ditto */ + uByte *lsd; /* -> least ditto */ uInt sign; /* 0=positive, DECFLOAT_Sign=negative */ - Int exponent; /* Unadjusted signed exponent (q), or */ + Int exponent; /* Unadjusted signed exponent (q), or */ /* DECFLOAT_NaN etc. for a special */ } bcdnum; @@ -308,12 +324,12 @@ #define DECWORDS (DECBYTES/4) #define DECWWORDS (DECWBYTES/4) #if DECLITEND - #define DFWORD(df, off) ((df)->words[DECWORDS-1-(off)]) - #define DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)]) + #define DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)]) + #define DFWORD(df, off) ((df)->words[DECWORDS-1-(off)]) #define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)]) #else - #define DFWORD(df, off) ((df)->words[off]) - #define DFBYTE(df, off) ((df)->bytes[off]) + #define DFBYTE(df, off) ((df)->bytes[off]) + #define DFWORD(df, off) ((df)->words[off]) #define DFWWORD(dfw, off) ((dfw)->words[off]) #endif @@ -326,7 +342,6 @@ #define DFISSNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7e000000) /* Shared lookup tables */ -#include "decCommonSymbols.h" extern const uInt DECCOMBMSD[64]; /* Combination field -> MSD */ extern const uInt DECCOMBFROM[48]; /* exp+msd -> Combination */ @@ -338,7 +353,7 @@ /* Format-dependent macros and constants */ #if defined(DECPMAX) - /* Useful constants */ + /* Useful constants */ #define DECPMAX9 (ROUNDUP(DECPMAX, 9)/9) /* 'Pmax' in 10**9s */ /* Top words for a zero */ #define SINGLEZERO 0x22500000 @@ -350,10 +365,10 @@ /* DFISZERO -- test for (any) zero */ /* DFISCCZERO -- test for coefficient continuation being zero */ /* DFISCC01 -- test for coefficient contains only 0s and 1s */ - /* DFISINT -- test for finite and exponent q=0 */ + /* DFISINT -- test for finite and exponent q=0 */ /* DFISUINT01 -- test for sign=0, finite, exponent q=0, and */ /* MSD=0 or 1 */ - /* ZEROWORD is also defined here. */ + /* ZEROWORD is also defined here. */ /* In DFISZERO the first test checks the least-significant word */ /* (most likely to be non-zero); the penultimate tests MSD and */ /* DPDs in the signword, and the final test excludes specials and */ @@ -407,26 +422,36 @@ || ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k))) /* declet is at offset k (a multiple of 2) in a pair of uInts: */ /* [the top 2 bits will always be in the more-significant uInt] */ - #define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0 \ + #define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0 \ || ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k))) \ || ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k))) /* Macro to test whether a full-length (length DECPMAX) BCD8 */ - /* coefficient is zero */ - /* test just the LSWord first, then the remainder */ + /* coefficient, starting at uByte u, is all zeros */ + /* Test just the LSWord first, then the remainder as a sequence */ + /* of tests in order to avoid same-level use of UBTOUI */ #if DECPMAX==7 - #define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \ - && UINTAT((u)+DECPMAX-7)==0) + #define ISCOEFFZERO(u) ( \ + UBTOUI((u)+DECPMAX-4)==0 \ + && UBTOUS((u)+DECPMAX-6)==0 \ + && *(u)==0) #elif DECPMAX==16 - #define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \ - && (UINTAT((u)+DECPMAX-8)+UINTAT((u)+DECPMAX-12) \ - +UINTAT((u)+DECPMAX-16))==0) + #define ISCOEFFZERO(u) ( \ + UBTOUI((u)+DECPMAX-4)==0 \ + && UBTOUI((u)+DECPMAX-8)==0 \ + && UBTOUI((u)+DECPMAX-12)==0 \ + && UBTOUI(u)==0) #elif DECPMAX==34 - #define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \ - && (UINTAT((u)+DECPMAX-8) +UINTAT((u)+DECPMAX-12) \ - +UINTAT((u)+DECPMAX-16)+UINTAT((u)+DECPMAX-20) \ - +UINTAT((u)+DECPMAX-24)+UINTAT((u)+DECPMAX-28) \ - +UINTAT((u)+DECPMAX-32)+USHORTAT((u)+DECPMAX-34))==0) + #define ISCOEFFZERO(u) ( \ + UBTOUI((u)+DECPMAX-4)==0 \ + && UBTOUI((u)+DECPMAX-8)==0 \ + && UBTOUI((u)+DECPMAX-12)==0 \ + && UBTOUI((u)+DECPMAX-16)==0 \ + && UBTOUI((u)+DECPMAX-20)==0 \ + && UBTOUI((u)+DECPMAX-24)==0 \ + && UBTOUI((u)+DECPMAX-28)==0 \ + && UBTOUI((u)+DECPMAX-32)==0 \ + && UBTOUS(u)==0) #endif /* Macros and masks for the exponent continuation field and MSD */ @@ -448,29 +473,24 @@ #define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL)) /* Macros to decode the coefficient in a finite decFloat *df into */ - /* a BCD string (uByte *bcdin) of length DECPMAX uBytes */ - - /* In-line sequence to convert 10 bits at right end of uInt dpd */ - /* to three BCD8 digits starting at uByte u. Note that an extra */ - /* byte is written to the right of the three digits because this */ - /* moves four at a time for speed; the alternative macro moves */ - /* exactly three bytes */ - #define dpd2bcd8(u, dpd) { \ - UINTAT(u)=UINTAT(&DPD2BCD8[((dpd)&0x3ff)*4]);} + /* a BCD string (uByte *bcdin) of length DECPMAX uBytes. */ - #define dpd2bcd83(u, dpd) { \ - *(u)=DPD2BCD8[((dpd)&0x3ff)*4]; \ - *(u+1)=DPD2BCD8[((dpd)&0x3ff)*4+1]; \ - *(u+2)=DPD2BCD8[((dpd)&0x3ff)*4+2];} + /* In-line sequence to convert least significant 10 bits of uInt */ + /* dpd to three BCD8 digits starting at uByte u. Note that an */ + /* extra byte is written to the right of the three digits because */ + /* four bytes are moved at a time for speed; the alternative */ + /* macro moves exactly three bytes (usually slower). */ + #define dpd2bcd8(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 4) + #define dpd2bcd83(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 3) /* Decode the declets. After extracting each one, it is decoded */ /* to BCD8 using a table lookup (also used for variable-length */ - /* decode). Each DPD decode is 3 bytes BCD8 plus a one-byte */ - /* length which is not used, here). Fixed-length 4-byte moves */ + /* decode). Each DPD decode is 3 bytes BCD8 plus a one-byte */ + /* length which is not used, here). Fixed-length 4-byte moves */ /* are fast, however, almost everywhere, and so are used except */ /* for the final three bytes (to avoid overrun). The code below */ /* is 36 instructions for Doubles and about 70 for Quads, even */ - /* on IA32. */ + /* on IA32. */ /* Two macros are defined for each format: */ /* GETCOEFF extracts the coefficient of the current format */ @@ -478,7 +498,7 @@ /* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */ #if DECPMAX==7 - #define GETCOEFF(df, bcd) { \ + #define GETCOEFF(df, bcd) { \ uInt sourhi=DFWORD(df, 0); \ *(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \ dpd2bcd8(bcd+1, sourhi>>10); \ @@ -494,7 +514,7 @@ dpd2bcd83(bcd+13, sourlo);} #elif DECPMAX==16 - #define GETCOEFF(df, bcd) { \ + #define GETCOEFF(df, bcd) { \ uInt sourhi=DFWORD(df, 0); \ uInt sourlo=DFWORD(df, 1); \ *(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \ @@ -522,7 +542,7 @@ dpd2bcd83(bcd+31, sourlo);} #elif DECPMAX==34 - #define GETCOEFF(df, bcd) { \ + #define GETCOEFF(df, bcd) { \ uInt sourhi=DFWORD(df, 0); \ uInt sourmh=DFWORD(df, 1); \ uInt sourml=DFWORD(df, 2); \ @@ -540,12 +560,12 @@ dpd2bcd8(bcd+28, sourlo>>10); \ dpd2bcd83(bcd+31, sourlo);} - #define GETWCOEFF(df, bcd) {??} /* [should never be used] */ + #define GETWCOEFF(df, bcd) {??} /* [should never be used] */ #endif /* Macros to decode the coefficient in a finite decFloat *df into */ /* a base-billion uInt array, with the least-significant */ - /* 0-999999999 'digit' at offset 0. */ + /* 0-999999999 'digit' at offset 0. */ /* Decode the declets. After extracting each one, it is decoded */ /* to binary using a table lookup. Three tables are used; one */ @@ -597,8 +617,8 @@ #endif /* Macros to decode the coefficient in a finite decFloat *df into */ - /* a base-thousand uInt array, with the least-significant 0-999 */ - /* 'digit' at offset 0. */ + /* a base-thousand uInt array (of size DECLETS+1, to allow for */ + /* the MSD), with the least-significant 0-999 'digit' at offset 0.*/ /* Decode the declets. After extracting each one, it is decoded */ /* to binary using a table lookup. */ @@ -640,9 +660,72 @@ (buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \ (buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff]; \ (buf)[11]=DECCOMBMSD[sourhi>>26];} + #endif + + + /* Macros to decode the coefficient in a finite decFloat *df and */ + /* add to a base-thousand uInt array (as for GETCOEFFTHOU). */ + /* After the addition then most significant 'digit' in the array */ + /* might have a value larger then 10 (with a maximum of 19). */ + #if DECPMAX==7 + #define ADDCOEFFTHOU(df, buf) { \ + uInt sourhi=DFWORD(df, 0); \ + (buf)[0]+=DPD2BIN[sourhi&0x3ff]; \ + if (buf[0]>999) {buf[0]-=1000; buf[1]++;} \ + (buf)[1]+=DPD2BIN[(sourhi>>10)&0x3ff]; \ + if (buf[1]>999) {buf[1]-=1000; buf[2]++;} \ + (buf)[2]+=DECCOMBMSD[sourhi>>26];} + #elif DECPMAX==16 + #define ADDCOEFFTHOU(df, buf) { \ + uInt sourhi, sourlo; \ + sourlo=DFWORD(df, 1); \ + (buf)[0]+=DPD2BIN[sourlo&0x3ff]; \ + if (buf[0]>999) {buf[0]-=1000; buf[1]++;} \ + (buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff]; \ + if (buf[1]>999) {buf[1]-=1000; buf[2]++;} \ + (buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff]; \ + if (buf[2]>999) {buf[2]-=1000; buf[3]++;} \ + sourhi=DFWORD(df, 0); \ + (buf)[3]+=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff]; \ + if (buf[3]>999) {buf[3]-=1000; buf[4]++;} \ + (buf)[4]+=DPD2BIN[(sourhi>>8)&0x3ff]; \ + if (buf[4]>999) {buf[4]-=1000; buf[5]++;} \ + (buf)[5]+=DECCOMBMSD[sourhi>>26];} + + #elif DECPMAX==34 + #define ADDCOEFFTHOU(df, buf) { \ + uInt sourhi, sourmh, sourml, sourlo; \ + sourlo=DFWORD(df, 3); \ + (buf)[0]+=DPD2BIN[sourlo&0x3ff]; \ + if (buf[0]>999) {buf[0]-=1000; buf[1]++;} \ + (buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff]; \ + if (buf[1]>999) {buf[1]-=1000; buf[2]++;} \ + (buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff]; \ + if (buf[2]>999) {buf[2]-=1000; buf[3]++;} \ + sourml=DFWORD(df, 2); \ + (buf)[3]+=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff]; \ + if (buf[3]>999) {buf[3]-=1000; buf[4]++;} \ + (buf)[4]+=DPD2BIN[(sourml>>8)&0x3ff]; \ + if (buf[4]>999) {buf[4]-=1000; buf[5]++;} \ + (buf)[5]+=DPD2BIN[(sourml>>18)&0x3ff]; \ + if (buf[5]>999) {buf[5]-=1000; buf[6]++;} \ + sourmh=DFWORD(df, 1); \ + (buf)[6]+=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff]; \ + if (buf[6]>999) {buf[6]-=1000; buf[7]++;} \ + (buf)[7]+=DPD2BIN[(sourmh>>6)&0x3ff]; \ + if (buf[7]>999) {buf[7]-=1000; buf[8]++;} \ + (buf)[8]+=DPD2BIN[(sourmh>>16)&0x3ff]; \ + if (buf[8]>999) {buf[8]-=1000; buf[9]++;} \ + sourhi=DFWORD(df, 0); \ + (buf)[9]+=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \ + if (buf[9]>999) {buf[9]-=1000; buf[10]++;} \ + (buf)[10]+=DPD2BIN[(sourhi>>4)&0x3ff]; \ + if (buf[10]>999) {buf[10]-=1000; buf[11]++;} \ + (buf)[11]+=DECCOMBMSD[sourhi>>26];} #endif + /* Set a decFloat to the maximum positive finite number (Nmax) */ #if DECPMAX==7 #define DFSETNMAX(df) \ diff --git a/libdecnumber/decPacked.c b/libdecnumber/decPacked.c index 2b912fe13bc..2297d7d6e7d 100644 --- a/libdecnumber/decPacked.c +++ b/libdecnumber/decPacked.c @@ -31,12 +31,12 @@ /* ------------------------------------------------------------------ */ /* Packed Decimal conversion module */ /* ------------------------------------------------------------------ */ -/* This module comprises the routines for Packed Decimal format */ +/* This module comprises the routines for Packed Decimal format */ /* numbers. Conversions are supplied to and from decNumber, which in */ /* turn supports: */ /* conversions to and from string */ /* arithmetic routines */ -/* utilities. */ +/* utilities. */ /* Conversions from decNumber to and from densely packed decimal */ /* formats are provided by the decimal32 through decimal128 modules. */ /* ------------------------------------------------------------------ */ @@ -51,8 +51,8 @@ /* */ /* bcd is the BCD bytes */ /* length is the length of the BCD array */ -/* scale is the scale result */ -/* dn is the decNumber */ +/* scale is the scale result */ +/* dn is the decNumber */ /* returns bcd, or NULL if error */ /* */ /* The number is converted to a BCD packed decimal byte array, */ @@ -67,7 +67,7 @@ /* as necessary. */ /* */ /* If there is an error (that is, the decNumber has too many digits */ -/* to fit in length bytes, or it is a NaN or Infinity), NULL is */ +/* to fit in length bytes, or it is a NaN or Infinity), NULL is */ /* returned and the bcd and scale results are unchanged. Otherwise */ /* bcd is returned. */ /* ------------------------------------------------------------------ */ @@ -86,9 +86,9 @@ uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale, if (dn->digits>length*2-1 /* too long .. */ ||(dn->bits & DECSPECIAL)) return NULL; /* .. or special -- hopeless */ - if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */ - else obyte=DECPPLUS; - *scale=-dn->exponent; /* .. and scale */ + if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */ + else obyte=DECPPLUS; + *scale=-dn->exponent; /* .. and scale */ /* loop from lowest (rightmost) byte */ out=bcd+length-1; /* -> final byte */ @@ -141,7 +141,7 @@ uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale, /* bcd is the BCD bytes */ /* length is the length of the BCD array */ /* scale is the scale associated with the BCD integer */ -/* dn is the decNumber [with space for length*2 digits] */ +/* dn is the decNumber [with space for length*2 digits] */ /* returns dn, or NULL if error */ /* */ /* The BCD packed decimal byte array, together with an associated */ @@ -157,7 +157,7 @@ uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale, /* no error is possible unless the adjusted exponent is out of range, */ /* no sign nibble was found, or a sign nibble was found before the */ /* final nibble. In these error cases, NULL is returned and the */ -/* decNumber will be 0. */ +/* decNumber will be 0. */ /* ------------------------------------------------------------------ */ decNumber * decPackedToNumber(const uByte *bcd, Int length, const Int *scale, decNumber *dn) { @@ -165,7 +165,7 @@ decNumber * decPackedToNumber(const uByte *bcd, Int length, const uByte *first; /* -> first non-zero byte */ uInt nib; /* work nibble */ Unit *up=dn->lsu; /* output pointer */ - Int digits; /* digits count */ + Int digits; /* digits count */ Int cut=0; /* phase of output */ decNumberZero(dn); /* default result */ @@ -182,7 +182,7 @@ decNumber * decPackedToNumber(const uByte *bcd, Int length, /* leave as 1] */ /* check the adjusted exponent; note that scale could be unbounded */ - dn->exponent=-*scale; /* set the exponent */ + dn->exponent=-*scale; /* set the exponent */ if (*scale>=0) { /* usual case */ if ((dn->digits-*scale-1)<-DECNUMMAXE) { /* underflow */ decNumberZero(dn); diff --git a/libdecnumber/decPacked.h b/libdecnumber/decPacked.h index c76aa09631e..04fcf53dfc5 100644 --- a/libdecnumber/decPacked.h +++ b/libdecnumber/decPacked.h @@ -36,7 +36,7 @@ #define DECPACKED #define DECPNAME "decPacked" /* Short name */ #define DECPFULLNAME "Packed Decimal conversions" /* Verbose name */ - #define DECPAUTHOR "Mike Cowlishaw" /* Who to blame */ + #define DECPAUTHOR "Mike Cowlishaw" /* Who to blame */ #define DECPACKED_DefP 32 /* default precision */ @@ -47,12 +47,12 @@ /* Sign nibble constants */ #if !defined(DECPPLUSALT) - #define DECPPLUSALT 0x0A /* alternate plus nibble */ - #define DECPMINUSALT 0x0B /* alternate minus nibble */ - #define DECPPLUS 0x0C /* preferred plus nibble */ - #define DECPMINUS 0x0D /* preferred minus nibble */ - #define DECPPLUSALT2 0x0E /* alternate plus nibble */ - #define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */ + #define DECPPLUSALT 0x0A /* alternate plus nibble */ + #define DECPMINUSALT 0x0B /* alternate minus nibble */ + #define DECPPLUS 0x0C /* preferred plus nibble */ + #define DECPMINUS 0x0D /* preferred minus nibble */ + #define DECPPLUSALT2 0x0E /* alternate plus nibble */ + #define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */ #endif /* ---------------------------------------------------------------- */ diff --git a/libdecnumber/decQuad.c b/libdecnumber/decQuad.c index 6ec9b7f735f..a8eb9050ddc 100644 --- a/libdecnumber/decQuad.c +++ b/libdecnumber/decQuad.c @@ -34,111 +34,111 @@ /* This module comprises decQuad operations (including conversions) */ /* ------------------------------------------------------------------ */ -#include "decContext.h" /* public includes */ +#include "decContext.h" /* public includes */ #include "decQuad.h" /* .. */ /* Constant mappings for shared code */ -#define DECPMAX DECQUAD_Pmax -#define DECEMIN DECQUAD_Emin -#define DECEMAX DECQUAD_Emax +#define DECPMAX DECQUAD_Pmax +#define DECEMIN DECQUAD_Emin +#define DECEMAX DECQUAD_Emax #define DECEMAXD DECQUAD_EmaxD #define DECBYTES DECQUAD_Bytes #define DECSTRING DECQUAD_String #define DECECONL DECQUAD_EconL -#define DECBIAS DECQUAD_Bias -#define DECLETS DECQUAD_Declets +#define DECBIAS DECQUAD_Bias +#define DECLETS DECQUAD_Declets #define DECQTINY (-DECQUAD_Bias) /* Type and function mappings for shared code */ -#define decFloat decQuad /* Type name */ +#define decFloat decQuad /* Type name */ /* Utilities and conversions (binary results, extractors, etc.) */ -#define decFloatFromBCD decQuadFromBCD -#define decFloatFromInt32 decQuadFromInt32 -#define decFloatFromPacked decQuadFromPacked -#define decFloatFromString decQuadFromString -#define decFloatFromUInt32 decQuadFromUInt32 -#define decFloatFromWider decQuadFromWider -#define decFloatGetCoefficient decQuadGetCoefficient -#define decFloatGetExponent decQuadGetExponent -#define decFloatSetCoefficient decQuadSetCoefficient -#define decFloatSetExponent decQuadSetExponent -#define decFloatShow decQuadShow -#define decFloatToBCD decQuadToBCD -#define decFloatToEngString decQuadToEngString -#define decFloatToInt32 decQuadToInt32 -#define decFloatToInt32Exact decQuadToInt32Exact -#define decFloatToPacked decQuadToPacked -#define decFloatToString decQuadToString -#define decFloatToUInt32 decQuadToUInt32 -#define decFloatToUInt32Exact decQuadToUInt32Exact -#define decFloatToWider decQuadToWider -#define decFloatZero decQuadZero +#define decFloatFromBCD decQuadFromBCD +#define decFloatFromInt32 decQuadFromInt32 +#define decFloatFromPacked decQuadFromPacked +#define decFloatFromPackedChecked decQuadFromPackedChecked +#define decFloatFromString decQuadFromString +#define decFloatFromUInt32 decQuadFromUInt32 +#define decFloatFromWider decQuadFromWider +#define decFloatGetCoefficient decQuadGetCoefficient +#define decFloatGetExponent decQuadGetExponent +#define decFloatSetCoefficient decQuadSetCoefficient +#define decFloatSetExponent decQuadSetExponent +#define decFloatShow decQuadShow +#define decFloatToBCD decQuadToBCD +#define decFloatToEngString decQuadToEngString +#define decFloatToInt32 decQuadToInt32 +#define decFloatToInt32Exact decQuadToInt32Exact +#define decFloatToPacked decQuadToPacked +#define decFloatToString decQuadToString +#define decFloatToUInt32 decQuadToUInt32 +#define decFloatToUInt32Exact decQuadToUInt32Exact +#define decFloatToWider decQuadToWider +#define decFloatZero decQuadZero /* Computational (result is a decFloat) */ -#define decFloatAbs decQuadAbs -#define decFloatAdd decQuadAdd -#define decFloatAnd decQuadAnd -#define decFloatDivide decQuadDivide -#define decFloatDivideInteger decQuadDivideInteger -#define decFloatFMA decQuadFMA -#define decFloatInvert decQuadInvert -#define decFloatLogB decQuadLogB -#define decFloatMax decQuadMax -#define decFloatMaxMag decQuadMaxMag -#define decFloatMin decQuadMin -#define decFloatMinMag decQuadMinMag -#define decFloatMinus decQuadMinus -#define decFloatMultiply decQuadMultiply -#define decFloatNextMinus decQuadNextMinus -#define decFloatNextPlus decQuadNextPlus -#define decFloatNextToward decQuadNextToward -#define decFloatOr decQuadOr -#define decFloatPlus decQuadPlus -#define decFloatQuantize decQuadQuantize -#define decFloatReduce decQuadReduce -#define decFloatRemainder decQuadRemainder -#define decFloatRemainderNear decQuadRemainderNear -#define decFloatRotate decQuadRotate -#define decFloatScaleB decQuadScaleB -#define decFloatShift decQuadShift -#define decFloatSubtract decQuadSubtract -#define decFloatToIntegralValue decQuadToIntegralValue -#define decFloatToIntegralExact decQuadToIntegralExact -#define decFloatXor decQuadXor +#define decFloatAbs decQuadAbs +#define decFloatAdd decQuadAdd +#define decFloatAnd decQuadAnd +#define decFloatDivide decQuadDivide +#define decFloatDivideInteger decQuadDivideInteger +#define decFloatFMA decQuadFMA +#define decFloatInvert decQuadInvert +#define decFloatLogB decQuadLogB +#define decFloatMax decQuadMax +#define decFloatMaxMag decQuadMaxMag +#define decFloatMin decQuadMin +#define decFloatMinMag decQuadMinMag +#define decFloatMinus decQuadMinus +#define decFloatMultiply decQuadMultiply +#define decFloatNextMinus decQuadNextMinus +#define decFloatNextPlus decQuadNextPlus +#define decFloatNextToward decQuadNextToward +#define decFloatOr decQuadOr +#define decFloatPlus decQuadPlus +#define decFloatQuantize decQuadQuantize +#define decFloatReduce decQuadReduce +#define decFloatRemainder decQuadRemainder +#define decFloatRemainderNear decQuadRemainderNear +#define decFloatRotate decQuadRotate +#define decFloatScaleB decQuadScaleB +#define decFloatShift decQuadShift +#define decFloatSubtract decQuadSubtract +#define decFloatToIntegralValue decQuadToIntegralValue +#define decFloatToIntegralExact decQuadToIntegralExact +#define decFloatXor decQuadXor /* Comparisons */ -#define decFloatCompare decQuadCompare -#define decFloatCompareSignal decQuadCompareSignal -#define decFloatCompareTotal decQuadCompareTotal -#define decFloatCompareTotalMag decQuadCompareTotalMag +#define decFloatCompare decQuadCompare +#define decFloatCompareSignal decQuadCompareSignal +#define decFloatCompareTotal decQuadCompareTotal +#define decFloatCompareTotalMag decQuadCompareTotalMag /* Copies */ -#define decFloatCanonical decQuadCanonical -#define decFloatCopy decQuadCopy -#define decFloatCopyAbs decQuadCopyAbs -#define decFloatCopyNegate decQuadCopyNegate -#define decFloatCopySign decQuadCopySign +#define decFloatCanonical decQuadCanonical +#define decFloatCopy decQuadCopy +#define decFloatCopyAbs decQuadCopyAbs +#define decFloatCopyNegate decQuadCopyNegate +#define decFloatCopySign decQuadCopySign /* Non-computational */ -#define decFloatClass decQuadClass -#define decFloatClassString decQuadClassString -#define decFloatDigits decQuadDigits -#define decFloatIsCanonical decQuadIsCanonical -#define decFloatIsFinite decQuadIsFinite -#define decFloatIsInfinite decQuadIsInfinite -#define decFloatIsInteger decQuadIsInteger -#define decFloatIsNaN decQuadIsNaN -#define decFloatIsNormal decQuadIsNormal -#define decFloatIsSignaling decQuadIsSignaling -#define decFloatIsSignalling decQuadIsSignalling -#define decFloatIsSigned decQuadIsSigned -#define decFloatIsSubnormal decQuadIsSubnormal -#define decFloatIsZero decQuadIsZero -#define decFloatRadix decQuadRadix -#define decFloatSameQuantum decQuadSameQuantum -#define decFloatVersion decQuadVersion - +#define decFloatClass decQuadClass +#define decFloatClassString decQuadClassString +#define decFloatDigits decQuadDigits +#define decFloatIsCanonical decQuadIsCanonical +#define decFloatIsFinite decQuadIsFinite +#define decFloatIsInfinite decQuadIsInfinite +#define decFloatIsInteger decQuadIsInteger +#define decFloatIsNaN decQuadIsNaN +#define decFloatIsNormal decQuadIsNormal +#define decFloatIsSignaling decQuadIsSignaling +#define decFloatIsSignalling decQuadIsSignalling +#define decFloatIsSigned decQuadIsSigned +#define decFloatIsSubnormal decQuadIsSubnormal +#define decFloatIsZero decQuadIsZero +#define decFloatRadix decQuadRadix +#define decFloatSameQuantum decQuadSameQuantum +#define decFloatVersion decQuadVersion #include "decNumberLocal.h" /* local includes (need DECPMAX) */ #include "decCommon.c" /* non-arithmetic decFloat routines */ diff --git a/libdecnumber/decQuad.h b/libdecnumber/decQuad.h index af9bc24e265..80f5eef4958 100644 --- a/libdecnumber/decQuad.h +++ b/libdecnumber/decQuad.h @@ -31,27 +31,25 @@ /* ------------------------------------------------------------------ */ /* decQuad.h -- Decimal 128-bit format module header */ /* ------------------------------------------------------------------ */ -/* Please see decFloats.h for an overview and documentation details. */ -/* ------------------------------------------------------------------ */ /* This include file is always included by decSingle and decDouble, */ -/* and therefore also holds useful constants used by all three. */ +/* and therefore also holds useful constants used by all three. */ #if !defined(DECQUAD) #define DECQUAD #define DECQUADNAME "decimalQuad" /* Short name */ #define DECQUADTITLE "Decimal 128-bit datum" /* Verbose name */ - #define DECQUADAUTHOR "Mike Cowlishaw" /* Who to blame */ + #define DECQUADAUTHOR "Mike Cowlishaw" /* Who to blame */ /* parameters for decQuads */ - #define DECQUAD_Bytes 16 /* length */ + #define DECQUAD_Bytes 16 /* length */ #define DECQUAD_Pmax 34 /* maximum precision (digits) */ - #define DECQUAD_Emin -6143 /* minimum adjusted exponent */ - #define DECQUAD_Emax 6144 /* maximum adjusted exponent */ - #define DECQUAD_EmaxD 4 /* maximum exponent digits */ + #define DECQUAD_Emin -6143 /* minimum adjusted exponent */ + #define DECQUAD_Emax 6144 /* maximum adjusted exponent */ + #define DECQUAD_EmaxD 4 /* maximum exponent digits */ #define DECQUAD_Bias 6176 /* bias for the exponent */ - #define DECQUAD_String 43 /* maximum string length, +1 */ - #define DECQUAD_EconL 12 /* exponent continuation length */ + #define DECQUAD_String 43 /* maximum string length, +1 */ + #define DECQUAD_EconL 12 /* exponent continuation length */ #define DECQUAD_Declets 11 /* count of declets */ /* highest biased exponent (Elimit-1) */ #define DECQUAD_Ehigh (DECQUAD_Emax + DECQUAD_Bias - (DECQUAD_Pmax-1)) @@ -59,11 +57,14 @@ /* Required include */ #include "decContext.h" - /* The decQuad decimal 128-bit type, accessible by various types */ + /* The decQuad decimal 128-bit type, accessible by all sizes */ typedef union { - uint8_t bytes[DECQUAD_Bytes]; /* fields: 1, 5, 12, 110 bits */ + uint8_t bytes[DECQUAD_Bytes]; /* fields: 1, 5, 12, 110 bits */ uint16_t shorts[DECQUAD_Bytes/2]; - uint32_t words[DECQUAD_Bytes/4]; + uint32_t words[DECQUAD_Bytes/4]; + #if DECUSE64 + uint64_t longs[DECQUAD_Bytes/8]; + #endif } decQuad; /* ---------------------------------------------------------------- */ @@ -72,21 +73,21 @@ /* sign and special values [top 32-bits; last two bits are don't-care for Infinity on input, last bit don't-care for NaNs] */ - #define DECFLOAT_Sign 0x80000000 /* 1 00000 00 Sign */ + #define DECFLOAT_Sign 0x80000000 /* 1 00000 00 Sign */ #define DECFLOAT_NaN 0x7c000000 /* 0 11111 00 NaN generic */ - #define DECFLOAT_qNaN 0x7c000000 /* 0 11111 00 qNaN */ - #define DECFLOAT_sNaN 0x7e000000 /* 0 11111 10 sNaN */ + #define DECFLOAT_qNaN 0x7c000000 /* 0 11111 00 qNaN */ + #define DECFLOAT_sNaN 0x7e000000 /* 0 11111 10 sNaN */ #define DECFLOAT_Inf 0x78000000 /* 0 11110 00 Infinity */ #define DECFLOAT_MinSp 0x78000000 /* minimum special value */ /* [specials are all >=MinSp] */ /* Sign nibble constants */ #if !defined(DECPPLUSALT) - #define DECPPLUSALT 0x0A /* alternate plus nibble */ - #define DECPMINUSALT 0x0B /* alternate minus nibble */ - #define DECPPLUS 0x0C /* preferred plus nibble */ - #define DECPMINUS 0x0D /* preferred minus nibble */ - #define DECPPLUSALT2 0x0E /* alternate plus nibble */ - #define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */ + #define DECPPLUSALT 0x0A /* alternate plus nibble */ + #define DECPMINUSALT 0x0B /* alternate minus nibble */ + #define DECPPLUS 0x0C /* preferred plus nibble */ + #define DECPMINUS 0x0D /* preferred minus nibble */ + #define DECPPLUSALT2 0x0E /* alternate plus nibble */ + #define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */ #endif /* ---------------------------------------------------------------- */ @@ -99,6 +100,7 @@ extern decQuad * decQuadFromBCD(decQuad *, int32_t, const uint8_t *, int32_t); extern decQuad * decQuadFromInt32(decQuad *, int32_t); extern decQuad * decQuadFromPacked(decQuad *, int32_t, const uint8_t *); + extern decQuad * decQuadFromPackedChecked(decQuad *, int32_t, const uint8_t *); extern decQuad * decQuadFromString(decQuad *, const char *, decContext *); extern decQuad * decQuadFromUInt32(decQuad *, uint32_t); extern int32_t decQuadGetCoefficient(const decQuad *, uint8_t *); @@ -182,7 +184,8 @@ /* decNumber conversions; these are implemented as macros so as not */ /* to force a dependency on decimal128 and decNumber in decQuad. */ + /* decQuadFromNumber returns a decimal128 * to avoid warnings. */ #define decQuadToNumber(dq, dn) decimal128ToNumber((decimal128 *)(dq), dn) - #define decQuadFromNumber(dq, dn, set) (decQuad *)decimal128FromNumber((decimal128 *)(dq), dn, set) + #define decQuadFromNumber(dq, dn, set) decimal128FromNumber((decimal128 *)(dq), dn, set) #endif diff --git a/libdecnumber/decSingle.c b/libdecnumber/decSingle.c index 112395970fe..1c56c65806e 100644 --- a/libdecnumber/decSingle.c +++ b/libdecnumber/decSingle.c @@ -31,22 +31,20 @@ /* ------------------------------------------------------------------ */ /* decSingle.c -- decSingle operations module */ /* ------------------------------------------------------------------ */ -/* This module comprises decSingle operations (including conversions) */ -/* ------------------------------------------------------------------ */ -#include "decContext.h" /* public includes */ +#include "decContext.h" /* public includes */ #include "decSingle.h" /* public includes */ /* Constant mappings for shared code */ -#define DECPMAX DECSINGLE_Pmax -#define DECEMIN DECSINGLE_Emin -#define DECEMAX DECSINGLE_Emax +#define DECPMAX DECSINGLE_Pmax +#define DECEMIN DECSINGLE_Emin +#define DECEMAX DECSINGLE_Emax #define DECEMAXD DECSINGLE_EmaxD #define DECBYTES DECSINGLE_Bytes #define DECSTRING DECSINGLE_String #define DECECONL DECSINGLE_EconL -#define DECBIAS DECSINGLE_Bias -#define DECLETS DECSINGLE_Declets +#define DECBIAS DECSINGLE_Bias +#define DECLETS DECSINGLE_Declets #define DECQTINY (-DECSINGLE_Bias) /* parameters of next-wider format */ #define DECWBYTES DECDOUBLE_Bytes @@ -55,29 +53,30 @@ #define DECWBIAS DECDOUBLE_Bias /* Type and function mappings for shared code */ -#define decFloat decSingle /* Type name */ -#define decFloatWider decDouble /* Type name */ +#define decFloat decSingle /* Type name */ +#define decFloatWider decDouble /* Type name */ /* Utility (binary results, extractors, etc.) */ -#define decFloatFromBCD decSingleFromBCD -#define decFloatFromPacked decSingleFromPacked -#define decFloatFromString decSingleFromString -#define decFloatFromWider decSingleFromWider -#define decFloatGetCoefficient decSingleGetCoefficient -#define decFloatGetExponent decSingleGetExponent -#define decFloatSetCoefficient decSingleSetCoefficient -#define decFloatSetExponent decSingleSetExponent -#define decFloatShow decSingleShow -#define decFloatToBCD decSingleToBCD -#define decFloatToEngString decSingleToEngString -#define decFloatToPacked decSingleToPacked -#define decFloatToString decSingleToString -#define decFloatToWider decSingleToWider -#define decFloatZero decSingleZero +#define decFloatFromBCD decSingleFromBCD +#define decFloatFromPacked decSingleFromPacked +#define decFloatFromPackedChecked decSingleFromPackedChecked +#define decFloatFromString decSingleFromString +#define decFloatFromWider decSingleFromWider +#define decFloatGetCoefficient decSingleGetCoefficient +#define decFloatGetExponent decSingleGetExponent +#define decFloatSetCoefficient decSingleSetCoefficient +#define decFloatSetExponent decSingleSetExponent +#define decFloatShow decSingleShow +#define decFloatToBCD decSingleToBCD +#define decFloatToEngString decSingleToEngString +#define decFloatToPacked decSingleToPacked +#define decFloatToString decSingleToString +#define decFloatToWider decSingleToWider +#define decFloatZero decSingleZero /* Non-computational */ -#define decFloatRadix decSingleRadix -#define decFloatVersion decSingleVersion +#define decFloatRadix decSingleRadix +#define decFloatVersion decSingleVersion #include "decNumberLocal.h" /* local includes (need DECPMAX) */ #include "decCommon.c" /* non-basic decFloat routines */ diff --git a/libdecnumber/decSingle.h b/libdecnumber/decSingle.h index bae39848eed..29efe438e9b 100644 --- a/libdecnumber/decSingle.h +++ b/libdecnumber/decSingle.h @@ -31,24 +31,22 @@ /* ------------------------------------------------------------------ */ /* decSingle.h -- Decimal 32-bit format module header */ /* ------------------------------------------------------------------ */ -/* Please see decFloats.h for an overview and documentation details. */ -/* ------------------------------------------------------------------ */ #if !defined(DECSINGLE) #define DECSINGLE - #define DECSINGLENAME "decSingle" /* Short name */ + #define DECSINGLENAME "decSingle" /* Short name */ #define DECSINGLETITLE "Decimal 32-bit datum" /* Verbose name */ #define DECSINGLEAUTHOR "Mike Cowlishaw" /* Who to blame */ /* parameters for decSingles */ #define DECSINGLE_Bytes 4 /* length */ #define DECSINGLE_Pmax 7 /* maximum precision (digits) */ - #define DECSINGLE_Emin -95 /* minimum adjusted exponent */ - #define DECSINGLE_Emax 96 /* maximum adjusted exponent */ + #define DECSINGLE_Emin -95 /* minimum adjusted exponent */ + #define DECSINGLE_Emax 96 /* maximum adjusted exponent */ #define DECSINGLE_EmaxD 3 /* maximum exponent digits */ #define DECSINGLE_Bias 101 /* bias for the exponent */ - #define DECSINGLE_String 16 /* maximum string length, +1 */ + #define DECSINGLE_String 16 /* maximum string length, +1 */ #define DECSINGLE_EconL 6 /* exponent continuation length */ #define DECSINGLE_Declets 2 /* count of declets */ /* highest biased exponent (Elimit-1) */ @@ -59,11 +57,11 @@ #include "decQuad.h" #include "decDouble.h" - /* The decSingle decimal 32-bit type, accessible by various types */ + /* The decSingle decimal 32-bit type, accessible by all sizes */ typedef union { - uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */ + uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */ uint16_t shorts[DECSINGLE_Bytes/2]; - uint32_t words[DECSINGLE_Bytes/4]; + uint32_t words[DECSINGLE_Bytes/4]; } decSingle; /* ---------------------------------------------------------------- */ @@ -75,6 +73,7 @@ /* Utilities (binary argument(s) or result, extractors, etc.) */ extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t); extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_t *); + extern decSingle * decSingleFromPackedChecked(decSingle *, int32_t, const uint8_t *); extern decSingle * decSingleFromString(decSingle *, const char *, decContext *); extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *); extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *); @@ -97,7 +96,8 @@ /* decNumber conversions; these are implemented as macros so as not */ /* to force a dependency on decimal32 and decNumber in decSingle. */ + /* decSingleFromNumber returns a decimal32 * to avoid warnings. */ #define decSingleToNumber(dq, dn) decimal32ToNumber((decimal32 *)(dq), dn) - #define decSingleFromNumber(dq, dn, set) (decSingle *)decimal32FromNumber((decimal32 *)(dq), dn, set) + #define decSingleFromNumber(dq, dn, set) decimal32FromNumber((decimal32 *)(dq), dn, set) #endif diff --git a/libdecnumber/dpd/decimal128.c b/libdecnumber/dpd/decimal128.c index 54191aab5c0..edf22e1c8d5 100644 --- a/libdecnumber/dpd/decimal128.c +++ b/libdecnumber/dpd/decimal128.c @@ -42,11 +42,11 @@ #include <string.h> /* [for memset/memcpy] */ #include <stdio.h> /* [for printf] */ -#include "dconfig.h" /* GCC definitions */ -#define DECNUMDIGITS 34 /* make decNumbers with space for 34 */ +#include "dconfig.h" /* GCC definitions */ +#define DECNUMDIGITS 34 /* make decNumbers with space for 34 */ #include "decNumber.h" /* base number library */ #include "decNumberLocal.h" /* decNumber local types, etc. */ -#include "decimal128.h" /* our primary include */ +#include "decimal128.h" /* our primary include */ /* Utility routines and tables [in decimal64.c] */ extern const uInt COMBEXP[32], COMBMSD[32]; @@ -71,7 +71,7 @@ extern void decNumberShow(const decNumber *); /* .. */ /* */ /* ds is the target decimal128 */ /* dn is the source number (assumed valid) */ -/* set is the context, used only for reporting errors */ +/* set is the context, used only for reporting errors */ /* */ /* The set argument is used only for status reporting and for the */ /* rounding mode (used if the coefficient is more than DECIMAL128_Pmax*/ @@ -89,8 +89,8 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn, Int ae; /* adjusted exponent */ decNumber dw; /* work */ decContext dc; /* .. */ - uInt *pu; /* .. */ uInt comb, exp; /* .. */ + uInt uiwork; /* for macros */ uInt targar[4]={0,0,0,0}; /* target 128-bit */ #define targhi targar[3] /* name the word with the sign */ #define targmh targar[2] /* name the words */ @@ -102,7 +102,7 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn, /* constraints. This could push the number to Infinity or zero, */ /* so this check and rounding must be done before generating the */ /* decimal128] */ - ae=dn->exponent+dn->digits-1; /* [0 if special] */ + ae=dn->exponent+dn->digits-1; /* [0 if special] */ if (dn->digits>DECIMAL128_Pmax /* too many digits */ || ae>DECIMAL128_Emax /* likely overflow */ || ae<DECIMAL128_Emin) { /* likely underflow */ @@ -118,7 +118,7 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn, if (dn->bits&DECSPECIAL) { /* a special value */ if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24; else { /* sNaN or qNaN */ - if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */ + if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */ && (dn->digits<DECIMAL128_Pmax)) { /* coefficient fits */ decDigitsToDPD(dn, targar, 0); } @@ -144,11 +144,11 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn, comb=(exp>>9) & 0x18; /* msd=0, exp top 2 bits .. */ } else { /* non-zero finite number */ - uInt msd; /* work */ + uInt msd; /* work */ Int pad=0; /* coefficient pad digits */ /* the dn is known to fit, but it may need to be padded */ - exp=(uInt)(dn->exponent+DECIMAL128_Bias); /* bias exponent */ + exp=(uInt)(dn->exponent+DECIMAL128_Bias); /* bias exponent */ if (exp>DECIMAL128_Ehigh) { /* fold-down case */ pad=exp-DECIMAL128_Ehigh; exp=DECIMAL128_Ehigh; /* [to maximum] */ @@ -172,18 +172,19 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn, if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */ /* now write to storage; this is endian */ - pu=(uInt *)d128->bytes; /* overlay */ if (DECLITEND) { - pu[0]=targlo; /* directly store the low int */ - pu[1]=targml; /* then the mid-low */ - pu[2]=targmh; /* then the mid-high */ - pu[3]=targhi; /* then the high int */ + /* lo -> hi */ + UBFROMUI(d128->bytes, targlo); + UBFROMUI(d128->bytes+4, targml); + UBFROMUI(d128->bytes+8, targmh); + UBFROMUI(d128->bytes+12, targhi); } else { - pu[0]=targhi; /* directly store the high int */ - pu[1]=targmh; /* then the mid-high */ - pu[2]=targml; /* then the mid-low */ - pu[3]=targlo; /* then the low int */ + /* hi -> lo */ + UBFROMUI(d128->bytes, targhi); + UBFROMUI(d128->bytes+4, targmh); + UBFROMUI(d128->bytes+8, targml); + UBFROMUI(d128->bytes+12, targlo); } if (status!=0) decContextSetStatus(set, status); /* pass on status */ @@ -201,8 +202,8 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) { uInt msd; /* coefficient MSD */ uInt exp; /* exponent top two bits */ uInt comb; /* combination field */ - const uInt *pu; /* work */ - Int need; /* .. */ + Int need; /* work */ + uInt uiwork; /* for macros */ uInt sourar[4]; /* source 128-bit */ #define sourhi sourar[3] /* name the word with the sign */ #define sourmh sourar[2] /* and the mid-high word */ @@ -210,18 +211,17 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) { #define sourlo sourar[0] /* and the lowest word */ /* load source from storage; this is endian */ - pu=(const uInt *)d128->bytes; /* overlay */ if (DECLITEND) { - sourlo=pu[0]; /* directly load the low int */ - sourml=pu[1]; /* then the mid-low */ - sourmh=pu[2]; /* then the mid-high */ - sourhi=pu[3]; /* then the high int */ + sourlo=UBTOUI(d128->bytes ); /* directly load the low int */ + sourml=UBTOUI(d128->bytes+4 ); /* then the mid-low */ + sourmh=UBTOUI(d128->bytes+8 ); /* then the mid-high */ + sourhi=UBTOUI(d128->bytes+12); /* then the high int */ } else { - sourhi=pu[0]; /* directly load the high int */ - sourmh=pu[1]; /* then the mid-high */ - sourml=pu[2]; /* then the mid-low */ - sourlo=pu[3]; /* then the low int */ + sourhi=UBTOUI(d128->bytes ); /* directly load the high int */ + sourmh=UBTOUI(d128->bytes+4 ); /* then the mid-high */ + sourml=UBTOUI(d128->bytes+8 ); /* then the mid-low */ + sourlo=UBTOUI(d128->bytes+12); /* then the low int */ } comb=(sourhi>>26)&0x1f; /* combination field */ @@ -232,7 +232,7 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) { msd=COMBMSD[comb]; /* decode the combination field */ exp=COMBEXP[comb]; /* .. */ - if (exp==3) { /* is a special */ + if (exp==3) { /* is a special */ if (msd==0) { dn->bits|=DECINF; return dn; /* no coefficient needed */ @@ -265,7 +265,7 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) { } /* decimal128ToNumber */ /* ------------------------------------------------------------------ */ -/* to-scientific-string -- conversion to numeric string */ +/* to-scientific-string -- conversion to numeric string */ /* to-engineering-string -- conversion to numeric string */ /* */ /* decimal128ToString(d128, string); */ @@ -279,7 +279,7 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) { /* No error is possible, and no status can be set. */ /* ------------------------------------------------------------------ */ char * decimal128ToEngString(const decimal128 *d128, char *string){ - decNumber dn; /* work */ + decNumber dn; /* work */ decimal128ToNumber(d128, &dn); decNumberToEngString(&dn, string); return string; @@ -289,13 +289,13 @@ char * decimal128ToString(const decimal128 *d128, char *string){ uInt msd; /* coefficient MSD */ Int exp; /* exponent top two bits or full */ uInt comb; /* combination field */ - char *cstart; /* coefficient start */ + char *cstart; /* coefficient start */ char *c; /* output pointer in string */ - const uInt *pu; /* work */ + const uByte *u; /* work */ char *s, *t; /* .. (source, target) */ Int dpd; /* .. */ Int pre, e; /* .. */ - const uByte *u; /* .. */ + uInt uiwork; /* for macros */ uInt sourar[4]; /* source 128-bit */ #define sourhi sourar[3] /* name the word with the sign */ @@ -304,18 +304,17 @@ char * decimal128ToString(const decimal128 *d128, char *string){ #define sourlo sourar[0] /* and the lowest word */ /* load source from storage; this is endian */ - pu=(const uInt *)d128->bytes; /* overlay */ if (DECLITEND) { - sourlo=pu[0]; /* directly load the low int */ - sourml=pu[1]; /* then the mid-low */ - sourmh=pu[2]; /* then the mid-high */ - sourhi=pu[3]; /* then the high int */ + sourlo=UBTOUI(d128->bytes ); /* directly load the low int */ + sourml=UBTOUI(d128->bytes+4 ); /* then the mid-low */ + sourmh=UBTOUI(d128->bytes+8 ); /* then the mid-high */ + sourhi=UBTOUI(d128->bytes+12); /* then the high int */ } else { - sourhi=pu[0]; /* directly load the high int */ - sourmh=pu[1]; /* then the mid-high */ - sourml=pu[2]; /* then the mid-low */ - sourlo=pu[3]; /* then the low int */ + sourhi=UBTOUI(d128->bytes ); /* directly load the high int */ + sourmh=UBTOUI(d128->bytes+4 ); /* then the mid-high */ + sourml=UBTOUI(d128->bytes+8 ); /* then the mid-low */ + sourlo=UBTOUI(d128->bytes+12); /* then the low int */ } c=string; /* where result will go */ @@ -327,7 +326,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){ if (exp==3) { if (msd==0) { /* infinity */ - strcpy(c, "Inf"); + strcpy(c, "Inf"); strcpy(c+3, "inity"); return string; /* easy */ } @@ -353,12 +352,12 @@ char * decimal128ToString(const decimal128 *d128, char *string){ /* length. We use fixed-length memcpys because variable-length */ /* causes a subroutine call in GCC. (These are length 4 for speed */ /* and are safe because the array has an extra terminator byte.) */ - #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \ + #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \ if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \ else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;} dpd=(sourhi>>4)&0x3ff; /* declet 1 */ dpd2char; - dpd=((sourhi&0xf)<<6) | (sourmh>>26); /* declet 2 */ + dpd=((sourhi&0xf)<<6) | (sourmh>>26); /* declet 2 */ dpd2char; dpd=(sourmh>>16)&0x3ff; /* declet 3 */ dpd2char; @@ -381,7 +380,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){ if (c==cstart) *c++='0'; /* all zeros -- make 0 */ - if (exp==0) { /* integer or NaN case -- easy */ + if (exp==0) { /* integer or NaN case -- easy */ *c='\0'; /* terminate */ return string; } @@ -409,8 +408,8 @@ char * decimal128ToString(const decimal128 *d128, char *string){ /* finally add the E-part, if needed; it will never be 0, and has */ /* a maximum length of 4 digits */ if (e!=0) { - *c++='E'; /* starts with E */ - *c++='+'; /* assume positive */ + *c++='E'; /* starts with E */ + *c++='+'; /* assume positive */ if (e<0) { *(c-1)='-'; /* oops, need '-' */ e=-e; /* uInt, please */ @@ -449,13 +448,13 @@ char * decimal128ToString(const decimal128 *d128, char *string){ /* ------------------------------------------------------------------ */ /* to-number -- conversion from numeric string */ /* */ -/* decimal128FromString(result, string, set); */ +/* decimal128FromString(result, string, set); */ /* */ /* result is the decimal128 format number which gets the result of */ /* the conversion */ /* *string is the character string which should contain a valid */ /* number (which may be a special value) */ -/* set is the context */ +/* set is the context */ /* */ /* The context is supplied to this routine is used for error handling */ /* (setting of status and traps) and for the rounding mode, only. */ @@ -464,7 +463,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){ decimal128 * decimal128FromString(decimal128 *result, const char *string, decContext *set) { decContext dc; /* work */ - decNumber dn; /* .. */ + decNumber dn; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL128); /* no traps, please */ dc.round=set->round; /* use supplied rounding */ @@ -483,8 +482,8 @@ decimal128 * decimal128FromString(decimal128 *result, const char *string, /* returns 1 if the encoding of d128 is canonical, 0 otherwise */ /* No error is possible. */ /* ------------------------------------------------------------------ */ -uint32_t decimal128IsCanonical(const decimal128 *d128) { - decNumber dn; /* work */ +uInt decimal128IsCanonical(const decimal128 *d128) { + decNumber dn; /* work */ decimal128 canon; /* .. */ decContext dc; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL128); @@ -501,7 +500,7 @@ uint32_t decimal128IsCanonical(const decimal128 *d128) { /* No error is possible. */ /* ------------------------------------------------------------------ */ decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) { - decNumber dn; /* work */ + decNumber dn; /* work */ decContext dc; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL128); decimal128ToNumber(d128, &dn); @@ -532,13 +531,13 @@ decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) { /* This assumes range has been checked and exponent previously 0; */ /* type of exponent must be unsigned */ #define decimal128SetExpCon(d, e) { \ - (d)->bytes[0]|=(uint8_t)((e)>>10); \ - (d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2); \ - (d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);} + (d)->bytes[0]|=(uByte)((e)>>10); \ + (d)->bytes[1] =(uByte)(((e)&0x3fc)>>2); \ + (d)->bytes[2]|=(uByte)(((e)&0x03)<<6);} /* ------------------------------------------------------------------ */ /* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */ -/* d128 -- the number to show */ +/* d128 -- the number to show */ /* ------------------------------------------------------------------ */ /* Also shows sign/cob/expconfields extracted */ void decimal128Show(const decimal128 *d128) { diff --git a/libdecnumber/dpd/decimal128.h b/libdecnumber/dpd/decimal128.h index f8f5b5a8ff2..95f73f4bbf4 100644 --- a/libdecnumber/dpd/decimal128.h +++ b/libdecnumber/dpd/decimal128.h @@ -29,7 +29,7 @@ 02110-1301, USA. */ /* ------------------------------------------------------------------ */ -/* Decimal 128-bit format module header */ +/* Decimal 128-bit format module header */ /* ------------------------------------------------------------------ */ #if !defined(DECIMAL128) @@ -46,7 +46,7 @@ #define DECIMAL128_Bias 6176 /* bias for the exponent */ #define DECIMAL128_String 43 /* maximum string length, +1 */ #define DECIMAL128_EconL 12 /* exp. continuation length */ - /* highest biased exponent (Elimit-1) */ + /* highest biased exponent (Elimit-1) */ #define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1) /* check enough digits, if pre-defined */ @@ -71,20 +71,20 @@ /* special values [top byte excluding sign bit; last two bits are */ /* don't-care for Infinity on input, last bit don't-care for NaN] */ #if !defined(DECIMAL_NaN) - #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ + #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ #define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */ - #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ + #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ #endif - #include "decimal128Local.h" +#include "decimal128Local.h" /* ---------------------------------------------------------------- */ /* Routines */ /* ---------------------------------------------------------------- */ - #include "decimal128Symbols.h" +#include "decimal128Symbols.h" - /* String conversions */ + /* String conversions */ decimal128 * decimal128FromString(decimal128 *, const char *, decContext *); char * decimal128ToString(const decimal128 *, char *); char * decimal128ToEngString(const decimal128 *, char *); @@ -94,7 +94,7 @@ decContext *); decNumber * decimal128ToNumber(const decimal128 *, decNumber *); - /* Format-dependent utilities */ + /* Format-dependent utilities */ uint32_t decimal128IsCanonical(const decimal128 *); decimal128 * decimal128Canonical(decimal128 *, const decimal128 *); diff --git a/libdecnumber/dpd/decimal32.c b/libdecnumber/dpd/decimal32.c index d8e3f597811..eefd71c2a3c 100644 --- a/libdecnumber/dpd/decimal32.c +++ b/libdecnumber/dpd/decimal32.c @@ -29,7 +29,7 @@ 02110-1301, USA. */ /* ------------------------------------------------------------------ */ -/* Decimal 32-bit format module */ +/* Decimal 32-bit format module */ /* ------------------------------------------------------------------ */ /* This module comprises the routines for decimal32 format numbers. */ /* Conversions are supplied to and from decNumber and String. */ @@ -42,8 +42,8 @@ #include <string.h> /* [for memset/memcpy] */ #include <stdio.h> /* [for printf] */ -#include "dconfig.h" /* GCC definitions */ -#define DECNUMDIGITS 7 /* make decNumbers with space for 7 */ +#include "dconfig.h" /* GCC definitions */ +#define DECNUMDIGITS 7 /* make decNumbers with space for 7 */ #include "decNumber.h" /* base number library */ #include "decNumberLocal.h" /* decNumber local types, etc. */ #include "decimal32.h" /* our primary include */ @@ -69,9 +69,9 @@ extern void decNumberShow(const decNumber *); /* .. */ /* ------------------------------------------------------------------ */ /* decimal32FromNumber -- convert decNumber to decimal32 */ /* */ -/* ds is the target decimal32 */ +/* ds is the target decimal32 */ /* dn is the source number (assumed valid) */ -/* set is the context, used only for reporting errors */ +/* set is the context, used only for reporting errors */ /* */ /* The set argument is used only for status reporting and for the */ /* rounding mode (used if the coefficient is more than DECIMAL32_Pmax */ @@ -89,8 +89,8 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn, Int ae; /* adjusted exponent */ decNumber dw; /* work */ decContext dc; /* .. */ - uInt *pu; /* .. */ uInt comb, exp; /* .. */ + uInt uiwork; /* for macros */ uInt targ=0; /* target 32-bit */ /* If the number has too many digits, or the exponent could be */ @@ -98,9 +98,9 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn, /* constraints. This could push the number to Infinity or zero, */ /* so this check and rounding must be done before generating the */ /* decimal32] */ - ae=dn->exponent+dn->digits-1; /* [0 if special] */ - if (dn->digits>DECIMAL32_Pmax /* too many digits */ - || ae>DECIMAL32_Emax /* likely overflow */ + ae=dn->exponent+dn->digits-1; /* [0 if special] */ + if (dn->digits>DECIMAL32_Pmax /* too many digits */ + || ae>DECIMAL32_Emax /* likely overflow */ || ae<DECIMAL32_Emin) { /* likely underflow */ decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */ dc.round=set->round; /* use supplied rounding */ @@ -114,7 +114,7 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn, if (dn->bits&DECSPECIAL) { /* a special value */ if (dn->bits&DECINF) targ=DECIMAL_Inf<<24; else { /* sNaN or qNaN */ - if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */ + if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */ && (dn->digits<DECIMAL32_Pmax)) { /* coefficient fits */ decDigitsToDPD(dn, &targ, 0); } @@ -140,7 +140,7 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn, comb=(exp>>3) & 0x18; /* msd=0, exp top 2 bits .. */ } else { /* non-zero finite number */ - uInt msd; /* work */ + uInt msd; /* work */ Int pad=0; /* coefficient pad digits */ /* the dn is known to fit, but it may need to be padded */ @@ -175,8 +175,7 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn, if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */ /* now write to storage; this is endian */ - pu=(uInt *)d32->bytes; /* overlay */ - *pu=targ; /* directly store the int */ + UBFROMUI(d32->bytes, targ); /* directly store the int */ if (status!=0) decContextSetStatus(set, status); /* pass on status */ /* decimal32Show(d32); */ @@ -194,13 +193,12 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) { uInt exp; /* exponent top two bits */ uInt comb; /* combination field */ uInt sour; /* source 32-bit */ - const uInt *pu; /* work */ + uInt uiwork; /* for macros */ /* load source from storage; this is endian */ - pu=(const uInt *)d32->bytes; /* overlay */ - sour=*pu; /* directly load the int */ + sour=UBTOUI(d32->bytes); /* directly load the int */ - comb=(sour>>26)&0x1f; /* combination field */ + comb=(sour>>26)&0x1f; /* combination field */ decNumberZero(dn); /* clean number */ if (sour&0x80000000) dn->bits=DECNEG; /* set sign if negative */ @@ -208,7 +206,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) { msd=COMBMSD[comb]; /* decode the combination field */ exp=COMBEXP[comb]; /* .. */ - if (exp==3) { /* is a special */ + if (exp==3) { /* is a special */ if (msd==0) { dn->bits|=DECINF; return dn; /* no coefficient needed */ @@ -229,7 +227,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) { return dn; } /* msd=0 */ - if (!sour) return dn; /* easy: coefficient is 0 */ + if (!sour) return dn; /* easy: coefficient is 0 */ if (sour&0x000ffc00) /* need 2 declets? */ decDigitsFromDPD(dn, &sour, 2); /* process 2 declets */ else @@ -238,11 +236,11 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) { } /* decimal32ToNumber */ /* ------------------------------------------------------------------ */ -/* to-scientific-string -- conversion to numeric string */ +/* to-scientific-string -- conversion to numeric string */ /* to-engineering-string -- conversion to numeric string */ /* */ /* decimal32ToString(d32, string); */ -/* decimal32ToEngString(d32, string); */ +/* decimal32ToEngString(d32, string); */ /* */ /* d32 is the decimal32 format number to convert */ /* string is the string where the result will be laid out */ @@ -252,7 +250,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) { /* No error is possible, and no status can be set. */ /* ------------------------------------------------------------------ */ char * decimal32ToEngString(const decimal32 *d32, char *string){ - decNumber dn; /* work */ + decNumber dn; /* work */ decimal32ToNumber(d32, &dn); decNumberToEngString(&dn, string); return string; @@ -262,29 +260,28 @@ char * decimal32ToString(const decimal32 *d32, char *string){ uInt msd; /* coefficient MSD */ Int exp; /* exponent top two bits or full */ uInt comb; /* combination field */ - char *cstart; /* coefficient start */ + char *cstart; /* coefficient start */ char *c; /* output pointer in string */ - const uInt *pu; /* work */ - const uByte *u; /* .. */ + const uByte *u; /* work */ char *s, *t; /* .. (source, target) */ Int dpd; /* .. */ Int pre, e; /* .. */ + uInt uiwork; /* for macros */ uInt sour; /* source 32-bit */ /* load source from storage; this is endian */ - pu=(const uInt *)d32->bytes; /* overlay */ - sour=*pu; /* directly load the int */ + sour=UBTOUI(d32->bytes); /* directly load the int */ c=string; /* where result will go */ if (((Int)sour)<0) *c++='-'; /* handle sign */ - comb=(sour>>26)&0x1f; /* combination field */ + comb=(sour>>26)&0x1f; /* combination field */ msd=COMBMSD[comb]; /* decode the combination field */ exp=COMBEXP[comb]; /* .. */ if (exp==3) { if (msd==0) { /* infinity */ - strcpy(c, "Inf"); + strcpy(c, "Inf"); strcpy(c+3, "inity"); return string; /* easy */ } @@ -309,18 +306,18 @@ char * decimal32ToString(const decimal32 *d32, char *string){ /* length. We use fixed-length memcpys because variable-length */ /* causes a subroutine call in GCC. (These are length 4 for speed */ /* and are safe because the array has an extra terminator byte.) */ - #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \ + #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \ if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \ else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;} - dpd=(sour>>10)&0x3ff; /* declet 1 */ + dpd=(sour>>10)&0x3ff; /* declet 1 */ dpd2char; dpd=(sour)&0x3ff; /* declet 2 */ dpd2char; if (c==cstart) *c++='0'; /* all zeros -- make 0 */ - if (exp==0) { /* integer or NaN case -- easy */ + if (exp==0) { /* integer or NaN case -- easy */ *c='\0'; /* terminate */ return string; } @@ -348,13 +345,13 @@ char * decimal32ToString(const decimal32 *d32, char *string){ /* finally add the E-part, if needed; it will never be 0, and has */ /* a maximum length of 3 digits (E-101 case) */ if (e!=0) { - *c++='E'; /* starts with E */ - *c++='+'; /* assume positive */ + *c++='E'; /* starts with E */ + *c++='+'; /* assume positive */ if (e<0) { *(c-1)='-'; /* oops, need '-' */ e=-e; /* uInt, please */ } - u=&BIN2CHAR[e*4]; /* -> length byte */ + u=&BIN2CHAR[e*4]; /* -> length byte */ memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */ c+=*u; /* bump pointer appropriately */ } @@ -384,7 +381,7 @@ char * decimal32ToString(const decimal32 *d32, char *string){ /* the conversion */ /* *string is the character string which should contain a valid */ /* number (which may be a special value) */ -/* set is the context */ +/* set is the context */ /* */ /* The context is supplied to this routine is used for error handling */ /* (setting of status and traps) and for the rounding mode, only. */ @@ -393,7 +390,7 @@ char * decimal32ToString(const decimal32 *d32, char *string){ decimal32 * decimal32FromString(decimal32 *result, const char *string, decContext *set) { decContext dc; /* work */ - decNumber dn; /* .. */ + decNumber dn; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL32); /* no traps, please */ dc.round=set->round; /* use supplied rounding */ @@ -409,11 +406,11 @@ decimal32 * decimal32FromString(decimal32 *result, const char *string, /* ------------------------------------------------------------------ */ /* decimal32IsCanonical -- test whether encoding is canonical */ /* d32 is the source decimal32 */ -/* returns 1 if the encoding of d32 is canonical, 0 otherwise */ +/* returns 1 if the encoding of d32 is canonical, 0 otherwise */ /* No error is possible. */ /* ------------------------------------------------------------------ */ -uint32_t decimal32IsCanonical(const decimal32 *d32) { - decNumber dn; /* work */ +uInt decimal32IsCanonical(const decimal32 *d32) { + decNumber dn; /* work */ decimal32 canon; /* .. */ decContext dc; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL32); @@ -430,7 +427,7 @@ uint32_t decimal32IsCanonical(const decimal32 *d32) { /* No error is possible. */ /* ------------------------------------------------------------------ */ decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) { - decNumber dn; /* work */ + decNumber dn; /* work */ decContext dc; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL32); decimal32ToNumber(d32, &dn); @@ -460,8 +457,8 @@ decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) { /* This assumes range has been checked and exponent previously 0; */ /* type of exponent must be unsigned */ #define decimal32SetExpCon(d, e) { \ - (d)->bytes[0]|=(uint8_t)((e)>>4); \ - (d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);} + (d)->bytes[0]|=(uByte)((e)>>4); \ + (d)->bytes[1]|=(uByte)(((e)&0x0F)<<4);} /* ------------------------------------------------------------------ */ /* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */ diff --git a/libdecnumber/dpd/decimal32.h b/libdecnumber/dpd/decimal32.h index 0d530464172..222ba973f4c 100644 --- a/libdecnumber/dpd/decimal32.h +++ b/libdecnumber/dpd/decimal32.h @@ -35,7 +35,7 @@ #if !defined(DECIMAL32) #define DECIMAL32 #define DEC32NAME "decimal32" /* Short name */ - #define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */ + #define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */ #define DEC32AUTHOR "Mike Cowlishaw" /* Who to blame */ /* parameters for decimal32s */ @@ -46,7 +46,7 @@ #define DECIMAL32_Bias 101 /* bias for the exponent */ #define DECIMAL32_String 15 /* maximum string length, +1 */ #define DECIMAL32_EconL 6 /* exp. continuation length */ - /* highest biased exponent (Elimit-1) */ + /* highest biased exponent (Elimit-1) */ #define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1) /* check enough digits, if pre-defined */ @@ -71,18 +71,18 @@ /* special values [top byte excluding sign bit; last two bits are */ /* don't-care for Infinity on input, last bit don't-care for NaN] */ #if !defined(DECIMAL_NaN) - #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ + #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ #define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */ - #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ + #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ #endif /* ---------------------------------------------------------------- */ /* Routines */ /* ---------------------------------------------------------------- */ - #include "decimal32Symbols.h" +#include "decimal32Symbols.h" - /* String conversions */ + /* String conversions */ decimal32 * decimal32FromString(decimal32 *, const char *, decContext *); char * decimal32ToString(const decimal32 *, char *); char * decimal32ToEngString(const decimal32 *, char *); @@ -92,7 +92,7 @@ decContext *); decNumber * decimal32ToNumber(const decimal32 *, decNumber *); - /* Format-dependent utilities */ + /* Format-dependent utilities */ uint32_t decimal32IsCanonical(const decimal32 *); decimal32 * decimal32Canonical(decimal32 *, const decimal32 *); diff --git a/libdecnumber/dpd/decimal64.c b/libdecnumber/dpd/decimal64.c index 474eb7cf8a0..77684d82fcc 100644 --- a/libdecnumber/dpd/decimal64.c +++ b/libdecnumber/dpd/decimal64.c @@ -29,7 +29,7 @@ 02110-1301, USA. */ /* ------------------------------------------------------------------ */ -/* Decimal 64-bit format module */ +/* Decimal 64-bit format module */ /* ------------------------------------------------------------------ */ /* This module comprises the routines for decimal64 format numbers. */ /* Conversions are supplied to and from decNumber and String. */ @@ -42,8 +42,8 @@ #include <string.h> /* [for memset/memcpy] */ #include <stdio.h> /* [for printf] */ -#include "dconfig.h" /* GCC definitions */ -#define DECNUMDIGITS 16 /* make decNumbers with space for 16 */ +#include "dconfig.h" /* GCC definitions */ +#define DECNUMDIGITS 16 /* make decNumbers with space for 16 */ #include "decNumber.h" /* base number library */ #include "decNumberLocal.h" /* decNumber local types, etc. */ #include "decimal64.h" /* our primary include */ @@ -75,9 +75,9 @@ extern void decNumberShow(const decNumber *); /* .. */ /* ------------------------------------------------------------------ */ /* decimal64FromNumber -- convert decNumber to decimal64 */ /* */ -/* ds is the target decimal64 */ +/* ds is the target decimal64 */ /* dn is the source number (assumed valid) */ -/* set is the context, used only for reporting errors */ +/* set is the context, used only for reporting errors */ /* */ /* The set argument is used only for status reporting and for the */ /* rounding mode (used if the coefficient is more than DECIMAL64_Pmax */ @@ -95,8 +95,8 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn, Int ae; /* adjusted exponent */ decNumber dw; /* work */ decContext dc; /* .. */ - uInt *pu; /* .. */ uInt comb, exp; /* .. */ + uInt uiwork; /* for macros */ uInt targar[2]={0, 0}; /* target 64-bit */ #define targhi targar[1] /* name the word with the sign */ #define targlo targar[0] /* and the other */ @@ -106,9 +106,9 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn, /* constraints. This could push the number to Infinity or zero, */ /* so this check and rounding must be done before generating the */ /* decimal64] */ - ae=dn->exponent+dn->digits-1; /* [0 if special] */ - if (dn->digits>DECIMAL64_Pmax /* too many digits */ - || ae>DECIMAL64_Emax /* likely overflow */ + ae=dn->exponent+dn->digits-1; /* [0 if special] */ + if (dn->digits>DECIMAL64_Pmax /* too many digits */ + || ae>DECIMAL64_Emax /* likely overflow */ || ae<DECIMAL64_Emin) { /* likely underflow */ decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */ dc.round=set->round; /* use supplied rounding */ @@ -122,7 +122,7 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn, if (dn->bits&DECSPECIAL) { /* a special value */ if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24; else { /* sNaN or qNaN */ - if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */ + if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */ && (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */ decDigitsToDPD(dn, targar, 0); } @@ -148,7 +148,7 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn, comb=(exp>>5) & 0x18; /* msd=0, exp top 2 bits .. */ } else { /* non-zero finite number */ - uInt msd; /* work */ + uInt msd; /* work */ Int pad=0; /* coefficient pad digits */ /* the dn is known to fit, but it may need to be padded */ @@ -193,14 +193,15 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn, if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */ /* now write to storage; this is now always endian */ - pu=(uInt *)d64->bytes; /* overlay */ if (DECLITEND) { - pu[0]=targar[0]; /* directly store the low int */ - pu[1]=targar[1]; /* then the high int */ + /* lo int then hi */ + UBFROMUI(d64->bytes, targar[0]); + UBFROMUI(d64->bytes+4, targar[1]); } else { - pu[0]=targar[1]; /* directly store the high int */ - pu[1]=targar[0]; /* then the low int */ + /* hi int then lo */ + UBFROMUI(d64->bytes, targar[1]); + UBFROMUI(d64->bytes+4, targar[0]); } if (status!=0) decContextSetStatus(set, status); /* pass on status */ @@ -218,21 +219,20 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) { uInt msd; /* coefficient MSD */ uInt exp; /* exponent top two bits */ uInt comb; /* combination field */ - const uInt *pu; /* work */ - Int need; /* .. */ + Int need; /* work */ + uInt uiwork; /* for macros */ uInt sourar[2]; /* source 64-bit */ #define sourhi sourar[1] /* name the word with the sign */ #define sourlo sourar[0] /* and the lower word */ /* load source from storage; this is endian */ - pu=(const uInt *)d64->bytes; /* overlay */ if (DECLITEND) { - sourlo=pu[0]; /* directly load the low int */ - sourhi=pu[1]; /* then the high int */ + sourlo=UBTOUI(d64->bytes ); /* directly load the low int */ + sourhi=UBTOUI(d64->bytes+4); /* then the high int */ } else { - sourhi=pu[0]; /* directly load the high int */ - sourlo=pu[1]; /* then the low int */ + sourhi=UBTOUI(d64->bytes ); /* directly load the high int */ + sourlo=UBTOUI(d64->bytes+4); /* then the low int */ } comb=(sourhi>>26)&0x1f; /* combination field */ @@ -243,7 +243,7 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) { msd=COMBMSD[comb]; /* decode the combination field */ exp=COMBEXP[comb]; /* .. */ - if (exp==3) { /* is a special */ + if (exp==3) { /* is a special */ if (msd==0) { dn->bits|=DECINF; return dn; /* no coefficient needed */ @@ -281,11 +281,11 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) { /* ------------------------------------------------------------------ */ -/* to-scientific-string -- conversion to numeric string */ +/* to-scientific-string -- conversion to numeric string */ /* to-engineering-string -- conversion to numeric string */ /* */ /* decimal64ToString(d64, string); */ -/* decimal64ToEngString(d64, string); */ +/* decimal64ToEngString(d64, string); */ /* */ /* d64 is the decimal64 format number to convert */ /* string is the string where the result will be laid out */ @@ -295,7 +295,7 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) { /* No error is possible, and no status can be set. */ /* ------------------------------------------------------------------ */ char * decimal64ToEngString(const decimal64 *d64, char *string){ - decNumber dn; /* work */ + decNumber dn; /* work */ decimal64ToNumber(d64, &dn); decNumberToEngString(&dn, string); return string; @@ -305,27 +305,26 @@ char * decimal64ToString(const decimal64 *d64, char *string){ uInt msd; /* coefficient MSD */ Int exp; /* exponent top two bits or full */ uInt comb; /* combination field */ - char *cstart; /* coefficient start */ + char *cstart; /* coefficient start */ char *c; /* output pointer in string */ - const uInt *pu; /* work */ + const uByte *u; /* work */ char *s, *t; /* .. (source, target) */ Int dpd; /* .. */ Int pre, e; /* .. */ - const uByte *u; /* .. */ + uInt uiwork; /* for macros */ uInt sourar[2]; /* source 64-bit */ #define sourhi sourar[1] /* name the word with the sign */ #define sourlo sourar[0] /* and the lower word */ /* load source from storage; this is endian */ - pu=(const uInt *)d64->bytes; /* overlay */ if (DECLITEND) { - sourlo=pu[0]; /* directly load the low int */ - sourhi=pu[1]; /* then the high int */ + sourlo=UBTOUI(d64->bytes ); /* directly load the low int */ + sourhi=UBTOUI(d64->bytes+4); /* then the high int */ } else { - sourhi=pu[0]; /* directly load the high int */ - sourlo=pu[1]; /* then the low int */ + sourhi=UBTOUI(d64->bytes ); /* directly load the high int */ + sourlo=UBTOUI(d64->bytes+4); /* then the low int */ } c=string; /* where result will go */ @@ -337,7 +336,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){ if (exp==3) { if (msd==0) { /* infinity */ - strcpy(c, "Inf"); + strcpy(c, "Inf"); strcpy(c+3, "inity"); return string; /* easy */ } @@ -362,7 +361,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){ /* length. We use fixed-length memcpys because variable-length */ /* causes a subroutine call in GCC. (These are length 4 for speed */ /* and are safe because the array has an extra terminator byte.) */ - #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \ + #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \ if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \ else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;} @@ -379,7 +378,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){ if (c==cstart) *c++='0'; /* all zeros -- make 0 */ - if (exp==0) { /* integer or NaN case -- easy */ + if (exp==0) { /* integer or NaN case -- easy */ *c='\0'; /* terminate */ return string; } @@ -407,13 +406,13 @@ char * decimal64ToString(const decimal64 *d64, char *string){ /* finally add the E-part, if needed; it will never be 0, and has */ /* a maximum length of 3 digits */ if (e!=0) { - *c++='E'; /* starts with E */ - *c++='+'; /* assume positive */ + *c++='E'; /* starts with E */ + *c++='+'; /* assume positive */ if (e<0) { *(c-1)='-'; /* oops, need '-' */ e=-e; /* uInt, please */ } - u=&BIN2CHAR[e*4]; /* -> length byte */ + u=&BIN2CHAR[e*4]; /* -> length byte */ memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */ c+=*u; /* bump pointer appropriately */ } @@ -443,7 +442,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){ /* the conversion */ /* *string is the character string which should contain a valid */ /* number (which may be a special value) */ -/* set is the context */ +/* set is the context */ /* */ /* The context is supplied to this routine is used for error handling */ /* (setting of status and traps) and for the rounding mode, only. */ @@ -452,7 +451,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){ decimal64 * decimal64FromString(decimal64 *result, const char *string, decContext *set) { decContext dc; /* work */ - decNumber dn; /* .. */ + decNumber dn; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL64); /* no traps, please */ dc.round=set->round; /* use supplied rounding */ @@ -469,11 +468,11 @@ decimal64 * decimal64FromString(decimal64 *result, const char *string, /* ------------------------------------------------------------------ */ /* decimal64IsCanonical -- test whether encoding is canonical */ /* d64 is the source decimal64 */ -/* returns 1 if the encoding of d64 is canonical, 0 otherwise */ +/* returns 1 if the encoding of d64 is canonical, 0 otherwise */ /* No error is possible. */ /* ------------------------------------------------------------------ */ -uint32_t decimal64IsCanonical(const decimal64 *d64) { - decNumber dn; /* work */ +uInt decimal64IsCanonical(const decimal64 *d64) { + decNumber dn; /* work */ decimal64 canon; /* .. */ decContext dc; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL64); @@ -490,7 +489,7 @@ uint32_t decimal64IsCanonical(const decimal64 *d64) { /* No error is possible. */ /* ------------------------------------------------------------------ */ decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) { - decNumber dn; /* work */ + decNumber dn; /* work */ decContext dc; /* .. */ decContextDefault(&dc, DEC_INIT_DECIMAL64); decimal64ToNumber(d64, &dn); @@ -520,8 +519,8 @@ decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) { /* This assumes range has been checked and exponent previously 0; */ /* type of exponent must be unsigned */ #define decimal64SetExpCon(d, e) { \ - (d)->bytes[0]|=(uint8_t)((e)>>6); \ - (d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);} + (d)->bytes[0]|=(uByte)((e)>>6); \ + (d)->bytes[1]|=(uByte)(((e)&0x3F)<<2);} /* ------------------------------------------------------------------ */ /* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */ @@ -591,12 +590,12 @@ const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7, /* ------------------------------------------------------------------ */ /* decDigitsToDPD -- pack coefficient into DPD form */ /* */ -/* dn is the source number (assumed valid, max DECMAX754 digits) */ +/* dn is the source number (assumed valid, max DECMAX754 digits) */ /* targ is 1, 2, or 4-element uInt array, which the caller must */ -/* have cleared to zeros */ +/* have cleared to zeros */ /* shift is the number of 0 digits to add on the right (normally 0) */ /* */ -/* The coefficient must be known small enough to fit. The full */ +/* The coefficient must be known small enough to fit. The full */ /* coefficient is copied, including the leading 'odd' digit. This */ /* digit is retrieved and packed into the combination field by the */ /* caller. */ @@ -625,7 +624,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { uInt dpd; /* densely packed decimal value */ uInt bin; /* binary value 0-999 */ uInt *uout=targ; /* -> current output uInt */ - uInt uoff=0; /* -> current output offset [from right] */ + uInt uoff=0; /* -> current output offset [from right] */ const Unit *inu=dn->lsu; /* -> current input unit */ Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */ #if DECDPUN!=3 /* not fast path */ @@ -636,7 +635,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { /* shift the units array to the left by pad digits and copy */ /* [this code is a special case of decShiftToMost, which could */ /* be used instead if exposed and the array were copied first] */ - const Unit *source; /* .. */ + const Unit *source; /* .. */ Unit *target, *first; /* .. */ uInt next=0; /* work */ @@ -681,12 +680,12 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { for(n=0; digits>0; n++) { /* each output bunch */ #if DECDPUN==3 /* fast path, 3-at-a-time */ - bin=*inu; /* 3 digits ready for convert */ + bin=*inu; /* 3 digits ready for convert */ digits-=3; /* [may go negative] */ inu++; /* may need another */ #else /* must collect digit-by-digit */ - Unit dig; /* current digit */ + Unit dig; /* current digit */ Int j; /* digit-in-declet count */ for (j=0; j<3; j++) { #if DECDPUN<=4 @@ -698,7 +697,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { in=in/10; #endif if (j==0) bin=dig; - else if (j==1) bin+=X10(dig); + else if (j==1) bin+=X10(dig); else /* j==2 */ bin+=X100(dig); digits--; if (digits==0) break; /* [also protects *inu below] */ @@ -750,12 +749,12 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) { Int n; /* counter */ Unit *uout=dn->lsu; /* -> current output unit */ Unit *last=uout; /* will be unit containing msd */ - const uInt *uin=sour; /* -> current input uInt */ - uInt uoff=0; /* -> current input offset [from right] */ + const uInt *uin=sour; /* -> current input uInt */ + uInt uoff=0; /* -> current input offset [from right] */ #if DECDPUN!=3 uInt bcd; /* BCD result */ - uInt nibble; /* work */ + uInt nibble; /* work */ Unit out=0; /* accumulator */ Int cut=0; /* power of ten in current unit */ #endif @@ -772,7 +771,7 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) { uoff-=32; dpd|=*uin<<(10-uoff); /* get waiting bits */ } - dpd&=0x3ff; /* clear uninteresting bits */ + dpd&=0x3ff; /* clear uninteresting bits */ #if DECDPUN==3 if (dpd==0) *uout=0; @@ -822,9 +821,9 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) { cut++; if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;} } /* n */ - if (cut!=0) { /* some more left over */ + if (cut!=0) { /* some more left over */ *uout=out; /* write out final unit */ - if (out) last=uout; /* and note if non-zero */ + if (out) last=uout; /* and note if non-zero */ } #endif @@ -834,14 +833,14 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) { dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */ /* must be at least 1 digit */ #if DECDPUN>1 - if (*last<10) return; /* common odd digit or 0 */ - dn->digits++; /* must be 2 at least */ + if (*last<10) return; /* common odd digit or 0 */ + dn->digits++; /* must be 2 at least */ #if DECDPUN>2 if (*last<100) return; /* 10-99 */ - dn->digits++; /* must be 3 at least */ + dn->digits++; /* must be 3 at least */ #if DECDPUN>3 if (*last<1000) return; /* 100-999 */ - dn->digits++; /* must be 4 at least */ + dn->digits++; /* must be 4 at least */ #if DECDPUN>4 for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++; #endif diff --git a/libdecnumber/dpd/decimal64.h b/libdecnumber/dpd/decimal64.h index 549b626536c..95ae15f2b0f 100644 --- a/libdecnumber/dpd/decimal64.h +++ b/libdecnumber/dpd/decimal64.h @@ -35,7 +35,7 @@ #if !defined(DECIMAL64) #define DECIMAL64 #define DEC64NAME "decimal64" /* Short name */ - #define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */ + #define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */ #define DEC64AUTHOR "Mike Cowlishaw" /* Who to blame */ @@ -47,7 +47,7 @@ #define DECIMAL64_Bias 398 /* bias for the exponent */ #define DECIMAL64_String 24 /* maximum string length, +1 */ #define DECIMAL64_EconL 8 /* exp. continuation length */ - /* highest biased exponent (Elimit-1) */ + /* highest biased exponent (Elimit-1) */ #define DECIMAL64_Ehigh (DECIMAL64_Emax+DECIMAL64_Bias-DECIMAL64_Pmax+1) /* check enough digits, if pre-defined */ @@ -73,18 +73,18 @@ /* special values [top byte excluding sign bit; last two bits are */ /* don't-care for Infinity on input, last bit don't-care for NaN] */ #if !defined(DECIMAL_NaN) - #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ + #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ #define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */ - #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ + #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ #endif /* ---------------------------------------------------------------- */ /* Routines */ /* ---------------------------------------------------------------- */ - #include "decimal64Symbols.h" +#include "decimal64Symbols.h" - /* String conversions */ + /* String conversions */ decimal64 * decimal64FromString(decimal64 *, const char *, decContext *); char * decimal64ToString(const decimal64 *, char *); char * decimal64ToEngString(const decimal64 *, char *); @@ -94,7 +94,7 @@ decContext *); decNumber * decimal64ToNumber(const decimal64 *, decNumber *); - /* Format-dependent utilities */ + /* Format-dependent utilities */ uint32_t decimal64IsCanonical(const decimal64 *); decimal64 * decimal64Canonical(decimal64 *, const decimal64 *); |