Commit f988ec96 by Ben Elliston Committed by Ben Elliston

decNumber.c, [...]: Upgrade to decNumber 3.61.

	* 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.

From-SVN: r145222
parent 7cdc1972
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).
......
......@@ -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 */
......@@ -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 */
......
......@@ -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 */
......
......@@ -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 *);
......
......@@ -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,
......
......@@ -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 */
......@@ -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
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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)
......
......@@ -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) \
......
......@@ -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);
......
......@@ -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
/* ---------------------------------------------------------------- */
......
......@@ -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 */
......
......@@ -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
......@@ -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 */
......
......@@ -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
......@@ -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) {
......
......@@ -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 *);
......
......@@ -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] */
......
......@@ -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 *);
......
......@@ -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
......
......@@ -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 *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment