+2009-03-30 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).
/* 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 */
#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 *,
/* 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. */
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;
}
/* 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,
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 */
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) */
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 */
#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--;
/* 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, */
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 */
}
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;
/* 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;
}
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 */
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 */
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 */
/* */
/* 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 */
/* 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. */
/* */
/* 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 */
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 .. */
/* 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] */
/* */
/* 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 */
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);
/* 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' */
/* */
/* 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 */
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
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 */
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;
/* 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 */
/* */
/* 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];
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 {
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 */
#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
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 */
/* 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
/* 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 */
}
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 */
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);
*(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 */
}
}
}
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;
}
#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");
/* 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,
/* 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. */
/* ------------------------------------------------------------------ */
/* 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) {
/* ------------------------------------------------------------------ */
/* 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) {
} /* 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) */
/* 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) */
/* 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;
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;
/* 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 */
/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
/* 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 */
/* */
} /* 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 */
/* */
/* 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) {
} /* [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);
} /* [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);
/* 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 */
/* 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 */
/* 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 */
/* */
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] */
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;
}
/* 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 */
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;
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);
}
/* 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 */
/* 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 */
}
/* 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 */
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;
/* 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 + */
} /* 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 */
/* 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 */
/* */
/* ------------------------------------------------------------------ */
/* 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)) {
} /* 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 */
/* */
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 */
} /* 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 */
/* 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 */
} /* 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 */
/* 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 */
/* ------------------------------------------------------------------ */
/* 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 */
/* */
/* ------------------------------------------------------------------ */
/* 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 */
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 */
/* 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,
/* 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 */
/* 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,
/* 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 */
/* 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,
}
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 */
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 */
/* 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,
/* ------------------------------------------------------------------ */
/* 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. */
/* ------------------------------------------------------------------ */
/* 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 */
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 */
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) */
/* 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) */
/* [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++) {
/* 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;
/* 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) */
#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 */
/* 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 */
/* */
/* 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 */
/* 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 */
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] */
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 */
/* */
} /* 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 */
/* */
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
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 */
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 */
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 */
} /* 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 */
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 */
/* 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,
/* 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 */
/* */
/* 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 */
} /* 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 */
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] */
/* 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 */
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;
}
}
/* 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; /* .. */
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;
}
}
/* 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; /* .. */
/* ------------------------------------------------------------------ */
/* 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 */
/* */
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 */
/* 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,
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? */
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 */
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) */
/* 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,
#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};
/* 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). */
/* */
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 */
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 */
}
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) {
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] */
}
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 */
/* 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) {
#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) */
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: {
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);
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;
/*------------------------------------------------------------------*/
/* 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 */
/* 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];}
/* 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 */
/* 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. */
/* ------------------------------------------------------------------ */
/* 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 */
/* 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. */
/* ------------------------------------------------------------------ */
*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 */
} /* 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 */
/* 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. */
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, */
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 */
/* 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;
}
} /* 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 */
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 */
}
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;
*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 */
*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 */
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"); */
/* 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 */
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;
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 */
/* 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. */
/* ------------------------------------------------------------------ */
} /* 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). */
/* 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. */
/* ------------------------------------------------------------------ */
} /* 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 */
} /* 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++) {
/* */
/* 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 */
/* ------------------------------------------------------------------ */
/* 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 */
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 */
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 */
}
/* 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;
}
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 */
/* 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? */
/* -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 */
}
/* 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++;
/* 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 */
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
/* */
/* 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 */
/* ------------------------------------------------------------------ */
/* 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 */
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 */
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 */
/* 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 */
/* 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 (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? */
/* 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++;
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
}
/* 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;
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
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);
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 */
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 */
#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 */
/* */
/* 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. */
/* 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. */
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
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
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
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 */
/* ------------------------------------------------------------------ */
} /* decContextGetRounding */
/* ------------------------------------------------------------------ */
-/* decContextGetStatus -- return current status */
+/* decContextGetStatus -- return current status */
/* */
/* context is the context structure to be queried */
/* returns status */
/* 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 */
/* */
/* 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) {
/* */
/* 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) {
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) {
#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 */
/* */
/* */
/* 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., */
#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 */
#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,
#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
#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
#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"
/* 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
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 *);
/* ------------------------------------------------------------------------ */
/* 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"
/* 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) */
/* */
/* 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. */
#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,
#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,
/* 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
#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 */
-
/* ------------------------------------------------------------------ */
/* 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) */
#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;
/* ---------------------------------------------------------------- */
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 *);
/* 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
/* ------------------------------------------------------------------ */
/* Decimal Number arithmetic module */
/* ------------------------------------------------------------------ */
-/* This module comprises the routines for General Decimal Arithmetic */
-/* as defined in the specification which may be found on the */
-/* http://www2.hursley.ibm.com/decimal web pages. It implements both */
+/* This module comprises the routines for arbitrary-precision General */
+/* Decimal Arithmetic as defined in the specification which may be */
+/* found on the General Decimal Arithmetic pages. It implements both */
/* the full ('extended') arithmetic and the simpler ('subset') */
/* arithmetic. */
/* */
-/* Usage notes: */
+/* Usage notes: */
/* */
/* 1. This code is ANSI C89 except: */
/* */
-/* If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and */
+/* a) C99 line comments (double forward slash) are used. (Most C */
+/* compilers accept these. If yours does not, a simple script */
+/* can be used to convert them to ANSI C comments.) */
+/* */
+/* b) Types from C99 stdint.h are used. If you do not have this */
+/* header file, see the User's Guide section of the decNumber */
+/* documentation; this lists the necessary definitions. */
+/* */
+/* c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and */
/* uint64_t types may be used. To avoid these, set DECUSE64=0 */
/* and DECDPUN<=4 (see documentation). */
/* */
+/* The code also conforms to C99 restrictions; in particular, */
+/* strict aliasing rules are observed. */
+/* */
/* 2. The decNumber format which this library uses is optimized for */
/* efficient processing of relatively short numbers; in particular */
/* it allows the use of fixed sized structures and minimizes copy */
-/* and move operations. It does, however, support arbitrary */
+/* and move operations. It does, however, support arbitrary */
/* precision (up to 999,999,999 digits) and arbitrary exponent */
/* range (Emax in the range 0 through 999,999,999 and Emin in the */
/* range -999,999,999 through 0). Mathematical functions (for */
/* permitted). Other than that case, operands must not overlap. */
/* */
/* 5. Error handling: the type of the error is ORed into the status */
-/* flags in the current context (decContext structure). The */
+/* flags in the current context (decContext structure). The */
/* SIGFPE signal is then raised if the corresponding trap-enabler */
/* flag in the decContext is set (is 1). */
/* */
/* */
/* The result of any routine which returns a number will always */
/* be a valid number (which may be a special value, such as an */
-/* Infinity or NaN). */
+/* Infinity or NaN). */
/* */
/* 6. The decNumber format is not an exchangeable concrete */
/* representation as it comprises fields which may be machine- */
/* Canonical conversions to and from strings are provided; other */
/* conversions are available in separate modules. */
/* */
-/* 7. Normally, input operands are assumed to be valid. Set DECCHECK */
+/* 7. Normally, input operands are assumed to be valid. Set DECCHECK */
/* to 1 for extended operand checking (including NULL operands). */
/* Results are undefined if a badly-formed structure (or a NULL */
-/* pointer to a structure) is provided, though with DECCHECK */
+/* pointer to a structure) is provided, though with DECCHECK */
/* enabled the operator routines are protected against exceptions. */
/* (Except if the result pointer is NULL, which is unrecoverable.) */
/* */
/* */
/* 8. Subset arithmetic is available only if DECSUBSET is set to 1. */
/* ------------------------------------------------------------------ */
-/* Implementation notes for maintenance of this module: */
+/* Implementation notes for maintenance of this module: */
/* */
/* 1. Storage leak protection: Routines which use malloc are not */
/* permitted to use return for fastpath or error exits (i.e., */
/* 3. Setting status in the context must always be the very last */
/* action in a routine, as non-0 status may raise a trap and hence */
/* the call to set status may not return (if the handler uses long */
-/* jump). Therefore all cleanup must be done first. In general, */
+/* jump). Therefore all cleanup must be done first. In general, */
/* to achieve this status is accumulated and is only applied just */
/* before return by calling decContextSetStatus (via decStatus). */
/* */
/* */
/* 4. Exponent checking is minimized by allowing the exponent to */
/* grow outside its limits during calculations, provided that */
-/* the decFinalize function is called later. Multiplication and */
+/* the decFinalize function is called later. Multiplication and */
/* division, and intermediate calculations in exponentiation, */
-/* require more careful checks because of the risk of 31-bit */
+/* require more careful checks because of the risk of 31-bit */
/* overflow (the most negative valid exponent is -1999999997, for */
/* a 999999999-digit number with adjusted exponent of -999999999). */
/* */
/* is not useful for longer numbers because overflow of 32 bits */
/* would lead to 4 multiplies, which is almost as expensive as */
/* a divide (unless a floating-point or 64-bit multiply is */
-/* assumed to be available). */
+/* assumed to be available). */
/* */
-/* 8. Unusual abbreviations that may be used in the commentary: */
+/* 8. Unusual abbreviations that may be used in the commentary: */
/* lhs -- left hand side (operand, of an operation) */
-/* lsd -- least significant digit (of coefficient) */
+/* lsd -- least significant digit (of coefficient) */
/* lsu -- least significant Unit (of coefficient) */
/* msd -- most significant digit (of coefficient) */
/* msi -- most significant item (in an array) */
/* msu -- most significant Unit (of coefficient) */
/* rhs -- right hand side (operand, of an operation) */
-/* +ve -- positive */
-/* -ve -- negative */
+/* +ve -- positive */
+/* -ve -- negative */
/* ** -- raise to the power */
/* ------------------------------------------------------------------ */
/* Public lookup table used by the D2U macro */
const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
-#define DECVERB 1 /* set to 1 for verbose DECCHECK */
+#define DECVERB 1 /* set to 1 for verbose DECCHECK */
#define powers DECPOWERS /* old internal name */
/* Local constants */
#define DIVIDE 0x80 /* Divide operators */
#define REMAINDER 0x40 /* .. */
#define DIVIDEINT 0x20 /* .. */
-#define REMNEAR 0x10 /* .. */
-#define COMPARE 0x01 /* Compare operators */
-#define COMPMAX 0x02 /* .. */
-#define COMPMIN 0x03 /* .. */
+#define REMNEAR 0x10 /* .. */
+#define COMPARE 0x01 /* Compare operators */
+#define COMPMAX 0x02 /* .. */
+#define COMPMIN 0x03 /* .. */
#define COMPTOTAL 0x04 /* .. */
-#define COMPNAN 0x05 /* .. [NaN processing] */
-#define COMPSIG 0x06 /* .. [signaling COMPARE] */
+#define COMPNAN 0x05 /* .. [NaN processing] */
+#define COMPSIG 0x06 /* .. [signaling COMPARE] */
#define COMPMAXMAG 0x07 /* .. */
#define COMPMINMAG 0x08 /* .. */
-#define DEC_sNaN 0x40000000 /* local status: sNaN signal */
-#define BADINT (Int)0x80000000 /* most-negative Int; error indicator */
+#define DEC_sNaN 0x40000000 /* local status: sNaN signal */
+#define BADINT (Int)0x80000000 /* most-negative Int; error indicator */
/* Next two indicate an integer >= 10**6, and its parity (bottom bit) */
#define BIGEVEN (Int)0x80000002
#define BIGODD (Int)0x80000003
static Int decShiftToMost(Unit *, Int, Int);
static void decStatus(decNumber *, uInt, decContext *);
static void decToString(const decNumber *, char[], Flag);
-static decNumber * decTrim(decNumber *, decContext *, Flag, Int *);
+static decNumber * decTrim(decNumber *, decContext *, Flag, Flag, Int *);
static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
Unit *, Int);
static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
#if DECCHECK
/* Optional checking routines. Enabling these means that decNumber */
/* and decContext operands to operator routines are checked for */
-/* correctness. This roughly doubles the execution time of the */
+/* correctness. This roughly doubles the execution time of the */
/* fastest routines (and adds 600+ bytes), so should not normally be */
/* used in 'production'. */
/* decCheckInexact is used to check that inexact results have a full */
Int d; /* work */
const Unit *up; /* .. */
uInt hi=0, lo; /* .. */
- up=dn->lsu; /* -> lsu */
+ up=dn->lsu; /* -> lsu */
lo=*up; /* get 1 to 9 digits */
#if DECDPUN>1 /* split to higher */
hi=lo/10;
Int d; /* work */
const Unit *up; /* .. */
uInt hi=0, lo; /* .. */
- up=dn->lsu; /* -> lsu */
+ up=dn->lsu; /* -> lsu */
lo=*up; /* get 1 to 9 digits */
#if DECDPUN>1 /* split to higher */
hi=lo/10;
} /* decNumberToUInt32 */
/* ------------------------------------------------------------------ */
-/* to-scientific-string -- conversion to numeric string */
+/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric string */
/* */
/* decNumberToString(dn, string); */
/* to-number -- conversion from numeric string */
/* */
/* decNumberFromString -- convert string to decNumber */
-/* dn -- the number structure to fill */
+/* dn -- the number structure to fill */
/* chars[] -- the string to convert ('\0' terminated) */
/* set -- the context used for processing any error, */
/* determining the maximum precision available */
/* (set.digits), determining the maximum and minimum */
/* exponent (set.emax and set.emin), determining if */
-/* extended values are allowed, and checking the */
+/* extended values are allowed, and checking the */
/* rounding mode if overflow occurs or rounding is */
/* needed. */
/* */
/* The length of the coefficient and the size of the exponent are */
/* checked by this routine, so the correct error (Underflow or */
-/* Overflow) can be reported or rounding applied, as necessary. */
+/* Overflow) can be reported or rounding applied, as necessary. */
/* */
/* If bad syntax is detected, the result will be a quiet NaN. */
/* ------------------------------------------------------------------ */
decNumber * decNumberFromString(decNumber *dn, const char chars[],
decContext *set) {
Int exponent=0; /* working exponent [assume 0] */
- uByte bits=0; /* working flags [assume +ve] */
+ uByte bits=0; /* working flags [assume +ve] */
Unit *res; /* where result will be built */
Unit resbuff[SD2U(DECBUFFER+9)];/* local buffer in case need temporary */
/* [+9 allows for ln() constants] */
- Unit *allocres=NULL; /* -> allocated result, iff allocated */
+ Unit *allocres=NULL; /* -> allocated result, iff allocated */
Int d=0; /* count of digits found in decimal part */
const char *dotchar=NULL; /* where dot was found */
const char *cfirst=chars; /* -> first character of decimal part */
do { /* status & malloc protection */
for (c=chars;; c++) { /* -> input character */
- if (*c>='0' && *c<='9') { /* test for Arabic digit */
+ if (*c>='0' && *c<='9') { /* test for Arabic digit */
last=c;
d++; /* count of real digits */
continue; /* still in decimal part */
if (!set->extended) break; /* hopeless */
#endif
/* Infinities and NaNs are possible, here */
- if (dotchar!=NULL) break; /* .. unless had a dot */
+ if (dotchar!=NULL) break; /* .. unless had a dot */
decNumberZero(dn); /* be optimistic */
if (decBiStr(c, "infinity", "INFINITY")
|| decBiStr(c, "inf", "INF")) {
/* a NaN expected */
/* 2003.09.10 NaNs are now permitted to have a sign */
dn->bits=bits | DECNAN; /* assume simple NaN */
- if (*c=='s' || *c=='S') { /* looks like an sNaN */
+ if (*c=='s' || *c=='S') { /* looks like an sNaN */
c++;
dn->bits=bits | DECSNAN;
}
if (d>set->digits) break;
} /* too many digits? */
/* good; drop through to convert the integer to coefficient */
- status=0; /* syntax is OK */
+ status=0; /* syntax is OK */
bits=dn->bits; /* for copy-back */
} /* last==NULL */
/* [up to 1999999999 is OK, for example 1E-1000000998] */
}
if (nege) exponent=-exponent; /* was negative */
- status=0; /* is OK */
+ status=0; /* is OK */
} /* stuff after digits */
/* Here when whole string has been inspected; syntax is good */
/* cfirst->first digit (never dot), last->last digit (ditto) */
/* strip leading zeros/dot [leave final 0 if all 0's] */
- if (*cfirst=='0') { /* [cfirst has stepped over .] */
+ if (*cfirst=='0') { /* [cfirst has stepped over .] */
for (c=cfirst; c<last; c++, cfirst++) {
if (*c=='.') continue; /* ignore dots */
if (*c!='0') break; /* non-zero found */
/* Handle decimal point... */
if (dotchar!=NULL && dotchar<last) /* non-trailing '.' found? */
- exponent-=(last-dotchar); /* adjust exponent */
+ exponent-=(last-dotchar); /* adjust exponent */
/* [we can now ignore the .] */
/* OK, the digits string is good. Assemble in the decNumber, or in */
}
}
/* decNumberShow(dn); */
- } while(0); /* [for break] */
+ } while(0); /* [for break] */
if (allocres!=NULL) free(allocres); /* drop any storage used */
if (status!=0) decStatus(dn, status, set);
/* */
/* res is C, the result. C may be A */
/* rhs is A */
-/* set is the context */
+/* set is the context */
/* */
/* See also decNumberCopyAbs for a quiet bitwise version of this. */
/* C must have space for set->digits digits. */
#endif
decNumberZero(&dzero); /* set 0 */
- dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
+ dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
if (status!=0) decStatus(res, status, set);
#if DECCHECK
/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for one digit (or NaN). */
/* ------------------------------------------------------------------ */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for one digit (or NaN). */
/* ------------------------------------------------------------------ */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for one digit; the result will always be one of */
-/* -1, 0, or 1. */
+/* -1, 0, or 1. */
/* ------------------------------------------------------------------ */
decNumber * decNumberCompareTotal(decNumber *res, const decNumber *lhs,
const decNumber *rhs, decContext *set) {
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for one digit; the result will always be one of */
-/* -1, 0, or 1. */
+/* -1, 0, or 1. */
/* ------------------------------------------------------------------ */
decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
const decNumber *rhs, decContext *set) {
a=allocbufa; /* use the allocated space */
}
decNumberCopy(a, lhs); /* copy content */
- a->bits&=~DECNEG; /* .. and clear the sign */
+ a->bits&=~DECNEG; /* .. and clear the sign */
lhs=a; /* use copy from here on */
}
if (decNumberIsNegative(rhs)) { /* rhs<0 */
b=allocbufb; /* use the allocated space */
}
decNumberCopy(b, rhs); /* copy content */
- b->bits&=~DECNEG; /* .. and clear the sign */
+ b->bits&=~DECNEG; /* .. and clear the sign */
rhs=b; /* use copy from here on */
}
decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
if (allocbufb!=NULL) free(allocbufb); /* .. */
/* res is C, the result. C may be A and/or B (e.g., X=X/X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
} /* decNumberDivide */
/* ------------------------------------------------------------------ */
-/* decNumberDivideInteger -- divide and return integer quotient */
+/* decNumberDivideInteger -- divide and return integer quotient */
/* */
/* This computes C = A # B, where # is the integer divide operator */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X#X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* */
/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
/* almost always be correctly rounded, but may be up to 1 ulp in */
-/* error in rare cases. */
+/* error in rare cases. */
/* ------------------------------------------------------------------ */
/* This is a wrapper for decExpOp which can handle the slightly wider */
/* (double) range needed by Ln (which has to be able to calculate */
}
#endif
decExpOp(res, rhs, set, &status);
- } while(0); /* end protected */
+ } while(0); /* end protected */
#if DECSUBSET
if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */
/* lhs is A */
/* rhs is B */
/* fhs is C [far hand side] */
-/* set is the context */
+/* set is the context */
/* */
/* Mathematical function restrictions apply (see above); a NaN is */
/* returned with Invalid_operation if a restriction is violated. */
/* Note sNaN has to go through addOp to shorten payload if */
/* necessary */
if ((status&DEC_Invalid_operation)!=0) {
- if (!(status&DEC_sNaN)) { /* but be true invalid */
+ if (!(status&DEC_sNaN)) { /* but be true invalid */
decNumberZero(res); /* acc not yet set */
res->bits=DECNAN;
break;
}
#if DECCHECK
else { /* multiply was OK */
- if (status!=0) printf("Status=%08lx after FMA multiply\n", status);
+ if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
}
#endif
/* add the third operand and result -> res, and all is done */
decAddOp(res, acc, fhs, set, 0, &status);
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
if (status!=0) decStatus(res, status, set);
msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */
for (; uc<=msuc; ua++, uc++) { /* Unit loop */
Unit a; /* extract unit */
- Int i, j; /* work */
+ Int i, j; /* work */
if (ua>msua) a=0;
else a=*ua;
*uc=0; /* can now write back */
/* */
/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
/* almost always be correctly rounded, but may be up to 1 ulp in */
-/* error in rare cases. */
+/* error in rare cases. */
/* ------------------------------------------------------------------ */
/* This is a wrapper for decLnOp which can handle the slightly wider */
/* (+11) range needed by Ln, Log10, etc. (which may have to be able */
} /* extended=0 */
#endif
decLnOp(res, rhs, set, &status);
- } while(0); /* end protected */
+ } while(0); /* end protected */
#if DECSUBSET
if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */
} /* decNumberLn */
/* ------------------------------------------------------------------ */
-/* decNumberLogB - get adjusted exponent, by 754r rules */
+/* decNumberLogB - get adjusted exponent, by 754 rules */
/* */
/* This computes C = adjustedexponent(A) */
/* */
if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);
else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs);
else if (decNumberIsZero(rhs)) {
- decNumberZero(res); /* prepare for Infinity */
+ decNumberZero(res); /* prepare for Infinity */
res->bits=DECNEG|DECINF; /* -Infinity */
- status|=DEC_Division_by_zero; /* as per 754r */
+ status|=DEC_Division_by_zero; /* as per 754 */
}
else { /* finite non-zero */
Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
/* ------------------------------------------------------------------ */
/* decNumberLog10 -- logarithm in base 10 */
/* */
-/* This computes C = log10(A) */
+/* This computes C = log10(A) */
/* */
/* res is C, the result. C may be A */
/* rhs is A */
/* */
/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
/* almost always be correctly rounded, but may be up to 1 ulp in */
-/* error in rare cases. */
+/* error in rare cases. */
/* ------------------------------------------------------------------ */
/* This calculates ln(A)/ln(10) using appropriate precision. For */
/* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the */
/* requested digits and t is the number of digits in the exponent */
-/* (maximum 6). For ln(10) it is p + 3; this is often handled by the */
-/* fastpath in decLnOp. The final division is done to the requested */
+/* (maximum 6). For ln(10) it is p + 3; this is often handled by the */
+/* fastpath in decLnOp. The final division is done to the requested */
/* precision. */
/* ------------------------------------------------------------------ */
decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
decNumberFromInt32(w, w->exponent);
residue=0;
decCopyFit(res, w, set, &residue, &status); /* copy & round */
- decFinish(res, set, &residue, &status); /* cleanup/set flags */
+ decFinish(res, set, &residue, &status); /* cleanup/set flags */
break;
} /* not a power of 10 */
} /* not a candidate for exact */
aset.digits=set->digits; /* for final divide */
decDivideOp(res, a, b, &aset, DIVIDE, &status); /* into result */
- } while(0); /* [for break] */
+ } while(0); /* [for break] */
if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
if (allocbufb!=NULL) free(allocbufb); /* .. */
/* ------------------------------------------------------------------ */
/* decNumberMax -- compare two Numbers and return the maximum */
/* */
-/* This computes C = A ? B, returning the maximum by 754R rules */
+/* This computes C = A ? B, returning the maximum by 754 rules */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
/* decNumberMaxMag -- compare and return the maximum by magnitude */
/* */
-/* This computes C = A ? B, returning the maximum by 754R rules */
+/* This computes C = A ? B, returning the maximum by 754 rules */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
/* decNumberMin -- compare two Numbers and return the minimum */
/* */
-/* This computes C = A ? B, returning the minimum by 754R rules */
+/* This computes C = A ? B, returning the minimum by 754 rules */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
/* decNumberMinMag -- compare and return the minimum by magnitude */
/* */
-/* This computes C = A ? B, returning the minimum by 754R rules */
+/* This computes C = A ? B, returning the minimum by 754 rules */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* */
/* res is C, the result. C may be A */
/* rhs is A */
-/* set is the context */
+/* set is the context */
/* */
/* See also decNumberCopyNegate for a quiet bitwise version of this. */
/* C must have space for set->digits digits. */
#endif
decNumberZero(&dzero); /* make 0 */
- dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
+ dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
decAddOp(res, &dzero, rhs, set, DECNEG, &status);
if (status!=0) decStatus(res, status, set);
#if DECCHECK
} /* decNumberMinus */
/* ------------------------------------------------------------------ */
-/* decNumberNextMinus -- next towards -Infinity */
+/* decNumberNextMinus -- next towards -Infinity */
/* */
/* This computes C = A - infinitesimal, rounded towards -Infinity */
/* */
/* res is C, the result. C may be A */
/* rhs is A */
-/* set is the context */
+/* set is the context */
/* */
-/* This is a generalization of 754r NextDown. */
+/* This is a generalization of 754 NextDown. */
/* ------------------------------------------------------------------ */
decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
decContext *set) {
/* */
/* res is C, the result. C may be A */
/* rhs is A */
-/* set is the context */
+/* set is the context */
/* */
-/* This is a generalization of 754r NextUp. */
+/* This is a generalization of 754 NextUp. */
/* ------------------------------------------------------------------ */
decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
decContext *set) {
/* decNumberNextToward -- next towards rhs */
/* */
/* This computes C = A +/- infinitesimal, rounded towards */
-/* +/-Infinity in the direction of B, as per 754r nextafter rules */
+/* +/-Infinity in the direction of B, as per 754-1985 nextafter */
+/* modified during revision but dropped from 754-2008. */
/* */
/* res is C, the result. C may be A or B. */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
-/* This is a generalization of 754r NextAfter. */
+/* This is a generalization of 754-1985 NextAfter. */
/* ------------------------------------------------------------------ */
decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs,
const decNumber *rhs, decContext *set) {
if (result==0) decNumberCopySign(res, lhs, rhs); /* easy */
else { /* differ: need NextPlus or NextMinus */
uByte sub; /* add or subtract */
- if (result<0) { /* lhs<rhs, do nextplus */
+ if (result<0) { /* lhs<rhs, do nextplus */
/* -Infinity is the special case */
if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
decSetMaxValue(res, set);
res->bits=DECNEG; /* negative */
- return res; /* there is no status to set */
+ return res; /* there is no status to set */
}
workset.round=DEC_ROUND_CEILING;
sub=0; /* add, please */
} /* plus */
- else { /* lhs>rhs, do nextminus */
+ else { /* lhs>rhs, do nextminus */
/* +Infinity is the special case */
if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
decSetMaxValue(res, set);
- return res; /* there is no status to set */
+ return res; /* there is no status to set */
}
workset.round=DEC_ROUND_FLOOR;
sub=DECNEG; /* subtract, please */
} /* minus */
decNumberZero(&dtiny); /* start with 0 */
- dtiny.lsu[0]=1; /* make number that is .. */
+ dtiny.lsu[0]=1; /* make number that is .. */
dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */
decAddOp(res, lhs, &dtiny, &workset, sub, &status); /* + or - */
/* turn off exceptions if the result is a normal number */
/* */
/* res is C, the result. C may be A */
/* rhs is A */
-/* set is the context */
+/* set is the context */
/* */
/* See also decNumberCopy for a quiet bitwise version of this. */
/* C must have space for set->digits digits. */
#endif
decNumberZero(&dzero); /* make 0 */
- dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
+ dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
decAddOp(res, &dzero, rhs, set, 0, &status);
if (status!=0) decStatus(res, status, set);
#if DECCHECK
/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* res is C, the result. C may be A and/or B (e.g., X=X**X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* */
/* */
/* The final result is rounded according to the context; it will */
/* almost always be correctly rounded, but may be up to 1 ulp in */
-/* error in rare cases. */
+/* error in rare cases. */
/* ------------------------------------------------------------------ */
decNumber * decNumberPower(decNumber *res, const decNumber *lhs,
const decNumber *rhs, decContext *set) {
Flag seenbit; /* seen a bit while powering */
Int residue=0; /* rounding residue */
uInt status=0; /* accumulators */
- uByte bits=0; /* result sign if errors */
+ uByte bits=0; /* result sign if errors */
decContext aset; /* working context */
decNumber dnOne; /* work value 1... */
/* local accumulator buffer [a decNumber, with digits+elength+1 digits] */
if (decNumberIsNegative(lhs) /* lhs<0 */
&& !decNumberIsZero(lhs)) /* .. */
status|=DEC_Invalid_operation;
- else { /* lhs >=0 */
+ else { /* lhs >=0 */
decNumberZero(&dnOne); /* set up 1 */
dnOne.lsu[0]=1;
decNumberCompare(dac, lhs, &dnOne, set); /* lhs ? 1 */
/* Original rhs may be an integer that fits and is in range */
n=decGetInt(rhs);
if (n!=BADINT) { /* it is an integer */
- rhsint=1; /* record the fact for 1**n */
+ rhsint=1; /* record the fact for 1**n */
isoddint=(Flag)n&1; /* [works even if big] */
if (n!=BIGEVEN && n!=BIGODD) /* can use integer path? */
useint=1; /* looks good */
}
if (decNumberIsNegative(lhs) /* -x .. */
- && isoddint) bits=DECNEG; /* .. to an odd power */
+ && isoddint) bits=DECNEG; /* .. to an odd power */
/* handle LHS infinity */
if (decNumberIsInfinite(lhs)) { /* [NaNs already handled] */
uByte rbits=rhs->bits; /* save */
if (rbits & DECNEG) { /* was a 0**(-n) */
#if DECSUBSET
- if (!set->extended) { /* [bad if subset] */
+ if (!set->extended) { /* [bad if subset] */
status|=DEC_Invalid_operation;
break;}
#endif
aset.clamp=0; /* and no concrete format */
/* calculate the result using exp(ln(lhs)*rhs), which can */
- /* all be done into the accumulator, dac. The precision needed */
+ /* all be done into the accumulator, dac. The precision needed */
/* is enough to contain the full information in the lhs (which */
/* is the total digits, including exponent), or the requested */
/* precision, if larger, + 4; 6 is used for the exponent */
if (!rhsint) { /* add padding */
Int shift=set->digits-1;
dac->digits=decShiftToMost(dac->lsu, 1, shift);
- dac->exponent=-shift; /* make 1.0000... */
+ dac->exponent=-shift; /* make 1.0000... */
status|=DEC_Inexact|DEC_Rounded; /* deemed inexact */
}
}
/* if a negative power the constant 1 is needed, and if not subset */
/* invert the lhs now rather than inverting the result later */
if (decNumberIsNegative(rhs)) { /* was a **-n [hence digits>0] */
- decNumber *inv=invbuff; /* asssume use fixed buffer */
+ decNumber *inv=invbuff; /* asssume use fixed buffer */
decNumberCopy(&dnOne, dac); /* dnOne=1; [needed now or later] */
#if DECSUBSET
if (set->extended) { /* need to calculate 1/lhs */
}
/* [the following two lines revealed an optimizer bug in a C++ */
/* compiler, with symptom: 5**3 -> 25, when n=n+n was used] */
- n=n<<1; /* move next bit to testable position */
+ n=n<<1; /* move next bit to testable position */
if (n<0) { /* top bit is set */
seenbit=1; /* OK, significant bit seen */
decMultiplyOp(dac, dac, lhs, &aset, &status); /* dac=dac*x */
}
if (i==31) break; /* that was the last bit */
- if (!seenbit) continue; /* no need to square 1 */
+ if (!seenbit) continue; /* no need to square 1 */
decMultiplyOp(dac, dac, dac, &aset, &status); /* dac=dac*dac [square] */
} /*i*/ /* 32 bits */
decCopyFit(res, dac, set, &residue, &status);
decFinish(res, set, &residue, &status); /* final cleanup */
#if DECSUBSET
- if (!set->extended) decTrim(res, set, 0, &dropped); /* trailing zeros */
+ if (!set->extended) decTrim(res, set, 0, 1, &dropped); /* trailing zeros */
#endif
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (allocdac!=NULL) free(allocdac); /* drop any storage used */
if (allocinv!=NULL) free(allocinv); /* .. */
/* res is C, the result. C may be A or B */
/* lhs is A, the number to adjust */
/* rhs is B, the number with exponent to match */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* */
/* ------------------------------------------------------------------ */
/* decNumberReduce -- remove trailing zeros */
/* */
-/* This computes C = 0 + A, and normalizes the result */
+/* This computes C = 0 + A, and normalizes the result */
/* */
/* res is C, the result. C may be A */
/* rhs is A */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
#endif
uInt status=0; /* as usual */
Int residue=0; /* as usual */
- Int dropped; /* work */
+ Int dropped; /* work */
#if DECCHECK
if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
/* reduce result to the requested length and copy to result */
decCopyFit(res, rhs, set, &residue, &status); /* copy & round */
decFinish(res, set, &residue, &status); /* cleanup/set flags */
- decTrim(res, set, 1, &dropped); /* normalize in place */
- } while(0); /* end protected */
+ decTrim(res, set, 1, 0, &dropped); /* normalize in place */
+ /* [may clamp] */
+ } while(0); /* end protected */
#if DECSUBSET
if (allocrhs !=NULL) free(allocrhs); /* .. */
/* res is C, the result. C may be A or B */
/* lhs is A, the number to adjust */
/* rhs is B, the requested exponent */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X%X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* res is C, the result. C may be A and/or B (e.g., X=X%X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* This computes C = A rot B (in base ten and rotating set->digits */
/* digits). */
/* */
-/* res is C, the result. C may be A and/or B (e.g., X=XrotX) */
+/* res is C, the result. C may be A and/or B (e.g., X=XrotX) */
/* lhs is A */
/* rhs is B, the number of digits to rotate (-ve to right) */
-/* set is the context */
+/* set is the context */
/* */
/* The digits of the coefficient of A are rotated to the left (if B */
/* is positive) or to the right (if B is negative) without adjusting */
/* the exponent or the sign of A. If lhs->digits is less than */
-/* set->digits the coefficient is padded with zeros on the left */
+/* set->digits the coefficient is padded with zeros on the left */
/* before the rotate. Any leading zeros in the result are removed */
/* as usual. */
/* */
&& !decNumberIsInfinite(res)) { /* lhs was infinite */
/* left-rotate to do; 0 < rotate < set->digits */
uInt units, shift; /* work */
- uInt msudigits; /* digits in result msu */
+ uInt msudigits; /* digits in result msu */
Unit *msu=res->lsu+D2U(res->digits)-1; /* current msu */
Unit *msumax=res->lsu+D2U(set->digits)-1; /* rotation msu */
- for (msu++; msu<=msumax; msu++) *msu=0; /* ensure high units=0 */
+ for (msu++; msu<=msumax; msu++) *msu=0; /* ensure high units=0 */
res->digits=set->digits; /* now full-length */
msudigits=MSUDIGITS(res->digits); /* actual digits in msu */
/* (reversing is easy and fast) */
decReverse(res->lsu+units, msumax); /* left part */
decReverse(res->lsu, res->lsu+units-1); /* right part */
- decReverse(res->lsu, msumax); /* whole */
+ decReverse(res->lsu, msumax); /* whole */
} /* whole units to rotate */
/* the rotation may have left an undetermined number of zeros */
/* on the left, so true length needs to be calculated */
/* ------------------------------------------------------------------ */
/* decNumberSameQuantum -- test for equal exponents */
/* */
-/* res is the result number, which will contain either 0 or 1 */
+/* res is the result number, which will contain either 0 or 1 */
/* lhs is a number to test */
/* rhs is the second (usually a pattern) */
/* */
} /* decNumberSameQuantum */
/* ------------------------------------------------------------------ */
-/* decNumberScaleB -- multiply by a power of 10 */
+/* decNumberScaleB -- multiply by a power of 10 */
/* */
-/* This computes C = A x 10**B where B is an integer (q=0) with */
+/* This computes C = A x 10**B where B is an integer (q=0) with */
/* maximum magnitude 2*(emax+digits) */
/* */
/* res is C, the result. C may be A or B */
/* lhs is A, the number to adjust */
/* rhs is B, the requested power of ten to use */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* */
const decNumber *rhs, decContext *set) {
Int reqexp; /* requested exponent change [B] */
uInt status=0; /* accumulator */
- Int residue; /* work */
+ Int residue; /* work */
#if DECCHECK
if (decCheckOperands(res, lhs, rhs, set)) return res;
/* res is C, the result. C may be A and/or B (e.g., X=X<<X) */
/* lhs is A */
/* rhs is B, the number of digits to shift (-ve to right) */
-/* set is the context */
+/* set is the context */
/* */
/* The digits of the coefficient of A are shifted to the left (if B */
/* is positive) or to the right (if B is negative) without adjusting */
else { /* both numeric, rhs is an integer */
shift=decGetInt(rhs); /* [cannot fail] */
if (shift==BADINT /* something bad .. */
- || shift==BIGODD || shift==BIGEVEN /* .. very big .. */
- || abs(shift)>set->digits) /* .. or out of range */
+ || shift==BIGODD || shift==BIGEVEN /* .. very big .. */
+ || abs(shift)>set->digits) /* .. or out of range */
status=DEC_Invalid_operation;
else { /* rhs is OK */
decNumberCopy(res, lhs);
/* if x < 0 then */
/* assert false */
/* else */
-/* result 0 */
+/* result 0 */
/* end if */
/* end if */
-/* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */
+/* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */
/* var e := getexp(x) % exponent part of x */
/* var approx : real */
-/* if e mod 2 = 0 then */
+/* if e mod 2 = 0 then */
/* approx := .259 + .819 * f % approx to root of f */
-/* else */
+/* else */
/* f := f/l0 % adjustments */
-/* e := e + 1 % for odd */
-/* approx := .0819 + 2.59 * f % exponent */
+/* e := e + 1 % for odd */
+/* approx := .0819 + 2.59 * f % exponent */
/* end if */
/* */
/* var p:= 3 */
/* const maxp := currentprecision + 2 */
-/* loop */
+/* loop */
/* p := min(2*p - 2, maxp) % p = 4,6,10, . . . , maxp */
/* precision p */
-/* approx := .5 * (approx + f/approx) */
-/* exit when p = maxp */
+/* approx := .5 * (approx + f/approx) */
+/* exit when p = maxp */
/* end loop */
/* */
/* % approx is now within 1 ulp of the properly rounded square root */
Int workp; /* working precision */
Int residue=0; /* rounding residue */
uInt status=0, ignore=0; /* status accumulators */
- uInt rstatus; /* .. */
+ uInt rstatus; /* .. */
Int exp; /* working exponent */
Int ideal; /* ideal (preferred) exponent */
Int needbytes; /* work */
- Int dropped; /* .. */
+ Int dropped; /* .. */
#if DECSUBSET
decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */
}
/* calculate the ideal (preferred) exponent [floor(exp/2)] */
- /* [We would like to write: ideal=rhs->exponent>>1, but this */
+ /* [It would be nicer to write: ideal=rhs->exponent>>1, but this */
/* generates a compiler warning. Generated code is the same.] */
- ideal=(rhs->exponent&~1)/2; /* target */
+ ideal=(rhs->exponent&~1)/2; /* target */
/* handle zeros */
if (ISZERO(rhs)) {
/* b -- intermediate temporary result (same size as a) */
/* if any is too long for local storage, then allocate */
workp=MAXI(set->digits+1, rhs->digits); /* actual rounding precision */
+ workp=MAXI(workp, 7); /* at least 7 for low cases */
maxp=workp+2; /* largest working precision */
needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
if (needbytes>(Int)sizeof(bufa)) { /* [same applies to b] */
allocbufa=(decNumber *)malloc(needbytes);
allocbufb=(decNumber *)malloc(needbytes);
- if (allocbufa==NULL || allocbufb==NULL) { /* hopeless */
+ if (allocbufa==NULL || allocbufb==NULL) { /* hopeless */
status|=DEC_Insufficient_storage;
break;}
a=allocbufa; /* use the allocated spaces */
/* set up working context */
decContextDefault(&workset, DEC_INIT_DECIMAL64);
+ workset.emax=DEC_MAX_EMAX;
+ workset.emin=DEC_MIN_EMIN;
/* [Until further notice, no error is possible and status bits */
/* (Rounded, etc.) should be ignored, not accumulated.] */
workset.digits=workp; /* p for initial calculation */
t->bits=0; t->digits=3;
a->bits=0; a->digits=3;
- if ((exp & 1)==0) { /* even exponent */
+ if ((exp & 1)==0) { /* even exponent */
/* Set t=0.259, a=0.819 */
t->exponent=-3;
a->exponent=-3;
a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
#endif
}
+
decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */
decAddOp(a, a, t, &workset, 0, &ignore); /* ..+t */
/* [a is now the initial approximation for sqrt(f), calculated with */
t->lsu[0]=5; /* .. */
t->exponent=-1; /* .. */
workset.digits=3; /* initial p */
- for (;;) {
+ for (; workset.digits<maxp;) {
/* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */
- workset.digits=workset.digits*2-2;
- if (workset.digits>maxp) workset.digits=maxp;
+ workset.digits=MINI(workset.digits*2-2, maxp);
/* a = 0.5 * (a + f/a) */
/* [calculated at p then rounded to currentprecision] */
decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a */
- decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */
- decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */
- if (a->digits==maxp) break; /* have required digits */
+ decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */
+ decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */
} /* loop */
/* Here, 0.1 <= a < 1 [Hull], and a has maxp digits */
/* correctly */
approxset=*set; /* get emin, emax, etc. */
approxset.round=DEC_ROUND_HALF_EVEN;
- a->exponent+=exp/2; /* set correct exponent */
-
+ a->exponent+=exp/2; /* set correct exponent */
rstatus=0; /* clear status */
residue=0; /* .. and accumulator */
decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */
status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));
/* Carry out the Hull correction */
- a->exponent-=exp/2; /* back to 0.1->1 */
+ a->exponent-=exp/2; /* back to 0.1->1 */
/* a is now at final precision and within 1 ulp of the properly */
/* rounded square root of f; to ensure proper rounding, compare */
/* estimation are irrelevant, so status was not accumulated] */
/* Here, 0.1 <= a < 1 (still), so adjust back */
- a->exponent+=exp/2; /* set correct exponent */
+ a->exponent+=exp/2; /* set correct exponent */
/* count droppable zeros [after any subnormal rounding] by */
/* trimming a copy */
decNumberCopy(b, a);
- decTrim(b, set, 1, &dropped); /* [drops trailing zeros] */
+ decTrim(b, set, 1, 1, &dropped); /* [drops trailing zeros] */
- /* Set Inexact and Rounded. The answer can only be exact if */
- /* it is short enough so that squaring it could fit in workp digits, */
- /* and it cannot have trailing zeros due to clamping, so these are */
- /* the only (relatively rare) conditions a careful check is needed */
- if (b->digits*2-1 > workp && !set->clamp) { /* cannot fit */
+ /* Set Inexact and Rounded. The answer can only be exact if */
+ /* it is short enough so that squaring it could fit in workp */
+ /* digits, so this is the only (relatively rare) condition that */
+ /* a careful check is needed */
+ if (b->digits*2-1 > workp) { /* cannot fit */
status|=DEC_Inexact|DEC_Rounded;
}
else { /* could be exact/unrounded */
else { /* plausible */
decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); /* b ? rhs */
if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; /* not equal */
- else { /* is Exact */
+ else { /* is Exact */
/* here, dropped is the count of trailing zeros in 'a' */
/* use closest exponent to ideal... */
- Int todrop=ideal-a->exponent; /* most that can be dropped */
+ Int todrop=ideal-a->exponent; /* most that can be dropped */
if (todrop<0) status|=DEC_Rounded; /* ideally would add 0s */
else { /* unrounded */
+ /* there are some to drop, but emax may not allow all */
+ Int maxexp=set->emax-set->digits+1;
+ Int maxdrop=maxexp-a->exponent;
+ if (todrop>maxdrop && set->clamp) { /* apply clamping */
+ todrop=maxdrop;
+ status|=DEC_Clamped;
+ }
if (dropped<todrop) { /* clamp to those available */
todrop=dropped;
status|=DEC_Clamped;
}
decNumberCopy(res, a); /* a is now the result */
- } while(0); /* end protected */
+ } while(0); /* end protected */
- if (allocbuff!=NULL) free(allocbuff); /* drop any storage used */
- if (allocbufa!=NULL) free(allocbufa); /* .. */
- if (allocbufb!=NULL) free(allocbufb); /* .. */
+ if (allocbuff!=NULL) free(allocbuff); /* drop any storage used */
+ if (allocbufa!=NULL) free(allocbufa); /* .. */
+ if (allocbufb!=NULL) free(allocbufb); /* .. */
#if DECSUBSET
if (allocrhs !=NULL) free(allocrhs); /* .. */
#endif
/* res is C, the result. C may be A and/or B (e.g., X=X-X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* */
/* C must have space for set->digits digits. */
/* ------------------------------------------------------------------ */
/* */
/* res is the result */
/* rhs is input number */
-/* set is the context */
+/* set is the context */
/* */
/* res must have space for any value of rhs. */
/* */
if (rhs->exponent>=0) return decNumberCopy(res, rhs);
/* that was easy, but if negative exponent there is work to do... */
workset=*set; /* clone rounding, etc. */
- workset.digits=rhs->digits; /* no length rounding */
+ workset.digits=rhs->digits; /* no length rounding */
workset.traps=0; /* no traps */
- decNumberZero(&dn); /* make a number with exponent 0 */
+ decNumberZero(&dn); /* make a number with exponent 0 */
decNumberQuantize(res, rhs, &dn, &workset);
status|=workset.status;
}
/* ================================================================== */
/* ------------------------------------------------------------------ */
-/* decNumberClass -- return the decClass of a decNumber */
+/* decNumberClass -- return the decClass of a decNumber */
/* dn -- the decNumber to test */
-/* set -- the context to use for Emin */
+/* set -- the context to use for Emin */
/* returns the decClass enum */
/* ------------------------------------------------------------------ */
enum decClass decNumberClass(const decNumber *dn, decContext *set) {
const Unit *smsup, *s; /* work */
Unit *d; /* .. */
/* memcpy for the remaining Units would be safe as they cannot */
- /* overlap. However, this explicit loop is faster in short cases. */
+ /* overlap. However, this explicit loop is faster in short cases. */
d=dest->lsu+1; /* -> first destination */
smsup=src->lsu+D2U(src->digits); /* -> source msu+1 */
for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
/* ------------------------------------------------------------------ */
/* decNumberCopySign -- quiet copy and set sign operator */
/* */
-/* This sets C = A with the sign of B */
+/* This sets C = A with the sign of B */
/* */
/* res is C, the result. C may be A */
/* lhs is A */
/* ------------------------------------------------------------------ */
/* decNumberGetBCD -- get the coefficient in BCD8 */
-/* dn is the source decNumber */
+/* dn is the source decNumber */
/* bcd is the uInt array that will receive dn->digits BCD bytes, */
/* most-significant at offset 0 */
/* returns bcd */
/* bcd must have at least dn->digits bytes. No error is possible; if */
/* dn is a NaN or Infinite, digits must be 1 and the coefficient 0. */
/* ------------------------------------------------------------------ */
-uByte * decNumberGetBCD(const decNumber *dn, uint8_t *bcd) {
+uByte * decNumberGetBCD(const decNumber *dn, uByte *bcd) {
uByte *ub=bcd+dn->digits-1; /* -> lsd */
const Unit *up=dn->lsu; /* Unit pointer, -> lsu */
#if DECDPUN==1 /* trivial simple copy */
for (; ub>=bcd; ub--, up++) *ub=*up;
- #else /* chopping needed */
- uInt u=*up; /* work */
+ #else /* chopping needed */
+ uInt u=*up; /* work */
uInt cut=DECDPUN; /* downcounter through unit */
for (; ub>=bcd; ub--) {
*ub=(uByte)(u%10); /* [*6554 trick inhibits, here] */
/* ------------------------------------------------------------------ */
/* decNumberSetBCD -- set (replace) the coefficient from BCD8 */
-/* dn is the target decNumber */
+/* dn is the target decNumber */
/* bcd is the uInt array that will source n BCD bytes, most- */
/* significant at offset 0 */
/* n is the number of digits in the source BCD array (bcd) */
-/* returns dn */
+/* returns dn */
/* */
/* dn must have space for at least n digits. No error is possible; */
/* if dn is a NaN, or Infinite, or is to become a zero, n must be 1 */
#if DECDPUN==1 /* trivial simple copy */
for (; ub<bcd+n; ub++, up--) *up=*ub;
- #else /* some assembly needed */
+ #else /* some assembly needed */
/* calculate how many digits in msu, and hence first cut */
Int cut=MSUDIGITS(n); /* [faster than remainder] */
for (;up>=dn->lsu; up--) { /* each Unit from msu */
cut=DECDPUN; /* next Unit has all digits */
}
#endif
- dn->digits=n; /* set digit count */
+ dn->digits=n; /* set digit count */
return dn;
} /* decNumberSetBCD */
/* ------------------------------------------------------------------ */
/* decNumberIsNormal -- test normality of a decNumber */
/* dn is the decNumber to test */
-/* set is the context to use for Emin */
+/* set is the context to use for Emin */
/* returns 1 if |dn| is finite and >=Nmin, 0 otherwise */
/* ------------------------------------------------------------------ */
Int decNumberIsNormal(const decNumber *dn, decContext *set) {
if (decNumberIsSpecial(dn)) return 0; /* not finite */
if (decNumberIsZero(dn)) return 0; /* not non-zero */
- ae=dn->exponent+dn->digits-1; /* adjusted exponent */
+ ae=dn->exponent+dn->digits-1; /* adjusted exponent */
if (ae<set->emin) return 0; /* is subnormal */
return 1;
} /* decNumberIsNormal */
/* ------------------------------------------------------------------ */
/* decNumberIsSubnormal -- test subnormality of a decNumber */
/* dn is the decNumber to test */
-/* set is the context to use for Emin */
+/* set is the context to use for Emin */
/* returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise */
/* ------------------------------------------------------------------ */
Int decNumberIsSubnormal(const decNumber *dn, decContext *set) {
if (decNumberIsSpecial(dn)) return 0; /* not finite */
if (decNumberIsZero(dn)) return 0; /* not non-zero */
- ae=dn->exponent+dn->digits-1; /* adjusted exponent */
+ ae=dn->exponent+dn->digits-1; /* adjusted exponent */
if (ae<set->emin) return 1; /* is subnormal */
return 0;
} /* decNumberIsSubnormal */
/* decNumberTrim -- remove insignificant zeros */
/* */
/* dn is the number to trim */
-/* returns dn */
+/* returns dn */
/* */
/* All fields are updated as required. This is a utility operation, */
-/* so special values are unchanged and no error is possible. */
+/* so special values are unchanged and no error is possible. The */
+/* zeros are removed unconditionally. */
/* ------------------------------------------------------------------ */
decNumber * decNumberTrim(decNumber *dn) {
- Int dropped; /* work */
+ Int dropped; /* work */
decContext set; /* .. */
#if DECCHECK
if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
#endif
decContextDefault(&set, DEC_INIT_BASE); /* clamp=0 */
- return decTrim(dn, &set, 0, &dropped);
+ return decTrim(dn, &set, 0, 1, &dropped);
} /* decNumberTrim */
/* ------------------------------------------------------------------ */
/* decNumberZero -- set a number to 0 */
/* */
/* dn is the number to set, with space for one digit */
-/* returns dn */
+/* returns dn */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
/* decToString -- lay out a number into a string */
/* */
-/* dn is the number to lay out */
+/* dn is the number to lay out */
/* string is where to lay out the number */
/* eng is 1 if Engineering, 0 if Scientific */
/* */
/* If DECCHECK is enabled the string "?" is returned if a number is */
/* invalid. */
static void decToString(const decNumber *dn, char *string, Flag eng) {
- Int exp=dn->exponent; /* local copy */
+ Int exp=dn->exponent; /* local copy */
Int e; /* E-part value */
Int pre; /* digits before the '.' */
Int cut; /* for counting digits in a Unit */
}
if (dn->bits&DECSPECIAL) { /* Is a special value */
if (decNumberIsInfinite(dn)) {
- strcpy(c, "Inf");
+ strcpy(c, "Inf");
strcpy(c+3, "inity");
return;}
/* a NaN */
cut=MSUDIGITS(dn->digits); /* [faster than remainder] */
cut--; /* power of ten for digit */
- if (exp==0) { /* simple integer [common fastpath] */
+ if (exp==0) { /* simple integer [common fastpath] */
for (;up>=dn->lsu; up--) { /* each Unit from msu */
u=*up; /* contains DECDPUN digits to lay out */
for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);
pre=dn->digits+exp; /* digits before '.' */
e=0; /* no E */
if ((exp>0) || (pre<-5)) { /* need exponential form */
- e=exp+dn->digits-1; /* calculate E value */
+ e=exp+dn->digits-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
if (eng && (e!=0)) { /* engineering: may need to adjust */
Int adj; /* adjustment */
Int n=pre;
for (; pre>0; pre--, c++, cut--) {
if (cut<0) { /* need new Unit */
- if (up==dn->lsu) break; /* out of input digits (pre>digits) */
+ if (up==dn->lsu) break; /* out of input digits (pre>digits) */
up--;
cut=DECDPUN-1;
u=*up;
}
TODIGIT(u, cut, c, pow);
}
- if (n<dn->digits) { /* more to come, after '.' */
+ if (n<dn->digits) { /* more to come, after '.' */
*c='.'; c++;
for (;; c++, cut--) {
if (cut<0) { /* need new Unit */
for (; pre<0; pre++, c++) *c='0'; /* add any 0's after '.' */
for (; ; c++, cut--) {
if (cut<0) { /* need new Unit */
- if (up==dn->lsu) break; /* out of input digits */
+ if (up==dn->lsu) break; /* out of input digits */
up--;
cut=DECDPUN-1;
u=*up;
}
}
- /* Finally add the E-part, if needed. It will never be 0, has a
+ /* Finally add the E-part, if needed. It will never be 0, has a
base maximum and minimum of +999999999 through -999999999, but
could range down to -1999999998 for anormal numbers */
if (e!=0) {
- Flag had=0; /* 1=had non-zero */
+ Flag had=0; /* 1=had non-zero */
*c='E'; c++;
*c='+'; c++; /* assume positive */
u=e; /* .. */
/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* negate is DECNEG if rhs should be negated, or 0 otherwise */
/* status accumulates status for the caller */
/* */
/* Inexact in status must be 0 for correct Exact zero sign in result */
/* ------------------------------------------------------------------ */
/* If possible, the coefficient is calculated directly into C. */
-/* However, if: */
+/* However, if: */
/* -- a digits+1 calculation is needed because the numbers are */
-/* unaligned and span more than set->digits digits */
+/* unaligned and span more than set->digits digits */
/* -- a carry to digits+1 digits looks possible */
/* -- C is the same as A or B, and the result would destructively */
/* overlap the A or B coefficient */
Unit accbuff[SD2U(DECBUFFER*2+20)]; /* local buffer [*2+20 reduces many */
/* allocations when called from */
/* other operations, notable exp] */
- Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */
+ Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */
Int reqdigits=set->digits; /* local copy; requested DIGITS */
Int padding; /* work */
else bits=(rhs->bits^negate) & DECNEG;/* RHS must be Infinity */
bits|=DECINF;
decNumberZero(res);
- res->bits=bits; /* set +/- infinity */
+ res->bits=bits; /* set +/- infinity */
} /* an infinity */
break;
}
#endif
/* exponent will be the lower of the two */
adjust=lexp-res->exponent; /* adjustment needed [if -ve] */
- if (ISZERO(res)) { /* both 0: special IEEE 854 rules */
+ if (ISZERO(res)) { /* both 0: special IEEE 754 rules */
if (adjust<0) res->exponent=lexp; /* set exponent */
/* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */
if (diffsign) {
/* exponent will be the lower of the two */
/* [0-0 case handled above] */
adjust=rexp-res->exponent; /* adjustment needed [if -ve] */
- if (adjust<0) { /* 0-padding needed */
+ if (adjust<0) { /* 0-padding needed */
if ((res->digits-adjust)>set->digits) {
adjust=res->digits-set->digits; /* to fit exactly */
*status|=DEC_Rounded; /* [but exact] */
/* other) padding with up to DIGITS-1 trailing zeros may be */
/* needed; then apply rounding (as exotic rounding modes may be */
/* affected by the residue). */
- rhsshift=0; /* rhs shift to left (padding) in Units */
+ rhsshift=0; /* rhs shift to left (padding) in Units */
bits=lhs->bits; /* assume sign is that of LHS */
mult=1; /* likely multiplier */
/* for residue use the relative sign indication... */
Int shift=reqdigits-rhs->digits; /* left shift needed */
residue=1; /* residue for rounding */
- if (diffsign) residue=-residue; /* signs differ */
+ if (diffsign) residue=-residue; /* signs differ */
/* copy, shortening if necessary */
decCopyFit(res, rhs, set, &residue, status);
/* if it was already shorter, then need to pad with zeros */
if (shift>0) {
res->digits=decShiftToMost(res->lsu, res->digits, shift);
- res->exponent-=shift; /* adjust the exponent. */
+ res->exponent-=shift; /* adjust the exponent. */
}
/* flip the result sign if unswapped and rhs was negated */
if (!swapped) res->bits^=negate;
if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG; /* sign - */
else res->bits&=~DECNEG; /* sign + */
}
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (allocacc!=NULL) free(allocacc); /* drop any storage used */
#if DECSUBSET
/* res is C, the result. C may be A and/or B (e.g., X=X/X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
-/* op is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively. */
+/* set is the context */
+/* op is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively. */
/* status is the usual accumulator */
/* */
/* C must have space for set->digits digits. */
/* */
/* Prepare operands and handle special values */
/* Test for x/0 and then 0/x */
-/* Exp =Exp1 - Exp2 */
+/* Exp =Exp1 - Exp2 */
/* Exp =Exp +len(var1) -len(var2) */
/* Sign=Sign1 * Sign2 */
/* Pad accumulator (Var1) to double-length with 0's (pad1) */
/* this_unit=0 */
/* Do forever */
/* compare numbers */
-/* if <0 then leave inner_loop */
+/* if <0 then leave inner_loop */
/* if =0 then (* quick exit without subtract *) do */
/* this_unit=this_unit+1; output this_unit */
/* leave outer_loop; end */
/* If same then tops2=msu2pair -- {units 1&2 of var2} */
/* else tops2=msu2plus -- {0, unit 1 of var2} */
/* tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */
-/* mult=tops1/tops2 -- Good and safe guess at divisor */
+/* mult=tops1/tops2 -- Good and safe guess at divisor */
/* if mult=0 then mult=1 */
/* this_unit=this_unit+mult */
/* subtract */
/* exp=exp-1 */
/* end outer_loop */
/* exp=exp+1 -- set the proper exponent */
-/* if have=0 then generate answer=0 */
+/* if have=0 then generate answer=0 */
/* Return (Result is defined by Var1) */
/* */
/* ------------------------------------------------------------------ */
#endif
Unit accbuff[SD2U(DECBUFFER+DECDPUN+10)]; /* local buffer */
Unit *acc=accbuff; /* -> accumulator array for result */
- Unit *allocacc=NULL; /* -> allocated buffer, iff allocated */
+ Unit *allocacc=NULL; /* -> allocated buffer, iff allocated */
Unit *accnext; /* -> where next digit will go */
Int acclength; /* length of acc needed [Units] */
Int accunits; /* count of units accumulated */
Int accdigits; /* count of digits accumulated */
- Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)*sizeof(Unit)]; /* buffer for var1 */
+ Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)]; /* buffer for var1 */
Unit *var1=varbuff; /* -> var1 array for long subtraction */
- Unit *varalloc=NULL; /* -> allocated buffer, iff used */
+ Unit *varalloc=NULL; /* -> allocated buffer, iff used */
Unit *msu1; /* -> msu of var1 */
const Unit *var2; /* -> var2 array */
/* result is [finished clone of] lhs */
decCopyFit(res, lhs, set, &residue, status);
}
- else { /* a division */
+ else { /* a division */
decNumberZero(res);
res->bits=bits; /* set +/- zero */
/* for DIVIDEINT the exponent is always 0. For DIVIDE, result */
decNumberZero(res); /* integer 0 */
res->bits=bits; /* sign as computed */
}
- else { /* a remainder */
+ else { /* a remainder */
exponent=rhs->exponent; /* [save in case overwrite] */
decNumberCopy(res, lhs); /* [zeros always fit] */
if (exponent<res->exponent) res->exponent=exponent; /* use lower */
for (; target>=var1; target--) *target=0;
/* rhs (var2) is left-aligned with var1 at the start */
- var2ulen=var1units; /* rhs logical length (units) */
- var2units=D2U(rhs->digits); /* rhs actual length (units) */
+ var2ulen=var1units; /* rhs logical length (units) */
+ var2units=D2U(rhs->digits); /* rhs actual length (units) */
var2=rhs->lsu; /* -> rhs array */
msu2=var2+var2units-1; /* -> msu of var2 [never changes] */
/* now set up the variables which will be used for estimating the */
for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++;
/* Now, if doing an integer divide or remainder, ensure that */
- /* the result will be Unit-aligned. To do this, shift the var1 */
+ /* the result will be Unit-aligned. To do this, shift the var1 */
/* accumulator towards least if need be. (It's much easier to */
/* do this now than to reassemble the residue afterwards, if */
/* doing a remainder.) Also ensure the exponent is not negative. */
else cut=DECDPUN-exponent%DECDPUN;
decShiftToLeast(var1, var1units, cut);
exponent+=cut; /* maintain numerical value */
- var1initpad-=cut; /* .. and reduce padding */
+ var1initpad-=cut; /* .. and reduce padding */
/* clean any most-significant units which were just emptied */
for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;
} /* align */
}
/* ---- start the long-division loops ------------------------------ */
- accunits=0; /* no units accumulated yet */
+ accunits=0; /* no units accumulated yet */
accdigits=0; /* .. or digits */
accnext=acc+acclength-1; /* -> msu of acc [NB: allows digits+1] */
for (;;) { /* outer forever loop */
/* reach here if var1 and var2 are identical; subtraction */
/* would increase digit by one, and the residue will be 0 so */
/* the calculation is done; leave the loop with residue=0. */
- thisunit++; /* as though subtracted */
+ thisunit++; /* as though subtracted */
*var1=0; /* set var1 to 0 */
var1units=1; /* .. */
break; /* from inner */
}
if (mult==0) mult=1; /* must always be at least 1 */
/* subtraction needed; var1 is > var2 */
- thisunit=(Unit)(thisunit+mult); /* accumulate */
+ thisunit=(Unit)(thisunit+mult); /* accumulate */
/* subtract var1-var2, into var1; only the overlap needs */
/* processing, as this is an in-place calculation */
shift=var2ulen-var2units;
/* The next unit has been calculated in full; unless it's a */
/* leading zero, add to acc */
- if (accunits!=0 || thisunit!=0) { /* is first or non-zero */
+ if (accunits!=0 || thisunit!=0) { /* is first or non-zero */
*accnext=thisunit; /* store in accumulator */
/* account exactly for the new digits */
if (accunits==0) {
else accdigits+=DECDPUN;
accunits++; /* update count */
accnext--; /* ready for next */
- if (accdigits>reqdigits) break; /* have enough digits */
+ if (accdigits>reqdigits) break; /* have enough digits */
}
/* if the residue is zero, the operation is done (unless divide */
if ((lsu-QUOT10(lsu, drop+1)
*powers[drop+1])!=0) break; /* found non-0 digit */
#else
- if (lsu%powers[drop+1]!=0) break; /* found non-0 digit */
+ if (lsu%powers[drop+1]!=0) break; /* found non-0 digit */
#endif
exponent++;
}
Unit *quotlsu; /* for save */
Int quotdigits; /* .. */
- bits=lhs->bits; /* remainder sign is always as lhs */
+ bits=lhs->bits; /* remainder sign is always as lhs */
/* Fastpath when residue is truly 0 is worthwhile [and */
/* simplifies the code below] */
- if (*var1==0 && var1units==1) { /* residue is 0 */
+ if (*var1==0 && var1units==1) { /* residue is 0 */
Int exp=lhs->exponent; /* save min(exponents) */
if (rhs->exponent<exp) exp=rhs->exponent;
decNumberZero(res); /* 0 coefficient */
accdigits=decGetDigits(var1, var1units);
accunits=D2U(accdigits);
- exponent=lhs->exponent; /* exponent is smaller of lhs & rhs */
+ exponent=lhs->exponent; /* exponent is smaller of lhs & rhs */
if (rhs->exponent<exponent) exponent=rhs->exponent;
/* Now correct the result if doing remainderNear; if it */
if (quotdigits>DECDPUN) {
if (*up!=DECDPUNMAX) break;/* non-nines */
}
- else { /* this is the last Unit */
+ else { /* this is the last Unit */
if (*up==powers[quotdigits]-1) allnines=1;
break;
}
*status|=DEC_Division_impossible;
break;}
- /* rem-rhs is needed; the sign will invert. Again, var1 */
+ /* rem-rhs is needed; the sign will invert. Again, var1 */
/* can safely be used for the working Units array. */
- exp=rhs->exponent-exponent; /* RHS padding needed */
+ exp=rhs->exponent-exponent; /* RHS padding needed */
/* Calculate units and remainder from exponent. */
expunits=exp/DECDPUN;
exprem=exp%DECDPUN;
#if DECSUBSET
/* If a divide then strip trailing zeros if subset [after round] */
- if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, &dropped);
+ if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped);
#endif
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (varalloc!=NULL) free(varalloc); /* drop any storage used */
if (allocacc!=NULL) free(allocacc); /* .. */
/* res is C, the result. C may be A and/or B (e.g., X=X*X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
+/* set is the context */
/* status is the usual accumulator */
/* */
/* C must have space for set->digits digits. */
/* The fastpath version lumps units together into 8-digit or 9-digit */
/* chunks, and also uses a lazy carry strategy to minimise expensive */
/* 64-bit divisions. The chunks are then broken apart again into */
-/* units for continuing processing. Despite this overhead, the */
+/* units for continuing processing. Despite this overhead, the */
/* fastpath can speed up some 16-digit operations by 10x (and much */
/* more for higher-precision calculations). */
/* */
/* A buffer always has to be used for the accumulator; in the */
/* fastpath, buffers are also always needed for the chunked copies of */
-/* of the operand coefficients. */
+/* of the operand coefficients. */
/* Static buffers are larger than needed just for multiply, to allow */
/* for calls from other operations (notably exp). */
/* ------------------------------------------------------------------ */
Int accunits; /* Units of accumulator in use */
Int exponent; /* work */
Int residue=0; /* rounding residue */
- uByte bits; /* result sign */
+ uByte bits; /* result sign */
Unit *acc; /* -> accumulator Unit array */
Int needbytes; /* size calculator */
- void *allocacc=NULL; /* -> allocated accumulator, iff allocated */
+ void *allocacc=NULL; /* -> allocated accumulator, iff allocated */
Unit accbuff[SD2U(DECBUFFER*4+1)]; /* buffer (+1 for DECBUFFER==0, */
/* *4 for calls from other operations) */
const Unit *mer, *mermsup; /* work */
/* [allocacc is shared for both paths, as only one will run] */
uLong *zacc=zaccbuff; /* -> accumulator array for exact result */
#if DECDPUN==1
- Int zoff; /* accumulator offset */
+ Int zoff; /* accumulator offset */
#endif
uInt *lip, *rip; /* item pointers */
- uInt *lmsi, *rmsi; /* most significant items */
- Int ilhs, irhs, iacc; /* item counts in the arrays */
- Int lazy; /* lazy carry counter */
+ uInt *lmsi, *rmsi; /* most significant items */
+ Int ilhs, irhs, iacc; /* item counts in the arrays */
+ Int lazy; /* lazy carry counter */
uLong lcarry; /* uLong carry */
uInt carry; /* carry (NB not uLong) */
- Int count; /* work */
+ Int count; /* work */
const Unit *cup; /* .. */
Unit *up; /* .. */
uLong *lp; /* .. */
- Int p; /* .. */
+ Int p; /* .. */
#endif
#if DECSUBSET
#endif
/* [following code does not require input rounding] */
- #if FASTMUL /* fastpath can be used */
+ #if FASTMUL /* fastpath can be used */
/* use the fast path if there are enough digits in the shorter */
/* operand to make the setup and takedown worthwhile */
- #define NEEDTWO (DECDPUN*2) /* within two decUnitAddSub calls */
+ #define NEEDTWO (DECDPUN*2) /* within two decUnitAddSub calls */
if (rhs->digits>NEEDTWO) { /* use fastpath... */
/* calculate the number of elements in each array */
ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; /* [ceiling] */
/* Allocating the accumulator space needs a special case when */
/* DECDPUN=1 because when converting the accumulator to Units */
/* after the multiplication each 8-byte item becomes 9 1-byte */
- /* units. Therefore iacc extra bytes are needed at the front */
+ /* units. Therefore iacc extra bytes are needed at the front */
/* (rounded up to a multiple of 8 bytes), and the uLong */
/* accumulator starts offset the appropriate number of units */
/* to the right to avoid overwrite during the unchunking. */
*status|=DEC_Insufficient_storage;
break;}
- acc=(Unit *)zacc; /* -> target Unit array */
+ acc=(Unit *)zacc; /* -> target Unit array */
#if DECDPUN==1
zacc+=zoff; /* start uLong accumulator to right */
#endif
carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); /* [inline] */
}
*(lp+1)+=carry; /* add to item above [inline] */
- *lp-=((uLong)FASTBASE*carry); /* [inline] */
+ *lp-=((uLong)FASTBASE*carry); /* [inline] */
} /* carry resolution */
} /* rip loop */
/* The multiplication is complete; time to convert back into */
- /* units. This can be done in-place in the accumulator and in */
+ /* units. This can be done in-place in the accumulator and in */
/* 32-bit operations, because carries were resolved after the */
/* final add. This needs N-1 divides and multiplies for */
/* each item in the accumulator (which will become up to N */
/* There can be a 31-bit wrap in calculating the exponent. */
/* This can only happen if both input exponents are negative and */
- /* both their magnitudes are large. If there was a wrap, set a */
+ /* both their magnitudes are large. If there was a wrap, set a */
/* safe very negative exponent, from which decFinalize() will */
/* raise a hard underflow shortly. */
exponent=lhs->exponent+rhs->exponent; /* calculate exponent */
/* Set the coefficient. If any rounding, residue records */
decSetCoeff(res, set, acc, res->digits, &residue, status);
decFinish(res, set, &residue, status); /* final cleanup */
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (allocacc!=NULL) free(allocacc); /* drop any storage used */
#if DECSUBSET
/* Restrictions: */
/* */
/* digits, emax, and -emin in the context must be less than */
-/* 2*DEC_MAX_MATH (1999998), and the rhs must be within these */
+/* 2*DEC_MAX_MATH (1999998), and the rhs must be within these */
/* bounds or a zero. This is an internal routine, so these */
/* restrictions are contractual and not enforced. */
/* */
/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */
/* almost always be correctly rounded, but may be up to 1 ulp in */
-/* error in rare cases. */
+/* error in rare cases. */
/* */
/* Finite results will always be full precision and Inexact, except */
/* when A is a zero or -Infinity (giving 1 or 0 respectively). */
/* The error analysis in Hull & Abrham's paper applies except for the */
/* round-off error accumulation during the series evaluation. This */
/* code does not precalculate the number of iterations and so cannot */
-/* use Horner's scheme. Instead, the accumulation is done at double- */
+/* use Horner's scheme. Instead, the accumulation is done at double- */
/* precision, which ensures that the additions of the terms are exact */
/* and do not accumulate round-off (and any round-off errors in the */
/* terms themselves move 'to the right' faster than they can */
-/* accumulate). This code also extends the calculation by allowing, */
+/* accumulate). This code also extends the calculation by allowing, */
/* in the spirit of other decNumber operators, the input to be more */
/* precise than the result (the precision used is based on the more */
/* precise of the input or requested result). */
/* more for smaller values. */
/* */
/* The leverage that can be applied in this way is severely */
-/* limited by the cost of the raise-to-the power at the end, */
+/* limited by the cost of the raise-to-the power at the end, */
/* which dominates when the number of iterations is small (less */
/* than ten) or when rhs is short. As an example, the adjustment */
/* x**10,000,000 needs 31 multiplications, all but one full-width. */
*d->lsu=4; /* set 4 .. */
d->exponent=-set->digits; /* * 10**(-d) */
if (decNumberIsNegative(rhs)) d->exponent--; /* negative case */
- comp=decCompare(d, rhs, 1); /* signless compare */
+ comp=decCompare(d, rhs, 1); /* signless compare */
if (comp==BADINT) {
*status|=DEC_Insufficient_storage;
break;}
/* front" effect. */
Int lever=MINI(8-h, maxlever); /* leverage attainable */
Int use=-rhs->digits-lever; /* exponent to use for RHS */
- h+=lever; /* apply leverage selected */
+ h+=lever; /* apply leverage selected */
if (h<0) { /* clamp */
- use+=h; /* [may end up subnormal] */
+ use+=h; /* [may end up subnormal] */
h=0;
}
/* Take a copy of RHS if it needs normalization (true whenever x>=1) */
if (rhs->exponent!=use) {
- decNumber *newrhs=bufr; /* assume will fit on stack */
+ decNumber *newrhs=bufr; /* assume will fit on stack */
needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
if (needbytes>sizeof(bufr)) { /* need malloc space */
allocrhs=(decNumber *)malloc(needbytes);
- if (allocrhs==NULL) { /* hopeless -- abandon */
+ if (allocrhs==NULL) { /* hopeless -- abandon */
*status|=DEC_Insufficient_storage;
break;}
newrhs=allocrhs; /* use the allocated space */
/* third term by setting the term variable t=x, the accumulator */
/* a=1, and the divisor d=2. */
- /* First determine the working precision. From Hull & Abrham */
+ /* First determine the working precision. From Hull & Abrham */
/* this is set->digits+h+2. However, if x is 'over-precise' we */
/* need to allow for all its digits to potentially participate */
/* (consider an x where all the excess digits are 9s) so in */
/* only the status from the accumulation is interesting */
/* [but it should remain unchanged after first add] */
decAddOp(a, a, t, &aset, 0, status); /* a=a+t */
- decMultiplyOp(t, t, x, &tset, &ignore); /* t=t*x */
+ decMultiplyOp(t, t, x, &tset, &ignore); /* t=t*x */
decDivideOp(t, t, d, &tset, DIVIDE, &ignore); /* t=t/d */
/* the iteration ends when the term cannot affect the result, */
/* if rounded to p digits, which is when its value is smaller */
/* just a sanity check; comment out test to show always */
if (iterations>p+3)
printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
- iterations, *status, p, x->digits);
+ (LI)iterations, (LI)*status, (LI)p, (LI)x->digits);
#endif
} /* h<=8 */
/* abandon if have had overflow or terminal underflow */
if (*status & (DEC_Overflow|DEC_Underflow)) { /* interesting? */
if (*status&DEC_Overflow || ISZERO(t)) break;}
- n=n<<1; /* move next bit to testable position */
+ n=n<<1; /* move next bit to testable position */
if (n<0) { /* top bit is set */
seenbit=1; /* OK, have a significant bit */
decMultiplyOp(t, t, a, &aset, status); /* acc=acc*x */
}
if (i==31) break; /* that was the last bit */
- if (!seenbit) continue; /* no need to square 1 */
+ if (!seenbit) continue; /* no need to square 1 */
decMultiplyOp(t, t, t, &aset, status); /* acc=acc*acc [square] */
} /*i*/ /* 32 bits */
/* decNumberShow(t); */
aset.digits=set->digits; /* [use default rounding] */
decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */
decFinish(res, set, &residue, status); /* cleanup/set flags */
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */
if (allocbufa!=NULL) free(allocbufa); /* .. */
/* where x is truncated (NB) into the range 10 through 99, */
/* and then c = k>>2 and e = k&3. */
/* ------------------------------------------------------------------ */
-const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208,
- 6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312,
- 5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032,
+const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208,
+ 6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312,
+ 5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032,
39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
- 10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801,
- 5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
- 10130, 6046, 20055};
+ 10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801,
+ 5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
+ 10130, 6046, 20055};
/* ------------------------------------------------------------------ */
/* decLnOp -- effect natural logarithm */
/* */
/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */
/* almost always be correctly rounded, but may be up to 1 ulp in */
-/* error in rare cases. */
+/* error in rare cases. */
/* ------------------------------------------------------------------ */
/* The result is calculated using Newton's method, with each */
/* iteration calculating a' = a + x * exp(-a) - 1. See, for example, */
/* */
/* Implementation notes: */
/* */
-/* 1. This is separated out as decLnOp so it can be called from */
+/* 1. This is separated out as decLnOp so it can be called from */
/* other Mathematical functions (e.g., Log 10) with a wider range */
/* than normal. In particular, it can handle the slightly wider */
/* (+9+2) range needed by a power function. */
break;}
} /* integer and short */
- /* Determine the working precision. This is normally the */
+ /* Determine the working precision. This is normally the */
/* requested precision + 2, with a minimum of 9. However, if */
/* the rhs is 'over-precise' then allow for all its digits to */
/* potentially participate (consider an rhs where all the excess */
decCopyFit(b, rhs, &aset, &residue, &ignore); /* copy & shorten */
b->exponent=0; /* make integer */
t=decGetInt(b); /* [cannot fail] */
- if (t<10) t=X10(t); /* adjust single-digit b */
+ if (t<10) t=X10(t); /* adjust single-digit b */
t=LNnn[t-10]; /* look up ln(b) */
decNumberFromInt32(b, t>>2); /* b=ln(b) coefficient */
b->exponent=-(t&3)-3; /* set exponent */
/* [initially 9 as then the sequence starts 7+2, 16+2, and */
/* 34+2, which is ideal for standard-sized numbers] */
aset.digits=pp; /* working context */
- bset.digits=pp+rhs->digits; /* wider context */
+ bset.digits=pp+rhs->digits; /* wider context */
for (;;) { /* iterate */
#if DECCHECK
iterations++;
- if (iterations>24) break; /* consider 9 * 2**24 */
+ if (iterations>24) break; /* consider 9 * 2**24 */
#endif
- /* calculate the adjustment (exp(-a)*x-1) into b. This is a */
+ /* calculate the adjustment (exp(-a)*x-1) into b. This is a */
/* catastrophic subtraction but it really is the difference */
/* from 1 that is of interest. */
/* Use the internal entry point to Exp as it allows the double */
decExpOp(b, a, &bset, &ignore); /* b=exp(-a) */
a->bits^=DECNEG; /* restore sign of a */
/* now multiply by rhs and subtract 1, at the wider precision */
- decMultiplyOp(b, b, rhs, &bset, &ignore); /* b=b*rhs */
+ decMultiplyOp(b, b, rhs, &bset, &ignore); /* b=b*rhs */
decAddOp(b, b, &numone, &bset, DECNEG, &ignore); /* b=b-1 */
/* the iteration ends when the adjustment cannot affect the */
/* just a sanity check; remove the test to show always */
if (iterations>24)
printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
- iterations, *status, p, rhs->digits);
+ (LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits);
#endif
/* Copy and round the result to res */
aset.digits=set->digits; /* [use default rounding] */
decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */
decFinish(res, set, &residue, status); /* cleanup/set flags */
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
if (allocbufb!=NULL) free(allocbufb); /* .. */
/* */
/* This computes C = op(A, B), where op adjusts the coefficient */
/* of C (by rounding or shifting) such that the exponent (-scale) */
-/* of C has the value B or matches the exponent of B. */
+/* of C has the value B or matches the exponent of B. */
/* The numerical value of C will equal A, except for the effects of */
/* any rounding that occurred. */
/* */
/* res is C, the result. C may be A or B */
/* lhs is A, the number to adjust */
/* rhs is B, the requested exponent */
-/* set is the context */
+/* set is the context */
/* quant is 1 for quantize or 0 for rescale */
/* status is the status accumulator (this can be called without */
/* risk of control loss) */
#endif
const decNumber *inrhs=rhs; /* save original rhs */
Int reqdigits=set->digits; /* requested DIGITS */
- Int reqexp; /* requested exponent [-scale] */
+ Int reqexp; /* requested exponent [-scale] */
Int residue=0; /* rounding residue */
Int etiny=set->emin-(reqdigits-1);
if (res->exponent>reqexp) {
/* re-check needed, e.g., for quantize(0.9999, 0.001) under */
/* set->digits==3 */
- if (res->digits==reqdigits) { /* cannot shift by 1 */
+ if (res->digits==reqdigits) { /* cannot shift by 1 */
*status&=~(DEC_Inexact | DEC_Rounded); /* [clean these] */
*status|=DEC_Invalid_operation;
break;
}
else {
decFinalize(res, set, &residue, status); /* set subnormal flags */
- *status&=~DEC_Underflow; /* suppress Underflow [754r] */
+ *status&=~DEC_Underflow; /* suppress Underflow [as per 754] */
}
- } while(0); /* end protected */
+ } while(0); /* end protected */
#if DECSUBSET
if (allocrhs!=NULL) free(allocrhs); /* drop any storage used */
/* result of a comparison unless one or both */
/* operands is a NaN (in which case a NaN results) */
/* COMPSIG -- as COMPARE except that a quiet NaN raises */
-/* Invalid operation. */
+/* Invalid operation. */
/* COMPMAX -- returns the larger of the operands, using the */
-/* 754r maxnum operation */
+/* 754 maxnum operation */
/* COMPMAXMAG -- ditto, comparing absolute values */
-/* COMPMIN -- the 754r minnum operation */
+/* COMPMIN -- the 754 minnum operation */
/* COMPMINMAG -- ditto, comparing absolute values */
-/* COMTOTAL -- returns the signum (as a number) giving the */
-/* result of a comparison using 754r total ordering */
+/* COMTOTAL -- returns the signum (as a number) giving the */
+/* result of a comparison using 754 total ordering */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
/* rhs is B */
-/* set is the context */
-/* op is the operation flag */
+/* set is the context */
+/* op is the operation flag */
/* status is the usual accumulator */
/* */
/* C must have space for one digit for COMPARE or set->digits for */
-/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG. */
+/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG. */
/* ------------------------------------------------------------------ */
-/* The emphasis here is on speed for common cases, and avoiding */
+/* The emphasis here is on speed for common cases, and avoiding */
/* coefficient comparison if possible. */
/* ------------------------------------------------------------------ */
decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
decNumber *allocrhs=NULL; /* .., rhs */
#endif
Int result=0; /* default result value */
- uByte merged; /* work */
+ uByte merged; /* work */
#if DECCHECK
if (decCheckOperands(res, lhs, rhs, set)) return res;
/* This assumes sNaN (even just one) leads to NaN. */
merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
if (merged) { /* a NaN bit set */
- if (op==COMPARE); /* result will be NaN */
+ if (op==COMPARE); /* result will be NaN */
else if (op==COMPSIG) /* treat qNaN as sNaN */
*status|=DEC_Invalid_operation | DEC_sNaN;
else if (op==COMPTOTAL) { /* total ordering, always finite */
else if (merged & DECSNAN); /* sNaN -> qNaN */
else { /* here if MIN or MAX and one or two quiet NaNs */
- /* min or max -- 754r rules ignore single NaN */
+ /* min or max -- 754 rules ignore single NaN */
if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
/* just one NaN; force choice to be the non-NaN operand */
op=COMPMAX;
/* have numbers */
if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1);
else result=decCompare(lhs, rhs, 0); /* sign matters */
- } while(0); /* end protected */
+ } while(0); /* end protected */
if (result==BADINT) *status|=DEC_Insufficient_storage; /* rare */
else {
/* choose the operand for the result */
const decNumber *choice;
if (result==0) { /* operands are numerically equal */
- /* choose according to sign then exponent (see 754r) */
+ /* choose according to sign then exponent (see 754) */
uByte slhs=(lhs->bits & DECNEG);
uByte srhs=(rhs->bits & DECNEG);
#if DECSUBSET
else result=-1;
/* [if equal, use lhs, technically identical] */
}
- else { /* both positive */
+ else { /* both positive */
if (lhs->exponent>rhs->exponent) result=+1;
else result=-1;
/* [ditto] */
/* ------------------------------------------------------------------ */
static Int decCompare(const decNumber *lhs, const decNumber *rhs,
Flag abs) {
- Int result; /* result value */
+ Int result; /* result value */
Int sigr; /* rhs signum */
Int compare; /* work */
compare=decUnitCompare(lhs->lsu, D2U(lhs->digits),
rhs->lsu, D2U(rhs->digits),
rhs->exponent-lhs->exponent);
- if (compare!=BADINT) compare*=result; /* comparison succeeded */
+ if (compare!=BADINT) compare*=result; /* comparison succeeded */
return compare;
} /* decCompare */
/* */
/* This routine compares A ? B*10**E where A and B are unit arrays */
/* A is a plain integer */
-/* B has an exponent of E (which must be non-negative) */
+/* B has an exponent of E (which must be non-negative) */
/* */
/* Arg1 is A first Unit (lsu) */
/* Arg2 is A length in Units */
/* */
/* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */
/* (the only possible failure is an allocation error, which can */
-/* only occur if E!=0) */
+/* only occur if E!=0) */
/* ------------------------------------------------------------------ */
static Int decUnitCompare(const Unit *a, Int alength,
const Unit *b, Int blength, Int exp) {
Unit *acc; /* accumulator for result */
Unit accbuff[SD2U(DECBUFFER*2+1)]; /* local buffer */
- Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */
- Int accunits, need; /* units in use or needed for acc */
+ Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */
+ Int accunits, need; /* units in use or needed for acc */
const Unit *l, *r, *u; /* work */
Int expunits, exprem, result; /* .. */
- if (exp==0) { /* aligned; fastpath */
+ if (exp==0) { /* aligned; fastpath */
if (alength>blength) return 1;
if (alength<blength) return -1;
/* same number of units in both -- need unit-by-unit compare */
return 0; /* all units match */
} /* aligned */
- /* Unaligned. If one is >1 unit longer than the other, padded */
+ /* Unaligned. If one is >1 unit longer than the other, padded */
/* approximately, then can return easily */
if (alength>blength+(Int)D2U(exp)) return 1;
if (alength+1<blength+(Int)D2U(exp)) return -1;
/* A may be shorter or longer than B. */
/* */
/* Leading zeros are not removed after a calculation. The result is */
-/* either the same length as the longer of A and B (adding any */
+/* either the same length as the longer of A and B (adding any */
/* shift), or one Unit longer than that (if a Unit carry occurred). */
/* */
/* A and B content are not altered unless C is also A or B. */
const Unit *b, Int blength, Int bshift,
Unit *c, Int m) {
const Unit *alsu=a; /* A lsu [need to remember it] */
- Unit *clsu=c; /* C ditto */
+ Unit *clsu=c; /* C ditto */
Unit *minC; /* low water mark for C */
Unit *maxC; /* high water mark for C */
- eInt carry=0; /* carry integer (could be Long) */
+ eInt carry=0; /* carry integer (could be Long) */
Int add; /* work */
#if DECDPUN<=4 /* myriadal, millenary, etc. */
Int est; /* estimated quotient */
carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
est=(((ueInt)carry>>11)*53687)>>18;
*c=(Unit)(carry-est*(DECDPUNMAX+1));
- carry=est-(DECDPUNMAX+1); /* correctly negative */
+ carry=est-(DECDPUNMAX+1); /* correctly negative */
if (*c<DECDPUNMAX+1) continue; /* was OK */
carry++;
*c-=DECDPUNMAX+1;
carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
est=(((ueInt)carry>>3)*16777)>>21;
*c=(Unit)(carry-est*(DECDPUNMAX+1));
- carry=est-(DECDPUNMAX+1); /* correctly negative */
+ carry=est-(DECDPUNMAX+1); /* correctly negative */
if (*c<DECDPUNMAX+1) continue; /* was OK */
carry++;
*c-=DECDPUNMAX+1;
carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
est=QUOT10(carry, DECDPUN);
*c=(Unit)(carry-est*(DECDPUNMAX+1));
- carry=est-(DECDPUNMAX+1); /* correctly negative */
+ carry=est-(DECDPUNMAX+1); /* correctly negative */
#else
/* remainder operator is undefined if negative, so must test */
if ((ueInt)carry<(DECDPUNMAX+1)*2) { /* fastpath carry +1 */
carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
est=(((ueInt)carry>>11)*53687)>>18;
*c=(Unit)(carry-est*(DECDPUNMAX+1));
- carry=est-(DECDPUNMAX+1); /* correctly negative */
+ carry=est-(DECDPUNMAX+1); /* correctly negative */
if (*c<DECDPUNMAX+1) continue; /* was OK */
carry++;
*c-=DECDPUNMAX+1;
carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
est=(((ueInt)carry>>3)*16777)>>21;
*c=(Unit)(carry-est*(DECDPUNMAX+1));
- carry=est-(DECDPUNMAX+1); /* correctly negative */
+ carry=est-(DECDPUNMAX+1); /* correctly negative */
if (*c<DECDPUNMAX+1) continue; /* was OK */
carry++;
*c-=DECDPUNMAX+1;
carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
est=QUOT10(carry, DECDPUN);
*c=(Unit)(carry-est*(DECDPUNMAX+1));
- carry=est-(DECDPUNMAX+1); /* correctly negative */
+ carry=est-(DECDPUNMAX+1); /* correctly negative */
#else
if ((ueInt)carry<(DECDPUNMAX+1)*2){ /* fastpath carry 1 */
*c=(Unit)(carry-(DECDPUNMAX+1));
/* dn is the number to trim or normalize */
/* set is the context to use to check for clamp */
/* all is 1 to remove all trailing zeros, 0 for just fraction ones */
+/* noclamp is 1 to unconditional (unclamped) trim */
/* dropped returns the number of discarded trailing zeros */
-/* returns dn */
+/* returns dn */
/* */
/* If clamp is set in the context then the number of zeros trimmed */
/* may be limited if the exponent is high. */
/* so special values are unchanged and no error is possible. */
/* ------------------------------------------------------------------ */
static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
- Int *dropped) {
- Int d, exp; /* work */
+ Flag noclamp, Int *dropped) {
+ Int d, exp; /* work */
uInt cut; /* .. */
Unit *up; /* -> current Unit */
if (*up%powers[cut]!=0) break; /* found non-0 digit */
#endif
/* have a trailing 0 */
- if (!all) { /* trimming */
+ if (!all) { /* trimming */
/* [if exp>0 then all trailing 0s are significant for trim] */
if (exp<=0) { /* if digit might be significant */
if (exp==0) break; /* then quit */
if (d==0) return dn; /* none to drop */
/* may need to limit drop if clamping */
- if (set->clamp) {
+ if (set->clamp && !noclamp) {
Int maxd=set->emax-set->digits+1-dn->exponent;
if (maxd<=0) return dn; /* nothing possible */
if (d>maxd) d=maxd;
/* returns the new length of the integer in the array, in digits */
/* */
/* No overflow is permitted (that is, the uar array must be known to */
-/* be large enough to hold the result, after shifting). */
+/* be large enough to hold the result, after shifting). */
/* ------------------------------------------------------------------ */
static Int decShiftToMost(Unit *uar, Int digits, Int shift) {
Unit *target, *source, *first; /* work */
next=0; /* all paths */
source=uar+D2U(digits)-1; /* where msu comes from */
target=source+D2U(shift); /* where upper part of first cut goes */
- cut=DECDPUN-MSUDIGITS(shift); /* where to slice */
- if (cut==0) { /* unit-boundary case */
+ cut=DECDPUN-MSUDIGITS(shift); /* where to slice */
+ if (cut==0) { /* unit-boundary case */
for (; source>=uar; source--, target--) *target=*source;
}
else {
/* ------------------------------------------------------------------ */
/* decShiftToLeast -- shift digits in array towards least significant */
/* */
-/* uar is the array */
+/* uar is the array */
/* units is length of the array, in units */
/* shift is the number of digits to remove from the lsu end; it */
/* must be zero or positive and <= than units*DECDPUN. */
/* */
/* returns the new length of the integer in the array, in units */
/* */
-/* Removed digits are discarded (lost). Units not required to hold */
+/* Removed digits are discarded (lost). Units not required to hold */
/* the final result are unchanged. */
/* ------------------------------------------------------------------ */
static Int decShiftToLeast(Unit *uar, Int units, Int shift) {
/* lostDigits and other status may be set by this. */
/* */
/* Since the input is an operand, it must not be modified. */
-/* Instead, return an allocated decNumber, rounded as required. */
+/* Instead, return an allocated decNumber, rounded as required. */
/* It is the caller's responsibility to free the allocated storage. */
/* */
/* If no storage is available then the result cannot be used, so NULL */
-/* is returned. */
+/* is returned. */
/* ------------------------------------------------------------------ */
static decNumber *decRoundOperand(const decNumber *dn, decContext *set,
uInt *status) {
/* dest is the target decNumber */
/* src is the source decNumber */
/* set is the context [used for length (digits) and rounding mode] */
-/* residue is the residue accumulator */
+/* residue is the residue accumulator */
/* status contains the current status to be updated */
/* */
/* (dest==src is allowed and will be a no-op if fits) */
/* ------------------------------------------------------------------ */
/* decSetCoeff -- set the coefficient of a number */
/* */
-/* dn is the number whose coefficient array is to be set. */
+/* dn is the number whose coefficient array is to be set. */
/* It must have space for set->digits digits */
/* set is the context [for size] */
/* lsu -> lsu of the source coefficient [may be dn->lsu] */
/* len is digits in the source coefficient [may be dn->digits] */
-/* residue is the residue accumulator. This has values as in */
+/* residue is the residue accumulator. This has values as in */
/* decApplyRound, and will be unchanged unless the */
/* target size is less than len. In this case, the */
/* coefficient is truncated and the residue is updated to */
-/* reflect the previous residue and the dropped digits. */
-/* status is the status accumulator, as usual */
+/* reflect the previous residue and the dropped digits. */
+/* status is the status accumulator, as usual */
/* */
/* The coefficient may already be in the number, or it can be an */
-/* external intermediate array. If it is in the number, lsu must == */
+/* external intermediate array. If it is in the number, lsu must == */
/* dn->lsu and len must == dn->digits. */
/* */
/* Note that the coefficient length (len) may be < set->digits, and */
/* ------------------------------------------------------------------ */
/* mapping array: maps 0-9 to canonical residues, so that a residue */
/* can be adjusted in the range [-1, +1] and achieve correct rounding */
-/* 0 1 2 3 4 5 6 7 8 9 */
+/* 0 1 2 3 4 5 6 7 8 9 */
static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7};
static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu,
Int len, Int *residue, uInt *status) {
discard=len-set->digits; /* digits to discard */
if (discard<=0) { /* no digits are being discarded */
- if (dn->lsu!=lsu) { /* copy needed */
+ if (dn->lsu!=lsu) { /* copy needed */
/* copy the coefficient array to the result number; no shift needed */
count=len; /* avoids D2U */
up=lsu;
/* some digits must be discarded ... */
dn->exponent+=discard; /* maintain numerical value */
- *status|=DEC_Rounded; /* accumulate Rounded status */
+ *status|=DEC_Rounded; /* accumulate Rounded status */
if (*residue>1) *residue=1; /* previous residue now to right, so reduce */
if (discard>len) { /* everything, +1, is being discarded */
}
}
if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude */
- *dn->lsu=0; /* coefficient will now be 0 */
+ *dn->lsu=0; /* coefficient will now be 0 */
dn->digits=1; /* .. */
return;
} /* total discard */
/* here up -> Unit with first discarded digit */
cut=discard-(count-DECDPUN)-1;
- if (cut==DECDPUN-1) { /* unit-boundary case (fast) */
+ if (cut==DECDPUN-1) { /* unit-boundary case (fast) */
Unit half=(Unit)powers[DECDPUN]>>1;
/* set residue directly */
if (*up>=half) {
if (*up>half) *residue=7;
- else *residue+=5; /* add sticky bit */
+ else *residue+=5; /* add sticky bit */
}
else { /* <half */
if (*up!=0) *residue=3; /* [else is 0, leave as sticky bit] */
}
else { /* shift to least */
count=set->digits; /* now digits to end up with */
- dn->digits=count; /* set the new length */
+ dn->digits=count; /* set the new length */
up++; /* move to next */
/* on unit boundary, so shift-down copy loop is simple */
for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
uInt discard1; /* first discarded digit */
uInt quot, rem; /* for divisions */
if (cut==0) quot=*up; /* is at bottom of unit */
- else /* cut>0 */ { /* it's not at bottom of unit */
+ else /* cut>0 */ { /* it's not at bottom of unit */
#if DECDPUN<=4
quot=QUOT10(*up, cut);
rem=*up-quot*powers[cut];
}
else { /* shift to least needed */
count=set->digits; /* now digits to end up with */
- dn->digits=count; /* set the new length */
+ dn->digits=count; /* set the new length */
/* shift-copy the coefficient array to the result number */
for (target=dn->lsu; ; target++) {
*target=(Unit)quot;
/* ------------------------------------------------------------------ */
/* decApplyRound -- apply pending rounding to a number */
/* */
-/* dn is the number, with space for set->digits digits */
+/* dn is the number, with space for set->digits digits */
/* set is the context [for size and rounding mode] */
/* residue indicates pending rounding, being any accumulated */
/* guard and sticky information. It may be: */
/* 1-4: rounding digit is <5 and >0 */
/* 0: the coefficient is exact */
/* -1: as 1, but the hidden digits are subtractive, that */
-/* is, of the opposite sign to dn. In this case the */
+/* is, of the opposite sign to dn. In this case the */
/* coefficient must be non-0. This case occurs when */
/* subtracting a small number (which can be reduced to */
/* a sticky bit); see decAddOp. */
-/* status is the status accumulator, as usual */
+/* status is the status accumulator, as usual */
/* */
/* This routine applies rounding while keeping the length of the */
-/* coefficient constant. The exponent and status are unchanged */
+/* coefficient constant. The exponent and status are unchanged */
/* except if: */
/* */
/* -- the coefficient was increased and is all nines (in which */
if (bump==0) return; /* no action required */
/* Simply use decUnitAddSub unless bumping up and the number is */
- /* all nines. In this special case set to 100... explicitly */
+ /* all nines. In this special case set to 100... explicitly */
/* and adjust the exponent by one (as otherwise could overflow */
/* the array) */
/* Similarly handle all-nines result if bumping down. */
/* here if it, too, is all nines */
*up=(Unit)powers[count-1]; /* here 999 -> 100 etc. */
for (up=up-1; up>=dn->lsu; up--) *up=0; /* others all to 0 */
- dn->exponent++; /* and bump exponent */
+ dn->exponent++; /* and bump exponent */
/* [which, very rarely, could cause Overflow...] */
if ((dn->exponent+dn->digits)>set->emax+1) {
decSetOverflow(dn, set, status);
}
- return; /* done */
+ return; /* done */
}
/* a full unit to check, with more to come */
if (*up!=DECDPUNMAX) break; /* not still 9s */
/* this is the last Unit (the msu) */
if (*up!=powers[count-1]) break; /* not 100.. */
/* here if have the 1000... case */
- sup=up; /* save msu pointer */
+ sup=up; /* save msu pointer */
*up=(Unit)powers[count]-1; /* here 100 in msu -> 999 */
/* others all to all-nines, too */
for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1;
- dn->exponent--; /* and bump exponent */
+ dn->exponent--; /* and bump exponent */
/* iff the number was at the subnormal boundary (exponent=etiny) */
/* then the exponent is now out of range, so it will in fact get */
dn->exponent++;
*status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
}
- return; /* done */
+ return; /* done */
}
/* a full unit to check, with more to come */
/* decFinish -- finish processing a number */
/* */
/* dn is the number */
-/* set is the context */
+/* set is the context */
/* residue is the rounding accumulator (as in decApplyRound) */
/* status is the accumulator */
/* */
/* decFinalize -- final check, clamp, and round of a number */
/* */
/* dn is the number */
-/* set is the context */
+/* set is the context */
/* residue is the rounding accumulator (as in decApplyRound) */
/* status is the status accumulator */
/* */
/* This finishes off the current number by checking for subnormal */
/* results, applying any pending rounding, checking for overflow, */
/* and applying any clamping. */
-/* Underflow and overflow conditions are raised as appropriate. */
+/* Underflow and overflow conditions are raised as appropriate. */
/* All fields are updated as required. */
/* ------------------------------------------------------------------ */
static void decFinalize(decNumber *dn, decContext *set, Int *residue,
nmin.lsu[0]=1;
nmin.exponent=set->emin;
comp=decCompare(dn, &nmin, 1); /* (signless compare) */
- if (comp==BADINT) { /* oops */
+ if (comp==BADINT) { /* oops */
*status|=DEC_Insufficient_storage; /* abandon... */
return;
}
if (*residue<0 && comp==0) { /* neg residue and dn==Nmin */
- decApplyRound(dn, set, *residue, status); /* might force down */
+ decApplyRound(dn, set, *residue, status); /* might force down */
decSetSubnormal(dn, set, residue, status);
return;
}
dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
}
dn->exponent-=shift; /* adjust the exponent to match */
- *status|=DEC_Clamped; /* and record the dirty deed */
+ *status|=DEC_Clamped; /* and record the dirty deed */
return;
} /* decFinalize */
/* ------------------------------------------------------------------ */
/* decSetOverflow -- set number to proper overflow value */
/* */
-/* dn is the number (used for sign [only] and result) */
+/* dn is the number (used for sign [only] and result) */
/* set is the context [used for the rounding mode, etc.] */
/* status contains the current status to be updated */
/* */
/* This sets the sign of a number and sets its value to either */
/* Infinity or the maximum finite value, depending on the sign of */
-/* dn and the rounding mode, following IEEE 854 rules. */
+/* dn and the rounding mode, following IEEE 754 rules. */
/* ------------------------------------------------------------------ */
static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) {
Flag needmax=0; /* result is maximum finite value */
uByte sign=dn->bits&DECNEG; /* clean and save sign bit */
if (ISZERO(dn)) { /* zero does not overflow magnitude */
- Int emax=set->emax; /* limit value */
+ Int emax=set->emax; /* limit value */
if (set->clamp) emax-=set->digits-1; /* lower if clamping */
if (dn->exponent>emax) { /* clamp required */
dn->exponent=emax;
} /* decSetOverflow */
/* ------------------------------------------------------------------ */
-/* decSetMaxValue -- set number to +Nmax (maximum normal value) */
+/* decSetMaxValue -- set number to +Nmax (maximum normal value) */
/* */
/* dn is the number to set */
/* set is the context [used for digits and emax] */
/* ------------------------------------------------------------------ */
static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
uInt *status) {
- Int dnexp; /* saves original exponent */
decContext workset; /* work */
Int etiny, adjust; /* .. */
/* adjust>0, so need to rescale the result so exponent becomes Etiny */
/* [this code is similar to that in rescale] */
- dnexp=dn->exponent; /* save exponent */
- workset=*set; /* clone rounding, etc. */
+ workset=*set; /* clone rounding, etc. */
workset.digits=dn->digits-adjust; /* set requested length */
- workset.emin-=adjust; /* and adjust emin to match */
+ workset.emin-=adjust; /* and adjust emin to match */
/* [note that the latter can be <1, here, similar to Rescale case] */
decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
decApplyRound(dn, &workset, *residue, status);
- /* Use 754R/854 default rule: Underflow is set iff Inexact */
+ /* Use 754 default rule: Underflow is set iff Inexact */
/* [independent of whether trapped] */
if (*status&DEC_Inexact) *status|=DEC_Underflow;
/* ------------------------------------------------------------------ */
/* decDecap -- decapitate the coefficient of a number */
/* */
-/* dn is the number to be decapitated */
+/* dn is the number to be decapitated */
/* drop is the number of digits to be removed from the left of dn; */
-/* this must be <= dn->digits (if equal, the coefficient is */
+/* this must be <= dn->digits (if equal, the coefficient is */
/* set to 0) */
/* */
/* Returns dn; dn->digits will be <= the initial digits less drop */
-/* (after removing drop digits there may be leading zero digits */
-/* which will also be removed). Only dn->lsu and dn->digits change. */
+/* (after removing drop digits there may be leading zero digits */
+/* which will also be removed). Only dn->lsu and dn->digits change. */
/* ------------------------------------------------------------------ */
static decNumber *decDecap(decNumber *dn, Int drop) {
Unit *msu; /* -> target cut point */
/* ------------------------------------------------------------------ */
/* decStatus -- apply non-zero status */
/* */
-/* dn is the number to set if error */
+/* dn is the number to set if error */
/* status contains the current status (not yet in context) */
/* set is the context */
/* */
/* If the status is an error status, the number is set to a NaN, */
/* unless the error was an overflow, divide-by-zero, or underflow, */
-/* in which case the number will have already been set. */
+/* in which case the number will have already been set. */
/* */
/* The context status is then updated with the new status. Note that */
/* this may raise a signal, so control may never return from this */
/* ------------------------------------------------------------------ */
/* decGetDigits -- count digits in a Units array */
/* */
-/* uar is the Unit array holding the number (this is often an */
+/* uar is the Unit array holding the number (this is often an */
/* accumulator of some sort) */
/* len is the length of the array in units [>=1] */
/* */
/* ------------------------------------------------------------------ */
/* This may be called twice during some operations. */
static Int decGetDigits(Unit *uar, Int len) {
- Unit *up=uar+(len-1); /* -> msu */
+ Unit *up=uar+(len-1); /* -> msu */
Int digits=(len-1)*DECDPUN+1; /* possible digits excluding msu */
#if DECDPUN>4
uInt const *pow; /* work */
if (*up<10) break; /* is 1-9 */
digits++;
#if DECDPUN>2 /* not done yet */
- if (*up<100) break; /* is 10-99 */
+ if (*up<100) break; /* is 10-99 */
digits++;
#if DECDPUN>3 /* not done yet */
if (*up<1000) break; /* is 100-999 */
}
/* now carefully display the coefficient */
- up=dn->lsu+D2U(dn->digits)-1; /* msu */
+ up=dn->lsu+D2U(dn->digits)-1; /* msu */
printf("%ld", (LI)*up);
for (up=up-1; up>=dn->lsu; up--) {
u=*up;
/* ------------------------------------------------------------------ */
/* decDumpAr -- display a unit array [debug/check aid] */
/* name is a single-character tag name */
-/* ar is the array to display */
+/* ar is the array to display */
/* len is the length of the array in Units */
/* ------------------------------------------------------------------ */
static void decDumpAr(char name, const Unit *ar, Int len) {
/* rhs is the second (may be DECUNUSED) */
/* set is the context (may be DECUNCONT) */
/* returns 0 if both operands, and the context are clean, or 1 */
-/* otherwise (in which case the context will show an error, */
+/* otherwise (in which case the context will show an error, */
/* unless NULL). Note that res is not cleaned; caller should */
/* handle this so res=NULL case is safe. */
/* The caller is expected to abandon immediately if 1 is returned. */
if (set!=DECUNCONT) decContextSetStatus(set, DEC_Invalid_operation);
if (res!=DECUNRESU && res!=NULL) {
decNumberZero(res);
- res->bits=DECNAN; /* qNaN */
+ res->bits=DECNAN; /* qNaN */
}
}
return bad;
/* ------------------------------------------------------------------ */
static Flag decCheckNumber(const decNumber *dn) {
const Unit *up; /* work */
- uInt maxuint; /* .. */
+ uInt maxuint; /* .. */
Int ae, d, digits; /* .. */
Int emin, emax; /* .. */
/* check the exponent. Note that input operands can have exponents */
/* which are out of the set->emin/set->emax and set->digits range */
/* (just as they can have more digits than set->digits). */
- ae=dn->exponent+dn->digits-1; /* adjusted exponent */
+ ae=dn->exponent+dn->digits-1; /* adjusted exponent */
emax=DECNUMMAXE;
emin=DECNUMMINE;
digits=DECNUMMAXP;
/* */
/* Semantics is the same as the stdlib malloc routine, but bytes */
/* allocated are accounted for globally, and corruption fences are */
-/* added before and after the 'actual' storage. */
+/* added before and after the 'actual' storage. */
/* ------------------------------------------------------------------ */
/* This routine allocates storage with an extra twelve bytes; 8 are */
/* at the start and hold: */
/* ------------------------------------------------------------------ */
static void *decMalloc(size_t n) {
uInt size=n+12; /* true size */
- void *alloc; /* -> allocated storage */
- uInt *j; /* work */
- uByte *b, *b0; /* .. */
+ void *alloc; /* -> allocated storage */
+ uByte *b, *b0; /* work */
+ uInt uiwork; /* for macros */
alloc=malloc(size); /* -> allocated storage */
- if (alloc==NULL) return NULL; /* out of strorage */
+ if (alloc==NULL) return NULL; /* out of strorage */
b0=(uByte *)alloc; /* as bytes */
decAllocBytes+=n; /* account for storage */
- j=(uInt *)alloc; /* -> first four bytes */
- *j=n; /* save n */
- /* printf(" alloc ++ dAB: %ld (%d)\n", decAllocBytes, n); */
+ UBFROMUI(alloc, n); /* save n */
+ /* printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n); */
for (b=b0+4; b<b0+8; b++) *b=DECFENCE;
for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;
return b0+8; /* -> play area */
/* is, offset by 8). */
/* ------------------------------------------------------------------ */
static void decFree(void *alloc) {
- uInt *j, n; /* pointer, original length */
+ uInt n; /* original length */
uByte *b, *b0; /* work */
+ uInt uiwork; /* for macros */
if (alloc==NULL) return; /* allowed; it's a nop */
b0=(uByte *)alloc; /* as bytes */
b0-=8; /* -> true start of storage */
- j=(uInt *)b0; /* -> first four bytes */
- n=*j; /* lift */
+ n=UBTOUI(b0); /* lift length */
for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)
printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b,
- b-b0-8, (Int)b0);
+ b-b0-8, (LI)b0);
for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE)
printf("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n", *b,
- b-b0-8, (Int)b0, n);
+ b-b0-8, (LI)b0, (LI)n);
free(b0); /* drop the storage */
decAllocBytes-=n; /* account for storage */
/* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n); */
#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 */
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 *);
/* 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)
/* ------------------------------------------------------------------ */
/* 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 */
+ #include "dconfig.h" /* for WORDS_BIGENDIAN */
/* Conditional code flag -- set this to match hardware platform */
- /* 1=little-endian, 0=big-endian */
+ /* 1=little-endian, 0=big-endian */
#if WORDS_BIGENDIAN
#define DECLITEND 0
#else
#define DECLITEND 1
#endif
+ #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) */
/* 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 */
+ #include "decDPDSymbols.h"
+ 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 */
/* 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 */
- /* 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)))
+ /* 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]. */
+
+ /* 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] */
/* 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')
#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
/* 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))
/* 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. */
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;} \
/* 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;
#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
/* 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
/* 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 */
|| ((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 */
#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 */
+ /* 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]);}
-
- #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 */
/* 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); \
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]; \
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); \
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 */
#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. */
(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) \
/* ------------------------------------------------------------------ */
/* 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. */
/* ------------------------------------------------------------------ */
/* */
/* 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, */
/* 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. */
/* ------------------------------------------------------------------ */
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 */
/* 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 */
/* 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) {
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 */
/* 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);
#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 */
/* 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
/* ---------------------------------------------------------------- */
/* 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 */
/* ------------------------------------------------------------------ */
/* 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))
/* 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;
/* ---------------------------------------------------------------- */
/* 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
/* ---------------------------------------------------------------- */
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 *);
/* 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
/* ------------------------------------------------------------------ */
/* 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
#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 */
/* ------------------------------------------------------------------ */
/* 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) */
#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;
/* ---------------------------------------------------------------- */
/* 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 *);
/* 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
#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];
/* */
/* 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*/
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 */
/* 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 */
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);
}
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] */
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 */
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 */
#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 */
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 */
} /* 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); */
/* 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;
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 */
#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 */
if (exp==3) {
if (msd==0) { /* infinity */
- strcpy(c, "Inf");
+ strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
/* 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;
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;
}
/* 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 */
/* ------------------------------------------------------------------ */
/* 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. */
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 */
/* 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);
/* 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);
/* 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) {
02110-1301, USA. */
/* ------------------------------------------------------------------ */
-/* Decimal 128-bit format module header */
+/* Decimal 128-bit format module header */
/* ------------------------------------------------------------------ */
#if !defined(DECIMAL128)
#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 */
/* 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 *);
decContext *);
decNumber * decimal128ToNumber(const decimal128 *, decNumber *);
- /* Format-dependent utilities */
+ /* Format-dependent utilities */
uint32_t decimal128IsCanonical(const decimal128 *);
decimal128 * decimal128Canonical(decimal128 *, const decimal128 *);
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. */
#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 */
/* ------------------------------------------------------------------ */
/* 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 */
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 */
/* 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 */
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);
}
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 */
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); */
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 */
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 */
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
} /* 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 */
/* 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;
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 */
}
/* 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;
}
/* 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 */
}
/* 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. */
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 */
/* ------------------------------------------------------------------ */
/* 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);
/* 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);
/* 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] */
#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 */
#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 */
/* 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 *);
decContext *);
decNumber * decimal32ToNumber(const decimal32 *, decNumber *);
- /* Format-dependent utilities */
+ /* Format-dependent utilities */
uint32_t decimal32IsCanonical(const decimal32 *);
decimal32 * decimal32Canonical(decimal32 *, const decimal32 *);
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. */
#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 */
/* ------------------------------------------------------------------ */
/* 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 */
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 */
/* 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 */
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);
}
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 */
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 */
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 */
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 */
/* ------------------------------------------------------------------ */
-/* 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 */
/* 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;
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 */
if (exp==3) {
if (msd==0) { /* infinity */
- strcpy(c, "Inf");
+ strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
/* 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;}
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;
}
/* 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 */
}
/* 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. */
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 */
/* ------------------------------------------------------------------ */
/* 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);
/* 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);
/* 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] */
/* ------------------------------------------------------------------ */
/* 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. */
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 */
/* 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 */
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
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] */
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
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;
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
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
#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 */
#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 */
/* 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 *);
decContext *);
decNumber * decimal64ToNumber(const decimal64 *, decNumber *);
- /* Format-dependent utilities */
+ /* Format-dependent utilities */
uint32_t decimal64IsCanonical(const decimal64 *);
decimal64 * decimal64Canonical(decimal64 *, const decimal64 *);