Temporarily revert revision 145222.

From-SVN: r145264
This commit is contained in:
Ben Elliston 2009-03-30 10:44:21 +11:00
parent 148e4216a4
commit 8a1c0f0c85
23 changed files with 1611 additions and 1971 deletions

View File

@ -1,12 +1,3 @@
2009-03-29 Ben Elliston <bje@au.ibm.com>
* decNumber.c, decNumber.h, decNumberLocal.h, decDouble.c,
decDouble.h, decSingle.c, decContext.c, decSingle.h, decPacked.c,
decCommon.c, decContext.h, decQuad.c, decPacked.h, decQuad.h,
decDPD.h, decBasic.c: Upgrade to decNumber 3.61.
* dpd/decimal128.h, dpd/decimal32.c, dpd/decimal32.h,
dpd/decimal64.c, dpd/decimal128.c, dpd/decimal64.h: Likewise.
2009-02-10 Joseph Myers <joseph@codesourcery.com>
* Makefile.in (clean): Don't remove makedepend$(EXEEXT).

File diff suppressed because it is too large Load Diff

View File

@ -161,7 +161,7 @@ static const uInt DECCOMBWEXP[64]={
#if QUAD
const uInt DECCOMBMSD[64]={
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1,
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};
@ -248,7 +248,6 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
decContext *set) {
uByte *ub; /* work */
uInt dpd; /* .. */
uInt uiwork; /* for macros */
uByte *umsd=num->msd; /* local copy */
uByte *ulsd=num->lsd; /* .. */
uInt encode; /* encoding accumulator */
@ -280,7 +279,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* skip leading insignificant zeros to calculate an exact length */
/* [this is quite expensive] */
if (*umsd==0) {
for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4;
for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4;
for (; *umsd==0 && umsd<ulsd;) umsd++;
length=ulsd-umsd+1; /* recalculate */
}
@ -389,9 +388,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* increment the coefficient; this might end up with 1000... */
/* (after the all nines case) */
ub=ulsd;
for(; ub-3>=umsd && UBTOUI(ub-3)==0x09090909; ub-=4) {
UBFROMUI(ub-3, 0); /* to 00000000 */
}
for(; ub-3>=umsd && UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0;
/* [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) */
@ -478,8 +475,8 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
uByte *t=buffer; /* safe target */
uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
/* printf("folddown shift=%ld\n", (LI)shift); */
for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s));
for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0); /* pad 0s */
for (; s<=ulsd; s+=4, t+=4) UINTAT(t)=UINTAT(s);
for (t=tlsd-shift+1; t<=tlsd; t+=4) UINTAT(t)=0; /* pad */
num->exponent-=shift;
umsd=buffer;
ulsd=tlsd;
@ -495,23 +492,23 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/*------------------------------------------------------------------*/
/* Following code does not alter coefficient (could be allnines array) */
/* fast path possible when DECPMAX digits */
if (length==DECPMAX) {
return decFloatFromBCD(df, num->exponent, umsd, num->sign);
} /* full-length */
}
/* slower path when not a full-length number; must care about length */
/* [coefficient length here will be < DECPMAX] */
/* Here when length is short */
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 */
@ -522,7 +519,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* working pointer, uInt *ub. */
/* As not full-length then chances are there are many leading zeros */
/* [and there may be a partial triad] */
#define getDPDt(dpd, n) ub=ulsd-(3*(n))-2; \
#define getDPD(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];}
@ -531,48 +528,48 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* according to endianness; in all cases complete the sign word */
/* first */
#if DECPMAX==7
getDPDt(dpd, 1);
getDPD(dpd, 1);
encode|=dpd<<10;
getDPDt(dpd, 0);
getDPD(dpd, 0);
encode|=dpd;
DFWORD(df, 0)=encode; /* just the one word */
#elif DECPMAX==16
getDPDt(dpd, 4); encode|=dpd<<8;
getDPDt(dpd, 3); encode|=dpd>>2;
getDPD(dpd, 4); encode|=dpd<<8;
getDPD(dpd, 3); encode|=dpd>>2;
DFWORD(df, 0)=encode;
encode=dpd<<30;
getDPDt(dpd, 2); encode|=dpd<<20;
getDPDt(dpd, 1); encode|=dpd<<10;
getDPDt(dpd, 0); encode|=dpd;
getDPD(dpd, 2); encode|=dpd<<20;
getDPD(dpd, 1); encode|=dpd<<10;
getDPD(dpd, 0); encode|=dpd;
DFWORD(df, 1)=encode;
#elif DECPMAX==34
getDPDt(dpd,10); encode|=dpd<<4;
getDPDt(dpd, 9); encode|=dpd>>6;
getDPD(dpd,10); encode|=dpd<<4;
getDPD(dpd, 9); encode|=dpd>>6;
DFWORD(df, 0)=encode;
encode=dpd<<26;
getDPDt(dpd, 8); encode|=dpd<<16;
getDPDt(dpd, 7); encode|=dpd<<6;
getDPDt(dpd, 6); encode|=dpd>>4;
getDPD(dpd, 8); encode|=dpd<<16;
getDPD(dpd, 7); encode|=dpd<<6;
getDPD(dpd, 6); encode|=dpd>>4;
DFWORD(df, 1)=encode;
encode=dpd<<28;
getDPDt(dpd, 5); encode|=dpd<<18;
getDPDt(dpd, 4); encode|=dpd<<8;
getDPDt(dpd, 3); encode|=dpd>>2;
getDPD(dpd, 5); encode|=dpd<<18;
getDPD(dpd, 4); encode|=dpd<<8;
getDPD(dpd, 3); encode|=dpd>>2;
DFWORD(df, 2)=encode;
encode=dpd<<30;
getDPDt(dpd, 2); encode|=dpd<<20;
getDPDt(dpd, 1); encode|=dpd<<10;
getDPDt(dpd, 0); encode|=dpd;
getDPD(dpd, 2); encode|=dpd<<20;
getDPD(dpd, 1); encode|=dpd<<10;
getDPD(dpd, 0); encode|=dpd;
DFWORD(df, 3)=encode;
#endif
/* printf("Status: %08lx\n", (LI)set->status); */
/* decFloatShow(df, "final2"); */
/* decFloatShow(df, "final"); */
return df;
} /* decFinalize */
@ -585,7 +582,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* 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 are undefined otherwise. */
/* All bytes must be in 0-9; results undefined otherwise. */
/* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */
/* returns df, which will be canonical */
/* */
@ -612,53 +609,53 @@ decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
/* and put the corresponding DPD code into dpd. */
/* Use of a working pointer, uInt *ub, is assumed. */
#define getDPDb(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \
#define getDPDf(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
getDPDb(dpd, 1);
getDPDf(dpd, 1);
encode|=dpd<<10;
getDPDb(dpd, 0);
getDPDf(dpd, 0);
encode|=dpd;
DFWORD(df, 0)=encode; /* just the one word */
#elif DECPMAX==16
getDPDb(dpd, 4); encode|=dpd<<8;
getDPDb(dpd, 3); encode|=dpd>>2;
getDPDf(dpd, 4); encode|=dpd<<8;
getDPDf(dpd, 3); encode|=dpd>>2;
DFWORD(df, 0)=encode;
encode=dpd<<30;
getDPDb(dpd, 2); encode|=dpd<<20;
getDPDb(dpd, 1); encode|=dpd<<10;
getDPDb(dpd, 0); encode|=dpd;
getDPDf(dpd, 2); encode|=dpd<<20;
getDPDf(dpd, 1); encode|=dpd<<10;
getDPDf(dpd, 0); encode|=dpd;
DFWORD(df, 1)=encode;
#elif DECPMAX==34
getDPDb(dpd,10); encode|=dpd<<4;
getDPDb(dpd, 9); encode|=dpd>>6;
getDPDf(dpd,10); encode|=dpd<<4;
getDPDf(dpd, 9); encode|=dpd>>6;
DFWORD(df, 0)=encode;
encode=dpd<<26;
getDPDb(dpd, 8); encode|=dpd<<16;
getDPDb(dpd, 7); encode|=dpd<<6;
getDPDb(dpd, 6); encode|=dpd>>4;
getDPDf(dpd, 8); encode|=dpd<<16;
getDPDf(dpd, 7); encode|=dpd<<6;
getDPDf(dpd, 6); encode|=dpd>>4;
DFWORD(df, 1)=encode;
encode=dpd<<28;
getDPDb(dpd, 5); encode|=dpd<<18;
getDPDb(dpd, 4); encode|=dpd<<8;
getDPDb(dpd, 3); encode|=dpd>>2;
getDPDf(dpd, 5); encode|=dpd<<18;
getDPDf(dpd, 4); encode|=dpd<<8;
getDPDf(dpd, 3); encode|=dpd>>2;
DFWORD(df, 2)=encode;
encode=dpd<<30;
getDPDb(dpd, 2); encode|=dpd<<20;
getDPDb(dpd, 1); encode|=dpd<<10;
getDPDb(dpd, 0); encode|=dpd;
getDPDf(dpd, 2); encode|=dpd<<20;
getDPDf(dpd, 1); encode|=dpd<<10;
getDPDf(dpd, 0); encode|=dpd;
DFWORD(df, 3)=encode;
#endif
/* decFloatShow(df, "fromB"); */
/* decFloatShow(df, "final"); */
return df;
} /* decFloatFromBCD */
@ -704,70 +701,6 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
return decFloatFromBCD(df, exp, bcdar+1, sig);
} /* decFloatFromPacked */
/* ------------------------------------------------------------------ */
/* 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 */
/* */
@ -797,7 +730,6 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
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, */
@ -900,8 +832,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
/* as usual, go by fours when safe; NB it has been asserted */
/* that a '.' does not have the same mask as a digit */
if (c<=clast-3 /* safe for four */
&& (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* test four */
UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */
&& (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* test four */
UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */
ub+=4;
c+=4;
continue;
@ -914,7 +846,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
}
} /* had dot */
/* Now no dot; do this by fours (where safe) */
for (; c<=clast-3; c+=4, ub+=4) UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);
for (; c<=clast-3; c+=4, ub+=4) UINTAT(ub)=UINTAT(c)&0x0f0f0f0f;
for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0');
num.lsd=buffer+digits-1; /* record new LSD */
} /* fits */
@ -939,8 +871,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
/* (see commentary just above) */
if (c<=clast-3 /* safe for four */
&& (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */
&& (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */
ub+=4;
c+=3; /* [will become 4] */
continue;
@ -1242,9 +1174,6 @@ char * decFloatToEngString(const decFloat *df, char *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 */
@ -1302,9 +1231,9 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* 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) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \
else if (*(u+3)) { \
UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);}
#if DECPMAX==7
dpd2char(sourhi>>10); /* declet 1 */
@ -1381,8 +1310,8 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* because there is still space for exponent */
s=dotat+ROUNDDOWN4(c-dotat); /* source */
t=s+1; /* target */
/* open the gap [cannot use memcpy] */
for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
/* open the gap */
for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
*dotat='.';
c++; /* length increased by one */
} /* need dot? */
@ -1397,19 +1326,19 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* backoff if too far to the right */
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
/* now shift the entire coefficient to the right, being careful not */
/* to access to the left of string [cannot use memcpy] */
for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
/* to access to the left of string */
for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(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) {
memcpy(cstart+pre-4, "0000", 4);
memcpy(cstart, "0.00", 4);
UINTAT(cstart+pre-4)=UINTAT("0000");
UINTAT(cstart)=UINTAT("0.00");
}
else { /* 2 or 3 */
*(cstart+pre-1)='0';
memcpy(cstart, "0.", 2);
USHORTAT(cstart)=USHORTAT("0.");
}
c+=pre; /* to end */
}
@ -1417,7 +1346,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 or 4 digits (asserted above) */
if (e!=0) {
memcpy(c, "E+", 2); /* starts with E, assume + */
USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */
c++;
if (e<0) {
*c='-'; /* oops, need '-' */
@ -1429,12 +1358,12 @@ char * decFloatToEngString(const decFloat *df, char *string){
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
/* copy fixed 4 characters [is safe], starting at non-zero */
/* and with character mask to convert BCD to char */
UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
UINTAT(c)=UINTAT(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 */
UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
else { /* 4-digits */
@ -1442,7 +1371,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
UBFROMUI(c, UBTOUI(u)|CHARMASK);/* copy fixed 3+1 characters [is safe] */
UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
#endif
@ -1521,9 +1450,6 @@ char * decFloatToString(const decFloat *df, char *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 */
@ -1541,11 +1467,7 @@ char * decFloatToString(const decFloat *df, char *string){
msd=DECCOMBMSD[comb]; /* decode the combination field */
exp=DECCOMBEXP[comb]; /* .. */
if (!EXPISSPECIAL(exp)) { /* finite */
/* complete exponent; top two bits are in place */
exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */
}
else { /* IS special */
if (EXPISSPECIAL(exp)) { /* special */
if (exp==DECFLOAT_Inf) { /* infinity */
strcpy(c, "Infinity");
return string; /* easy */
@ -1565,6 +1487,9 @@ char * decFloatToString(const decFloat *df, char *string){
/* otherwise drop through to add integer; set correct exp etc. */
exp=0; msd=0; /* setup for following code */
}
else { /* complete exponent; top two bits are in place */
exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */
}
/* convert the digits of the significand to characters */
cstart=c; /* save start of coefficient */
@ -1581,9 +1506,9 @@ char * decFloatToString(const decFloat *df, char *string){
/* 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) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \
else if (*(u+3)) { \
UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);}
#if DECPMAX==7
dpd2char(sourhi>>10); /* declet 1 */
@ -1631,13 +1556,12 @@ char * decFloatToString(const decFloat *df, char *string){
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
/* [memmove is a disaster, here] */
/* move by fours; there must be space for junk at the end */
/* because exponent is still possible */
/* because there is still space for exponent */
s=dotat+ROUNDDOWN4(c-dotat); /* source */
t=s+1; /* target */
/* open the gap [cannot use memcpy] */
for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
/* open the gap */
for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
*dotat='.';
c++; /* length increased by one */
} /* need dot? */
@ -1645,7 +1569,7 @@ char * decFloatToString(const decFloat *df, char *string){
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 or 4 digits (asserted above) */
if (e!=0) {
memcpy(c, "E+", 2); /* starts with E, assume + */
USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */
c++;
if (e<0) {
*c='-'; /* oops, need '-' */
@ -1657,12 +1581,12 @@ char * decFloatToString(const decFloat *df, char *string){
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
/* copy fixed 4 characters [is safe], starting at non-zero */
/* and with character mask to convert BCD to char */
UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
UINTAT(c)=UINTAT(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 */
UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
else { /* 4-digits */
@ -1670,7 +1594,7 @@ char * decFloatToString(const decFloat *df, char *string){
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
#endif
@ -1694,19 +1618,19 @@ char * decFloatToString(const decFloat *df, char *string){
/* backoff if too far to the right */
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
/* now shift the entire coefficient to the right, being careful not */
/* to access to the left of string [cannot use memcpy] */
for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
/* to access to the left of string */
for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(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) {
memcpy(cstart+pre-4, "0000", 4);
memcpy(cstart, "0.00", 4);
UINTAT(cstart+pre-4)=UINTAT("0000");
UINTAT(cstart)=UINTAT("0.00");
}
else { /* 2 or 3 */
*(cstart+pre-1)='0';
memcpy(cstart, "0.", 2);
USHORTAT(cstart)=USHORTAT("0.");
}
*(c+pre)='\0'; /* terminate */
return string;
@ -1799,7 +1723,6 @@ decFloat * decFloatZero(decFloat *df){
void decShowNum(const bcdnum *num, const char *tag) {
const char *csign="+"; /* sign character */
uByte *ub; /* work */
uInt uiwork; /* for macros */
if (num->sign==DECFLOAT_Sign) csign="-";
printf(">%s> ", tag);
@ -1824,7 +1747,7 @@ decFloat * decFloatZero(decFloat *df){
if (e==0) *c++='0'; /* 0-length case */
else if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
else { /* 4-digits */
@ -1832,7 +1755,7 @@ decFloat * decFloatZero(decFloat *df){
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
*c='\0'; /* add terminator */

View File

@ -41,10 +41,12 @@
#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=(const Flag *)&mfcone; /* -> top byte */
static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
#define LITEND *mfctop /* named flag; 1=little-endian */
#endif
/* ------------------------------------------------------------------ */
/* round-for-reround digits */
@ -78,9 +80,9 @@ decContext *decContextClearStatus(decContext *context, uInt mask) {
/* context is the structure to be initialized */
/* kind selects the required set of default values, one of: */
/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
/* DEC_INIT_DECIMAL32 -- select IEEE 754 defaults, 32-bit */
/* DEC_INIT_DECIMAL64 -- select IEEE 754 defaults, 64-bit */
/* DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit */
/* 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 */
/* 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. */
@ -140,6 +142,15 @@ decContext * decContextDefault(decContext *context, Int kind) {
decContextSetStatus(context, DEC_Invalid_operation); /* trap */
}
#if DECCHECK
if (LITEND!=DECLITEND) {
const char *adj;
if (LITEND) adj="little";
else adj="big";
printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
DECLITEND, adj);
}
#endif
return context;} /* decContextDefault */
/* ------------------------------------------------------------------ */
@ -378,36 +389,6 @@ const char *decContextStatusToString(const decContext *context) {
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 */
/* */

View File

@ -56,21 +56,15 @@
#define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */
#define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */
#if !defined(int32_t)
#include <stdint.h> /* C99 standard integers */
#endif
#include "gstdint.h" /* C99 standard integers */
#include <stdio.h> /* for printf, etc. */
#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 {
@ -108,9 +102,9 @@
#define DEC_MIN_EMIN -999999999
#define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */
/* Classifications for decimal numbers, aligned with 754 (note that */
/* 'normal' and 'subnormal' are meaningful only with a decContext */
/* or a fixed size format). */
/* Classifications for decimal numbers, aligned with 754r (note */
/* that 'normal' and 'subnormal' are meaningful only with a */
/* decContext or a fixed size format). */
enum decClass {
DEC_CLASS_SNAN,
DEC_CLASS_QNAN,
@ -176,30 +170,30 @@
#define DEC_Underflow 0x00000004
#endif
/* IEEE 754 groupings for the flags */
/* IEEE 854 groupings for the flags */
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */
/* are not in IEEE 754] */
#define DEC_IEEE_754_Division_by_zero (DEC_Division_by_zero)
/* are not in IEEE 854] */
#define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero)
#if DECSUBSET
#define DEC_IEEE_754_Inexact (DEC_Inexact | DEC_Lost_digits)
#define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits)
#else
#define DEC_IEEE_754_Inexact (DEC_Inexact)
#define DEC_IEEE_854_Inexact (DEC_Inexact)
#endif
#define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax | \
#define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \
DEC_Division_impossible | \
DEC_Division_undefined | \
DEC_Insufficient_storage | \
DEC_Invalid_context | \
DEC_Invalid_operation)
#define DEC_IEEE_754_Overflow (DEC_Overflow)
#define DEC_IEEE_754_Underflow (DEC_Underflow)
#define DEC_IEEE_854_Overflow (DEC_Overflow)
#define DEC_IEEE_854_Underflow (DEC_Underflow)
/* flags which are normally errors (result is qNaN, infinite, or 0) */
#define DEC_Errors (DEC_IEEE_754_Division_by_zero | \
DEC_IEEE_754_Invalid_operation | \
DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)
#define DEC_Errors (DEC_IEEE_854_Division_by_zero | \
DEC_IEEE_854_Invalid_operation | \
DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow)
/* flags which cause a result to become qNaN */
#define DEC_NaNs DEC_IEEE_754_Invalid_operation
#define DEC_NaNs DEC_IEEE_854_Invalid_operation
/* flags which are normally for information only (finite results) */
#if DECSUBSET
@ -209,13 +203,6 @@
#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"
@ -264,7 +251,6 @@
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 *);

View File

@ -30,9 +30,10 @@
/* ------------------------------------------------------------------------ */
/* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
/* [Automatically generated -- do not edit. 2008.06.21] */
/* [Automatically generated -- do not edit. 2007.05.05] */
/* ------------------------------------------------------------------------ */
/* For details, see DPDecimal.html on the General Decimal Arithmetic page. */
/* ------------------------------------------------------------------------ */
/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */
#include "decDPDSymbols.h"

View File

@ -62,7 +62,6 @@
#define decFloatFromBCD decDoubleFromBCD
#define decFloatFromInt32 decDoubleFromInt32
#define decFloatFromPacked decDoubleFromPacked
#define decFloatFromPackedChecked decDoubleFromPackedChecked
#define decFloatFromString decDoubleFromString
#define decFloatFromUInt32 decDoubleFromUInt32
#define decFloatFromWider decDoubleFromWider
@ -146,7 +145,10 @@
#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 */

View File

@ -31,6 +31,8 @@
/* ------------------------------------------------------------------ */
/* decDouble.h -- Decimal 64-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
#if !defined(DECDOUBLE)
#define DECDOUBLE
@ -56,14 +58,11 @@
#include "decContext.h"
#include "decQuad.h"
/* The decDouble decimal 64-bit type, accessible by all sizes */
/* The decDouble decimal 64-bit type, accessible by various types */
typedef union {
uint8_t bytes[DECDOUBLE_Bytes]; /* fields: 1, 5, 8, 50 bits */
uint16_t shorts[DECDOUBLE_Bytes/2];
uint32_t words[DECDOUBLE_Bytes/4];
#if DECUSE64
uint64_t longs[DECDOUBLE_Bytes/8];
#endif
} decDouble;
/* ---------------------------------------------------------------- */
@ -76,7 +75,6 @@
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 *);
@ -162,8 +160,7 @@
/* 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) decimal64FromNumber((decimal64 *)(dq), dn, set)
#define decDoubleFromNumber(dq, dn, set) (decDouble *)decimal64FromNumber((decimal64 *)(dq), dn, set)
#endif

View File

@ -31,9 +31,9 @@
/* ------------------------------------------------------------------ */
/* Decimal Number arithmetic module */
/* ------------------------------------------------------------------ */
/* 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 */
/* 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 */
/* the full ('extended') arithmetic and the simpler ('subset') */
/* arithmetic. */
/* */
@ -41,21 +41,10 @@
/* */
/* 1. This code is ANSI C89 except: */
/* */
/* 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 */
/* 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 */
@ -273,7 +262,7 @@ static Int decShiftToLeast(Unit *, Int, Int);
static Int decShiftToMost(Unit *, Int, Int);
static void decStatus(decNumber *, uInt, decContext *);
static void decToString(const decNumber *, char[], Flag);
static decNumber * decTrim(decNumber *, decContext *, Flag, Flag, Int *);
static decNumber * decTrim(decNumber *, decContext *, Flag, Int *);
static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
Unit *, Int);
static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
@ -1167,7 +1156,7 @@ decNumber * decNumberFMA(decNumber *res, const decNumber *lhs,
}
#if DECCHECK
else { /* multiply was OK */
if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
if (status!=0) printf("Status=%08lx after FMA multiply\n", status);
}
#endif
/* add the third operand and result -> res, and all is done */
@ -1312,7 +1301,7 @@ decNumber * decNumberLn(decNumber *res, const decNumber *rhs,
} /* decNumberLn */
/* ------------------------------------------------------------------ */
/* decNumberLogB - get adjusted exponent, by 754 rules */
/* decNumberLogB - get adjusted exponent, by 754r rules */
/* */
/* This computes C = adjustedexponent(A) */
/* */
@ -1349,7 +1338,7 @@ decNumber * decNumberLogB(decNumber *res, const decNumber *rhs,
else if (decNumberIsZero(rhs)) {
decNumberZero(res); /* prepare for Infinity */
res->bits=DECNEG|DECINF; /* -Infinity */
status|=DEC_Division_by_zero; /* as per 754 */
status|=DEC_Division_by_zero; /* as per 754r */
}
else { /* finite non-zero */
Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
@ -1530,7 +1519,7 @@ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
/* ------------------------------------------------------------------ */
/* decNumberMax -- compare two Numbers and return the maximum */
/* */
/* This computes C = A ? B, returning the maximum by 754 rules */
/* This computes C = A ? B, returning the maximum by 754R rules */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
@ -1553,7 +1542,7 @@ decNumber * decNumberMax(decNumber *res, const decNumber *lhs,
/* ------------------------------------------------------------------ */
/* decNumberMaxMag -- compare and return the maximum by magnitude */
/* */
/* This computes C = A ? B, returning the maximum by 754 rules */
/* This computes C = A ? B, returning the maximum by 754R rules */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
@ -1576,7 +1565,7 @@ decNumber * decNumberMaxMag(decNumber *res, const decNumber *lhs,
/* ------------------------------------------------------------------ */
/* decNumberMin -- compare two Numbers and return the minimum */
/* */
/* This computes C = A ? B, returning the minimum by 754 rules */
/* This computes C = A ? B, returning the minimum by 754R rules */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
@ -1599,7 +1588,7 @@ decNumber * decNumberMin(decNumber *res, const decNumber *lhs,
/* ------------------------------------------------------------------ */
/* decNumberMinMag -- compare and return the minimum by magnitude */
/* */
/* This computes C = A ? B, returning the minimum by 754 rules */
/* This computes C = A ? B, returning the minimum by 754R rules */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
@ -1661,7 +1650,7 @@ decNumber * decNumberMinus(decNumber *res, const decNumber *rhs,
/* rhs is A */
/* set is the context */
/* */
/* This is a generalization of 754 NextDown. */
/* This is a generalization of 754r NextDown. */
/* ------------------------------------------------------------------ */
decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
decContext *set) {
@ -1697,7 +1686,7 @@ decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
/* rhs is A */
/* set is the context */
/* */
/* This is a generalization of 754 NextUp. */
/* This is a generalization of 754r NextUp. */
/* ------------------------------------------------------------------ */
decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
decContext *set) {
@ -1729,15 +1718,14 @@ decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
/* decNumberNextToward -- next towards rhs */
/* */
/* This computes C = A +/- infinitesimal, rounded towards */
/* +/-Infinity in the direction of B, as per 754-1985 nextafter */
/* modified during revision but dropped from 754-2008. */
/* +/-Infinity in the direction of B, as per 754r nextafter rules */
/* */
/* res is C, the result. C may be A or B. */
/* lhs is A */
/* rhs is B */
/* set is the context */
/* */
/* This is a generalization of 754-1985 NextAfter. */
/* This is a generalization of 754r NextAfter. */
/* ------------------------------------------------------------------ */
decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs,
const decNumber *rhs, decContext *set) {
@ -2254,7 +2242,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs,
decCopyFit(res, dac, set, &residue, &status);
decFinish(res, set, &residue, &status); /* final cleanup */
#if DECSUBSET
if (!set->extended) decTrim(res, set, 0, 1, &dropped); /* trailing zeros */
if (!set->extended) decTrim(res, set, 0, &dropped); /* trailing zeros */
#endif
} while(0); /* end protected */
@ -2349,8 +2337,7 @@ decNumber * decNumberReduce(decNumber *res, const decNumber *rhs,
/* reduce result to the requested length and copy to result */
decCopyFit(res, rhs, set, &residue, &status); /* copy & round */
decFinish(res, set, &residue, &status); /* cleanup/set flags */
decTrim(res, set, 1, 0, &dropped); /* normalize in place */
/* [may clamp] */
decTrim(res, set, 1, &dropped); /* normalize in place */
} while(0); /* end protected */
#if DECSUBSET
@ -2862,7 +2849,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
}
/* calculate the ideal (preferred) exponent [floor(exp/2)] */
/* [It would be nicer to write: ideal=rhs->exponent>>1, but this */
/* [We would like to write: ideal=rhs->exponent>>1, but this */
/* generates a compiler warning. Generated code is the same.] */
ideal=(rhs->exponent&~1)/2; /* target */
@ -2889,7 +2876,6 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
/* b -- intermediate temporary result (same size as a) */
/* if any is too long for local storage, then allocate */
workp=MAXI(set->digits+1, rhs->digits); /* actual rounding precision */
workp=MAXI(workp, 7); /* at least 7 for low cases */
maxp=workp+2; /* largest working precision */
needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
@ -2919,8 +2905,6 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
/* set up working context */
decContextDefault(&workset, DEC_INIT_DECIMAL64);
workset.emax=DEC_MAX_EMAX;
workset.emin=DEC_MIN_EMIN;
/* [Until further notice, no error is possible and status bits */
/* (Rounded, etc.) should be ignored, not accumulated.] */
@ -2961,7 +2945,6 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
#endif
}
decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */
decAddOp(a, a, t, &workset, 0, &ignore); /* ..+t */
/* [a is now the initial approximation for sqrt(f), calculated with */
@ -2973,14 +2956,16 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
t->lsu[0]=5; /* .. */
t->exponent=-1; /* .. */
workset.digits=3; /* initial p */
for (; workset.digits<maxp;) {
for (;;) {
/* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */
workset.digits=MINI(workset.digits*2-2, maxp);
workset.digits=workset.digits*2-2;
if (workset.digits>maxp) workset.digits=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 */
} /* loop */
/* Here, 0.1 <= a < 1 [Hull], and a has maxp digits */
@ -2990,6 +2975,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
approxset=*set; /* get emin, emax, etc. */
approxset.round=DEC_ROUND_HALF_EVEN;
a->exponent+=exp/2; /* set correct exponent */
rstatus=0; /* clear status */
residue=0; /* .. and accumulator */
decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */
@ -3054,13 +3040,13 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
/* count droppable zeros [after any subnormal rounding] by */
/* trimming a copy */
decNumberCopy(b, a);
decTrim(b, set, 1, 1, &dropped); /* [drops trailing zeros] */
decTrim(b, set, 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, so this is the only (relatively rare) condition that */
/* a careful check is needed */
if (b->digits*2-1 > workp) { /* cannot fit */
/* 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 */
status|=DEC_Inexact|DEC_Rounded;
}
else { /* could be exact/unrounded */
@ -3078,13 +3064,6 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
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;
@ -3453,7 +3432,7 @@ decNumber * decNumberCopySign(decNumber *res, const decNumber *lhs,
/* bcd must have at least dn->digits bytes. No error is possible; if */
/* dn is a NaN or Infinite, digits must be 1 and the coefficient 0. */
/* ------------------------------------------------------------------ */
uByte * decNumberGetBCD(const decNumber *dn, uByte *bcd) {
uByte * decNumberGetBCD(const decNumber *dn, uint8_t *bcd) {
uByte *ub=bcd+dn->digits-1; /* -> lsd */
const Unit *up=dn->lsu; /* Unit pointer, -> lsu */
@ -3553,8 +3532,7 @@ Int decNumberIsSubnormal(const decNumber *dn, decContext *set) {
/* returns dn */
/* */
/* All fields are updated as required. This is a utility operation, */
/* so special values are unchanged and no error is possible. The */
/* zeros are removed unconditionally. */
/* so special values are unchanged and no error is possible. */
/* ------------------------------------------------------------------ */
decNumber * decNumberTrim(decNumber *dn) {
Int dropped; /* work */
@ -3563,7 +3541,7 @@ decNumber * decNumberTrim(decNumber *dn) {
if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
#endif
decContextDefault(&set, DEC_INIT_BASE); /* clamp=0 */
return decTrim(dn, &set, 0, 1, &dropped);
return decTrim(dn, &set, 0, &dropped);
} /* decNumberTrim */
/* ------------------------------------------------------------------ */
@ -3879,7 +3857,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs,
#endif
/* exponent will be the lower of the two */
adjust=lexp-res->exponent; /* adjustment needed [if -ve] */
if (ISZERO(res)) { /* both 0: special IEEE 754 rules */
if (ISZERO(res)) { /* both 0: special IEEE 854 rules */
if (adjust<0) res->exponent=lexp; /* set exponent */
/* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */
if (diffsign) {
@ -4228,7 +4206,7 @@ static decNumber * decDivideOp(decNumber *res,
Int accunits; /* count of units accumulated */
Int accdigits; /* count of digits accumulated */
Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)]; /* buffer for var1 */
Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)*sizeof(Unit)]; /* buffer for var1 */
Unit *var1=varbuff; /* -> var1 array for long subtraction */
Unit *varalloc=NULL; /* -> allocated buffer, iff used */
Unit *msu1; /* -> msu of var1 */
@ -4783,7 +4761,7 @@ static decNumber * decDivideOp(decNumber *res,
#if DECSUBSET
/* If a divide then strip trailing zeros if subset [after round] */
if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped);
if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, &dropped);
#endif
} while(0); /* end protected */
@ -5448,7 +5426,7 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs,
/* just a sanity check; comment out test to show always */
if (iterations>p+3)
printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
(LI)iterations, (LI)*status, (LI)p, (LI)x->digits);
iterations, *status, p, x->digits);
#endif
} /* h<=8 */
@ -5788,7 +5766,7 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs,
/* just a sanity check; remove the test to show always */
if (iterations>24)
printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
(LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits);
iterations, *status, p, rhs->digits);
#endif
/* Copy and round the result to res */
@ -5959,7 +5937,7 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
}
else {
decFinalize(res, set, &residue, status); /* set subnormal flags */
*status&=~DEC_Underflow; /* suppress Underflow [as per 754] */
*status&=~DEC_Underflow; /* suppress Underflow [754r] */
}
} while(0); /* end protected */
@ -5980,12 +5958,12 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
/* COMPSIG -- as COMPARE except that a quiet NaN raises */
/* Invalid operation. */
/* COMPMAX -- returns the larger of the operands, using the */
/* 754 maxnum operation */
/* 754r maxnum operation */
/* COMPMAXMAG -- ditto, comparing absolute values */
/* COMPMIN -- the 754 minnum operation */
/* COMPMIN -- the 754r minnum operation */
/* COMPMINMAG -- ditto, comparing absolute values */
/* COMTOTAL -- returns the signum (as a number) giving the */
/* result of a comparison using 754 total ordering */
/* result of a comparison using 754r total ordering */
/* */
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
/* lhs is A */
@ -6071,7 +6049,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
else if (merged & DECSNAN); /* sNaN -> qNaN */
else { /* here if MIN or MAX and one or two quiet NaNs */
/* min or max -- 754 rules ignore single NaN */
/* min or max -- 754r rules ignore single NaN */
if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
/* just one NaN; force choice to be the non-NaN operand */
op=COMPMAX;
@ -6113,7 +6091,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
/* choose the operand for the result */
const decNumber *choice;
if (result==0) { /* operands are numerically equal */
/* choose according to sign then exponent (see 754) */
/* choose according to sign then exponent (see 754r) */
uByte slhs=(lhs->bits & DECNEG);
uByte srhs=(rhs->bits & DECNEG);
#if DECSUBSET
@ -6578,7 +6556,6 @@ static Int decUnitAddSub(const Unit *a, Int alength,
/* dn is the number to trim or normalize */
/* set is the context to use to check for clamp */
/* all is 1 to remove all trailing zeros, 0 for just fraction ones */
/* noclamp is 1 to unconditional (unclamped) trim */
/* dropped returns the number of discarded trailing zeros */
/* returns dn */
/* */
@ -6588,7 +6565,7 @@ static Int decUnitAddSub(const Unit *a, Int alength,
/* so special values are unchanged and no error is possible. */
/* ------------------------------------------------------------------ */
static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
Flag noclamp, Int *dropped) {
Int *dropped) {
Int d, exp; /* work */
uInt cut; /* .. */
Unit *up; /* -> current Unit */
@ -6634,7 +6611,7 @@ static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
if (d==0) return dn; /* none to drop */
/* may need to limit drop if clamping */
if (set->clamp && !noclamp) {
if (set->clamp) {
Int maxd=set->emax-set->digits+1-dn->exponent;
if (maxd<=0) return dn; /* nothing possible */
if (d>maxd) d=maxd;
@ -7342,7 +7319,7 @@ static void decFinalize(decNumber *dn, decContext *set, Int *residue,
/* */
/* 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 754 rules. */
/* dn and the rounding mode, following IEEE 854 rules. */
/* ------------------------------------------------------------------ */
static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) {
Flag needmax=0; /* result is maximum finite value */
@ -7426,6 +7403,7 @@ static void decSetMaxValue(decNumber *dn, decContext *set) {
/* ------------------------------------------------------------------ */
static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
uInt *status) {
Int dnexp; /* saves original exponent */
decContext workset; /* work */
Int etiny, adjust; /* .. */
@ -7470,6 +7448,7 @@ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
/* adjust>0, so need to rescale the result so exponent becomes Etiny */
/* [this code is similar to that in rescale] */
dnexp=dn->exponent; /* save exponent */
workset=*set; /* clone rounding, etc. */
workset.digits=dn->digits-adjust; /* set requested length */
workset.emin-=adjust; /* and adjust emin to match */
@ -7477,7 +7456,7 @@ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
decApplyRound(dn, &workset, *residue, status);
/* Use 754 default rule: Underflow is set iff Inexact */
/* Use 754R/854 default rule: Underflow is set iff Inexact */
/* [independent of whether trapped] */
if (*status&DEC_Inexact) *status|=DEC_Underflow;
@ -8092,15 +8071,16 @@ static void decCheckInexact(const decNumber *dn, decContext *set) {
static void *decMalloc(size_t n) {
uInt size=n+12; /* true size */
void *alloc; /* -> allocated storage */
uByte *b, *b0; /* work */
uInt uiwork; /* for macros */
uInt *j; /* work */
uByte *b, *b0; /* .. */
alloc=malloc(size); /* -> allocated storage */
if (alloc==NULL) return NULL; /* out of strorage */
b0=(uByte *)alloc; /* as bytes */
decAllocBytes+=n; /* account for storage */
UBFROMUI(alloc, n); /* save n */
/* printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n); */
j=(uInt *)alloc; /* -> first four bytes */
*j=n; /* save n */
/* printf(" alloc ++ dAB: %ld (%d)\n", decAllocBytes, 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 */
@ -8119,20 +8099,20 @@ static void *decMalloc(size_t n) {
/* is, offset by 8). */
/* ------------------------------------------------------------------ */
static void decFree(void *alloc) {
uInt n; /* original length */
uInt *j, n; /* pointer, 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 */
n=UBTOUI(b0); /* lift length */
j=(uInt *)b0; /* -> first four bytes */
n=*j; /* lift */
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, (LI)b0);
b-b0-8, (Int)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, (LI)b0, (LI)n);
b-b0-8, (Int)b0, n);
free(b0); /* drop the storage */
decAllocBytes-=n; /* account for storage */
/* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n); */

View File

@ -39,40 +39,34 @@
#if !defined(DECNUMBERLOC)
#define DECNUMBERLOC
#define DECVERSION "decNumber 3.61" /* Package Version [16 max.] */
#define DECVERSION "decNumber 3.53" /* Package Version [16 max.] */
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */
#include <stdlib.h> /* for abs */
#include <string.h> /* for memset, strcpy */
#include "dconfig.h" /* for WORDS_BIGENDIAN */
/* Conditional code flag -- set this to match hardware platform */
#if !defined(DECLITEND)
#define DECLITEND 1 /* 1=little-endian, 0=big-endian */
/* 1=little-endian, 0=big-endian */
#if WORDS_BIGENDIAN
#define DECLITEND 0
#else
#define DECLITEND 1
#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) */
@ -96,7 +90,6 @@
/* 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' */
@ -107,6 +100,7 @@
extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
extern const uInt DECPOWERS[10]; /* powers of ten table */
/* The following are included from decDPD.h */
#include "decDPDSymbols.h"
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */
@ -132,27 +126,17 @@
/* 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 */
/* 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)
/* 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)))
/* X10 and X100 -- multiply integer i by 10 or 100 */
/* [shifts are usually faster than multiply; could be conditional] */
@ -324,12 +308,12 @@
#define DECWORDS (DECBYTES/4)
#define DECWWORDS (DECWBYTES/4)
#if DECLITEND
#define DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)])
#define DFWORD(df, off) ((df)->words[DECWORDS-1-(off)])
#define DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)])
#define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
#else
#define DFBYTE(df, off) ((df)->bytes[off])
#define DFWORD(df, off) ((df)->words[off])
#define DFBYTE(df, off) ((df)->bytes[off])
#define DFWWORD(dfw, off) ((dfw)->words[off])
#endif
@ -342,6 +326,7 @@
#define DFISSNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7e000000)
/* Shared lookup tables */
#include "decCommonSymbols.h"
extern const uInt DECCOMBMSD[64]; /* Combination field -> MSD */
extern const uInt DECCOMBFROM[48]; /* exp+msd -> Combination */
@ -427,31 +412,21 @@
|| ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
/* Macro to test whether a full-length (length DECPMAX) BCD8 */
/* 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 */
/* coefficient is zero */
/* test just the LSWord first, then the remainder */
#if DECPMAX==7
#define ISCOEFFZERO(u) ( \
UBTOUI((u)+DECPMAX-4)==0 \
&& UBTOUS((u)+DECPMAX-6)==0 \
&& *(u)==0)
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& UINTAT((u)+DECPMAX-7)==0)
#elif DECPMAX==16
#define ISCOEFFZERO(u) ( \
UBTOUI((u)+DECPMAX-4)==0 \
&& UBTOUI((u)+DECPMAX-8)==0 \
&& UBTOUI((u)+DECPMAX-12)==0 \
&& UBTOUI(u)==0)
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& (UINTAT((u)+DECPMAX-8)+UINTAT((u)+DECPMAX-12) \
+UINTAT((u)+DECPMAX-16))==0)
#elif DECPMAX==34
#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)
#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)
#endif
/* Macros and masks for the exponent continuation field and MSD */
@ -473,15 +448,20 @@
#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 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)
/* 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];}
/* Decode the declets. After extracting each one, it is decoded */
/* to BCD8 using a table lookup (also used for variable-length */
@ -617,8 +597,8 @@
#endif
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a base-thousand uInt array (of size DECLETS+1, to allow for */
/* the MSD), with the least-significant 0-999 'digit' at offset 0.*/
/* a base-thousand uInt array, 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. */
@ -660,72 +640,9 @@
(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) \

View File

@ -56,7 +56,6 @@
#define decFloatFromBCD decQuadFromBCD
#define decFloatFromInt32 decQuadFromInt32
#define decFloatFromPacked decQuadFromPacked
#define decFloatFromPackedChecked decQuadFromPackedChecked
#define decFloatFromString decQuadFromString
#define decFloatFromUInt32 decQuadFromUInt32
#define decFloatFromWider decQuadFromWider
@ -140,6 +139,7 @@
#define decFloatSameQuantum decQuadSameQuantum
#define decFloatVersion decQuadVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-arithmetic decFloat routines */
#include "decBasic.c" /* basic formats routines */

View File

@ -31,6 +31,8 @@
/* ------------------------------------------------------------------ */
/* 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. */
@ -57,14 +59,11 @@
/* Required include */
#include "decContext.h"
/* The decQuad decimal 128-bit type, accessible by all sizes */
/* The decQuad decimal 128-bit type, accessible by various types */
typedef union {
uint8_t bytes[DECQUAD_Bytes]; /* fields: 1, 5, 12, 110 bits */
uint16_t shorts[DECQUAD_Bytes/2];
uint32_t words[DECQUAD_Bytes/4];
#if DECUSE64
uint64_t longs[DECQUAD_Bytes/8];
#endif
} decQuad;
/* ---------------------------------------------------------------- */
@ -100,7 +99,6 @@
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 *);
@ -184,8 +182,7 @@
/* 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) decimal128FromNumber((decimal128 *)(dq), dn, set)
#define decQuadFromNumber(dq, dn, set) (decQuad *)decimal128FromNumber((decimal128 *)(dq), dn, set)
#endif

View File

@ -31,6 +31,8 @@
/* ------------------------------------------------------------------ */
/* decSingle.c -- decSingle operations module */
/* ------------------------------------------------------------------ */
/* This module comprises decSingle operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decSingle.h" /* public includes */
@ -59,7 +61,6 @@
/* Utility (binary results, extractors, etc.) */
#define decFloatFromBCD decSingleFromBCD
#define decFloatFromPacked decSingleFromPacked
#define decFloatFromPackedChecked decSingleFromPackedChecked
#define decFloatFromString decSingleFromString
#define decFloatFromWider decSingleFromWider
#define decFloatGetCoefficient decSingleGetCoefficient

View File

@ -31,6 +31,8 @@
/* ------------------------------------------------------------------ */
/* decSingle.h -- Decimal 32-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
#if !defined(DECSINGLE)
#define DECSINGLE
@ -57,7 +59,7 @@
#include "decQuad.h"
#include "decDouble.h"
/* The decSingle decimal 32-bit type, accessible by all sizes */
/* The decSingle decimal 32-bit type, accessible by various types */
typedef union {
uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */
uint16_t shorts[DECSINGLE_Bytes/2];
@ -73,7 +75,6 @@
/* 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 *);
@ -96,8 +97,7 @@
/* 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) decimal32FromNumber((decimal32 *)(dq), dn, set)
#define decSingleFromNumber(dq, dn, set) (decSingle *)decimal32FromNumber((decimal32 *)(dq), dn, set)
#endif

View File

@ -89,8 +89,8 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
Int ae; /* adjusted exponent */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt uiwork; /* for macros */
uInt targar[4]={0,0,0,0}; /* target 128-bit */
#define targhi targar[3] /* name the word with the sign */
#define targmh targar[2] /* name the words */
@ -172,19 +172,18 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
/* now write to storage; this is endian */
pu=(uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
/* lo -> hi */
UBFROMUI(d128->bytes, targlo);
UBFROMUI(d128->bytes+4, targml);
UBFROMUI(d128->bytes+8, targmh);
UBFROMUI(d128->bytes+12, targhi);
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 */
}
else {
/* hi -> lo */
UBFROMUI(d128->bytes, targhi);
UBFROMUI(d128->bytes+4, targmh);
UBFROMUI(d128->bytes+8, targml);
UBFROMUI(d128->bytes+12, targlo);
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 */
}
if (status!=0) decContextSetStatus(set, status); /* pass on status */
@ -202,8 +201,8 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
uInt msd; /* coefficient MSD */
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
Int need; /* work */
uInt uiwork; /* for macros */
const uInt *pu; /* work */
Int need; /* .. */
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 */
@ -211,17 +210,18 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
#define sourlo sourar[0] /* and the lowest word */
/* load source from storage; this is endian */
pu=(const uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
sourlo=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 */
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 */
}
else {
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 */
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 */
}
comb=(sourhi>>26)&0x1f; /* combination field */
@ -291,11 +291,11 @@ char * decimal128ToString(const decimal128 *d128, char *string){
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uByte *u; /* work */
const uInt *pu; /* work */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
uInt uiwork; /* for macros */
const uByte *u; /* .. */
uInt sourar[4]; /* source 128-bit */
#define sourhi sourar[3] /* name the word with the sign */
@ -304,17 +304,18 @@ char * decimal128ToString(const decimal128 *d128, char *string){
#define sourlo sourar[0] /* and the lowest word */
/* load source from storage; this is endian */
pu=(const uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
sourlo=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 */
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 */
}
else {
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 */
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 */
}
c=string; /* where result will go */
@ -482,7 +483,7 @@ decimal128 * decimal128FromString(decimal128 *result, const char *string,
/* returns 1 if the encoding of d128 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decimal128IsCanonical(const decimal128 *d128) {
uint32_t decimal128IsCanonical(const decimal128 *d128) {
decNumber dn; /* work */
decimal128 canon; /* .. */
decContext dc; /* .. */
@ -531,9 +532,9 @@ decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal128SetExpCon(d, e) { \
(d)->bytes[0]|=(uByte)((e)>>10); \
(d)->bytes[1] =(uByte)(((e)&0x3fc)>>2); \
(d)->bytes[2]|=(uByte)(((e)&0x03)<<6);}
(d)->bytes[0]|=(uint8_t)((e)>>10); \
(d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2); \
(d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);}
/* ------------------------------------------------------------------ */
/* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */

View File

@ -89,8 +89,8 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
Int ae; /* adjusted exponent */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt uiwork; /* for macros */
uInt targ=0; /* target 32-bit */
/* If the number has too many digits, or the exponent could be */
@ -175,7 +175,8 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
/* now write to storage; this is endian */
UBFROMUI(d32->bytes, targ); /* directly store the int */
pu=(uInt *)d32->bytes; /* overlay */
*pu=targ; /* directly store the int */
if (status!=0) decContextSetStatus(set, status); /* pass on status */
/* decimal32Show(d32); */
@ -193,10 +194,11 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
uInt sour; /* source 32-bit */
uInt uiwork; /* for macros */
const uInt *pu; /* work */
/* load source from storage; this is endian */
sour=UBTOUI(d32->bytes); /* directly load the int */
pu=(const uInt *)d32->bytes; /* overlay */
sour=*pu; /* directly load the int */
comb=(sour>>26)&0x1f; /* combination field */
@ -262,15 +264,16 @@ char * decimal32ToString(const decimal32 *d32, char *string){
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uByte *u; /* work */
const uInt *pu; /* work */
const uByte *u; /* .. */
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 */
sour=UBTOUI(d32->bytes); /* directly load the int */
pu=(const uInt *)d32->bytes; /* overlay */
sour=*pu; /* directly load the int */
c=string; /* where result will go */
if (((Int)sour)<0) *c++='-'; /* handle sign */
@ -409,7 +412,7 @@ decimal32 * decimal32FromString(decimal32 *result, const char *string,
/* returns 1 if the encoding of d32 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decimal32IsCanonical(const decimal32 *d32) {
uint32_t decimal32IsCanonical(const decimal32 *d32) {
decNumber dn; /* work */
decimal32 canon; /* .. */
decContext dc; /* .. */
@ -457,8 +460,8 @@ decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal32SetExpCon(d, e) { \
(d)->bytes[0]|=(uByte)((e)>>4); \
(d)->bytes[1]|=(uByte)(((e)&0x0F)<<4);}
(d)->bytes[0]|=(uint8_t)((e)>>4); \
(d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);}
/* ------------------------------------------------------------------ */
/* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */

View File

@ -95,8 +95,8 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
Int ae; /* adjusted exponent */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt uiwork; /* for macros */
uInt targar[2]={0, 0}; /* target 64-bit */
#define targhi targar[1] /* name the word with the sign */
#define targlo targar[0] /* and the other */
@ -193,15 +193,14 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
/* now write to storage; this is now always endian */
pu=(uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
/* lo int then hi */
UBFROMUI(d64->bytes, targar[0]);
UBFROMUI(d64->bytes+4, targar[1]);
pu[0]=targar[0]; /* directly store the low int */
pu[1]=targar[1]; /* then the high int */
}
else {
/* hi int then lo */
UBFROMUI(d64->bytes, targar[1]);
UBFROMUI(d64->bytes+4, targar[0]);
pu[0]=targar[1]; /* directly store the high int */
pu[1]=targar[0]; /* then the low int */
}
if (status!=0) decContextSetStatus(set, status); /* pass on status */
@ -219,20 +218,21 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
uInt msd; /* coefficient MSD */
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
Int need; /* work */
uInt uiwork; /* for macros */
const uInt *pu; /* work */
Int need; /* .. */
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=UBTOUI(d64->bytes ); /* directly load the low int */
sourhi=UBTOUI(d64->bytes+4); /* then the high int */
sourlo=pu[0]; /* directly load the low int */
sourhi=pu[1]; /* then the high int */
}
else {
sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
sourlo=UBTOUI(d64->bytes+4); /* then the low int */
sourhi=pu[0]; /* directly load the high int */
sourlo=pu[1]; /* then the low int */
}
comb=(sourhi>>26)&0x1f; /* combination field */
@ -307,24 +307,25 @@ char * decimal64ToString(const decimal64 *d64, char *string){
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uByte *u; /* work */
const uInt *pu; /* work */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
uInt uiwork; /* for macros */
const uByte *u; /* .. */
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=UBTOUI(d64->bytes ); /* directly load the low int */
sourhi=UBTOUI(d64->bytes+4); /* then the high int */
sourlo=pu[0]; /* directly load the low int */
sourhi=pu[1]; /* then the high int */
}
else {
sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
sourlo=UBTOUI(d64->bytes+4); /* then the low int */
sourhi=pu[0]; /* directly load the high int */
sourlo=pu[1]; /* then the low int */
}
c=string; /* where result will go */
@ -471,7 +472,7 @@ decimal64 * decimal64FromString(decimal64 *result, const char *string,
/* returns 1 if the encoding of d64 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decimal64IsCanonical(const decimal64 *d64) {
uint32_t decimal64IsCanonical(const decimal64 *d64) {
decNumber dn; /* work */
decimal64 canon; /* .. */
decContext dc; /* .. */
@ -519,8 +520,8 @@ decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal64SetExpCon(d, e) { \
(d)->bytes[0]|=(uByte)((e)>>6); \
(d)->bytes[1]|=(uByte)(((e)&0x3F)<<2);}
(d)->bytes[0]|=(uint8_t)((e)>>6); \
(d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);}
/* ------------------------------------------------------------------ */
/* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */