merge from gcc
This commit is contained in:
parent
f2be950300
commit
87d32bb7b0
23 changed files with 1977 additions and 1607 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
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>
|
2009-02-10 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* Makefile.in (clean): Don't remove makedepend$(EXEEXT).
|
* Makefile.in (clean): Don't remove makedepend$(EXEEXT).
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -161,7 +161,7 @@ static const uInt DECCOMBWEXP[64]={
|
||||||
#if QUAD
|
#if QUAD
|
||||||
const uInt DECCOMBMSD[64]={
|
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, 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, 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, 0};
|
||||||
|
|
||||||
|
@ -248,6 +248,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
|
||||||
decContext *set) {
|
decContext *set) {
|
||||||
uByte *ub; /* work */
|
uByte *ub; /* work */
|
||||||
uInt dpd; /* .. */
|
uInt dpd; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uByte *umsd=num->msd; /* local copy */
|
uByte *umsd=num->msd; /* local copy */
|
||||||
uByte *ulsd=num->lsd; /* .. */
|
uByte *ulsd=num->lsd; /* .. */
|
||||||
uInt encode; /* encoding accumulator */
|
uInt encode; /* encoding accumulator */
|
||||||
|
@ -279,7 +280,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
|
||||||
/* skip leading insignificant zeros to calculate an exact length */
|
/* skip leading insignificant zeros to calculate an exact length */
|
||||||
/* [this is quite expensive] */
|
/* [this is quite expensive] */
|
||||||
if (*umsd==0) {
|
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++;
|
for (; *umsd==0 && umsd<ulsd;) umsd++;
|
||||||
length=ulsd-umsd+1; /* recalculate */
|
length=ulsd-umsd+1; /* recalculate */
|
||||||
}
|
}
|
||||||
|
@ -388,7 +389,9 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
|
||||||
/* increment the coefficient; this might end up with 1000... */
|
/* increment the coefficient; this might end up with 1000... */
|
||||||
/* (after the all nines case) */
|
/* (after the all nines case) */
|
||||||
ub=ulsd;
|
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 */
|
/* [note ub could now be to left of msd, and it is not safe */
|
||||||
/* to write to the the left of the msd] */
|
/* to write to the the left of the msd] */
|
||||||
/* now at most 3 digits left to non-9 (usually just the one) */
|
/* now at most 3 digits left to non-9 (usually just the one) */
|
||||||
|
@ -475,8 +478,8 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
|
||||||
uByte *t=buffer; /* safe target */
|
uByte *t=buffer; /* safe target */
|
||||||
uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
|
uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
|
||||||
/* printf("folddown shift=%ld\n", (LI)shift); */
|
/* printf("folddown shift=%ld\n", (LI)shift); */
|
||||||
for (; s<=ulsd; s+=4, t+=4) UINTAT(t)=UINTAT(s);
|
for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s));
|
||||||
for (t=tlsd-shift+1; t<=tlsd; t+=4) UINTAT(t)=0; /* pad */
|
for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0); /* pad 0s */
|
||||||
num->exponent-=shift;
|
num->exponent-=shift;
|
||||||
umsd=buffer;
|
umsd=buffer;
|
||||||
ulsd=tlsd;
|
ulsd=tlsd;
|
||||||
|
@ -492,23 +495,23 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/* Following code does not alter coefficient (could be allnines array) */
|
/* Following code does not alter coefficient (could be allnines array) */
|
||||||
|
|
||||||
|
/* fast path possible when DECPMAX digits */
|
||||||
if (length==DECPMAX) {
|
if (length==DECPMAX) {
|
||||||
return decFloatFromBCD(df, num->exponent, umsd, num->sign);
|
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 */
|
if (!NUMISSPECIAL(num)) { /* is still finite */
|
||||||
/* encode the combination field and exponent continuation */
|
/* encode the combination field and exponent continuation */
|
||||||
uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */
|
uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */
|
||||||
uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */
|
uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */
|
||||||
/* [msd=0] */
|
/* [msd==0] */
|
||||||
/* look up the combination field and make high word */
|
/* look up the combination field and make high word */
|
||||||
encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */
|
encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */
|
||||||
encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
|
encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
|
||||||
}
|
}
|
||||||
else encode=num->exponent; /* special [already in word] */
|
else encode=num->exponent; /* special [already in word] */
|
||||||
/* [coefficient length here will be < DECPMAX] */
|
|
||||||
|
|
||||||
encode|=num->sign; /* add sign */
|
encode|=num->sign; /* add sign */
|
||||||
|
|
||||||
/* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
|
/* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
|
||||||
|
@ -519,7 +522,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
|
||||||
/* working pointer, uInt *ub. */
|
/* working pointer, uInt *ub. */
|
||||||
/* As not full-length then chances are there are many leading zeros */
|
/* As not full-length then chances are there are many leading zeros */
|
||||||
/* [and there may be a partial triad] */
|
/* [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; \
|
if (ub<umsd-2) dpd=0; \
|
||||||
else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; \
|
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];}
|
else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];}
|
||||||
|
@ -528,48 +531,48 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
|
||||||
/* according to endianness; in all cases complete the sign word */
|
/* according to endianness; in all cases complete the sign word */
|
||||||
/* first */
|
/* first */
|
||||||
#if DECPMAX==7
|
#if DECPMAX==7
|
||||||
getDPD(dpd, 1);
|
getDPDt(dpd, 1);
|
||||||
encode|=dpd<<10;
|
encode|=dpd<<10;
|
||||||
getDPD(dpd, 0);
|
getDPDt(dpd, 0);
|
||||||
encode|=dpd;
|
encode|=dpd;
|
||||||
DFWORD(df, 0)=encode; /* just the one word */
|
DFWORD(df, 0)=encode; /* just the one word */
|
||||||
|
|
||||||
#elif DECPMAX==16
|
#elif DECPMAX==16
|
||||||
getDPD(dpd, 4); encode|=dpd<<8;
|
getDPDt(dpd, 4); encode|=dpd<<8;
|
||||||
getDPD(dpd, 3); encode|=dpd>>2;
|
getDPDt(dpd, 3); encode|=dpd>>2;
|
||||||
DFWORD(df, 0)=encode;
|
DFWORD(df, 0)=encode;
|
||||||
encode=dpd<<30;
|
encode=dpd<<30;
|
||||||
getDPD(dpd, 2); encode|=dpd<<20;
|
getDPDt(dpd, 2); encode|=dpd<<20;
|
||||||
getDPD(dpd, 1); encode|=dpd<<10;
|
getDPDt(dpd, 1); encode|=dpd<<10;
|
||||||
getDPD(dpd, 0); encode|=dpd;
|
getDPDt(dpd, 0); encode|=dpd;
|
||||||
DFWORD(df, 1)=encode;
|
DFWORD(df, 1)=encode;
|
||||||
|
|
||||||
#elif DECPMAX==34
|
#elif DECPMAX==34
|
||||||
getDPD(dpd,10); encode|=dpd<<4;
|
getDPDt(dpd,10); encode|=dpd<<4;
|
||||||
getDPD(dpd, 9); encode|=dpd>>6;
|
getDPDt(dpd, 9); encode|=dpd>>6;
|
||||||
DFWORD(df, 0)=encode;
|
DFWORD(df, 0)=encode;
|
||||||
|
|
||||||
encode=dpd<<26;
|
encode=dpd<<26;
|
||||||
getDPD(dpd, 8); encode|=dpd<<16;
|
getDPDt(dpd, 8); encode|=dpd<<16;
|
||||||
getDPD(dpd, 7); encode|=dpd<<6;
|
getDPDt(dpd, 7); encode|=dpd<<6;
|
||||||
getDPD(dpd, 6); encode|=dpd>>4;
|
getDPDt(dpd, 6); encode|=dpd>>4;
|
||||||
DFWORD(df, 1)=encode;
|
DFWORD(df, 1)=encode;
|
||||||
|
|
||||||
encode=dpd<<28;
|
encode=dpd<<28;
|
||||||
getDPD(dpd, 5); encode|=dpd<<18;
|
getDPDt(dpd, 5); encode|=dpd<<18;
|
||||||
getDPD(dpd, 4); encode|=dpd<<8;
|
getDPDt(dpd, 4); encode|=dpd<<8;
|
||||||
getDPD(dpd, 3); encode|=dpd>>2;
|
getDPDt(dpd, 3); encode|=dpd>>2;
|
||||||
DFWORD(df, 2)=encode;
|
DFWORD(df, 2)=encode;
|
||||||
|
|
||||||
encode=dpd<<30;
|
encode=dpd<<30;
|
||||||
getDPD(dpd, 2); encode|=dpd<<20;
|
getDPDt(dpd, 2); encode|=dpd<<20;
|
||||||
getDPD(dpd, 1); encode|=dpd<<10;
|
getDPDt(dpd, 1); encode|=dpd<<10;
|
||||||
getDPD(dpd, 0); encode|=dpd;
|
getDPDt(dpd, 0); encode|=dpd;
|
||||||
DFWORD(df, 3)=encode;
|
DFWORD(df, 3)=encode;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* printf("Status: %08lx\n", (LI)set->status); */
|
/* printf("Status: %08lx\n", (LI)set->status); */
|
||||||
/* decFloatShow(df, "final"); */
|
/* decFloatShow(df, "final2"); */
|
||||||
return df;
|
return df;
|
||||||
} /* decFinalize */
|
} /* decFinalize */
|
||||||
|
|
||||||
|
@ -582,7 +585,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
|
||||||
/* 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 */
|
/* digit in each byte (BCD8 encoding); the first (MSD) is ignored */
|
||||||
/* if df is a NaN; all are ignored if df is infinite. */
|
/* 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 */
|
/* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */
|
||||||
/* returns df, which will be canonical */
|
/* returns df, which will be canonical */
|
||||||
/* */
|
/* */
|
||||||
|
@ -609,53 +612,53 @@ decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
|
||||||
/* and put the corresponding DPD code into dpd. */
|
/* and put the corresponding DPD code into dpd. */
|
||||||
/* Use of a working pointer, uInt *ub, is assumed. */
|
/* 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)];
|
dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];
|
||||||
|
|
||||||
/* place the declets in the encoding words and copy to result (df), */
|
/* place the declets in the encoding words and copy to result (df), */
|
||||||
/* according to endianness; in all cases complete the sign word */
|
/* according to endianness; in all cases complete the sign word */
|
||||||
/* first */
|
/* first */
|
||||||
#if DECPMAX==7
|
#if DECPMAX==7
|
||||||
getDPDf(dpd, 1);
|
getDPDb(dpd, 1);
|
||||||
encode|=dpd<<10;
|
encode|=dpd<<10;
|
||||||
getDPDf(dpd, 0);
|
getDPDb(dpd, 0);
|
||||||
encode|=dpd;
|
encode|=dpd;
|
||||||
DFWORD(df, 0)=encode; /* just the one word */
|
DFWORD(df, 0)=encode; /* just the one word */
|
||||||
|
|
||||||
#elif DECPMAX==16
|
#elif DECPMAX==16
|
||||||
getDPDf(dpd, 4); encode|=dpd<<8;
|
getDPDb(dpd, 4); encode|=dpd<<8;
|
||||||
getDPDf(dpd, 3); encode|=dpd>>2;
|
getDPDb(dpd, 3); encode|=dpd>>2;
|
||||||
DFWORD(df, 0)=encode;
|
DFWORD(df, 0)=encode;
|
||||||
encode=dpd<<30;
|
encode=dpd<<30;
|
||||||
getDPDf(dpd, 2); encode|=dpd<<20;
|
getDPDb(dpd, 2); encode|=dpd<<20;
|
||||||
getDPDf(dpd, 1); encode|=dpd<<10;
|
getDPDb(dpd, 1); encode|=dpd<<10;
|
||||||
getDPDf(dpd, 0); encode|=dpd;
|
getDPDb(dpd, 0); encode|=dpd;
|
||||||
DFWORD(df, 1)=encode;
|
DFWORD(df, 1)=encode;
|
||||||
|
|
||||||
#elif DECPMAX==34
|
#elif DECPMAX==34
|
||||||
getDPDf(dpd,10); encode|=dpd<<4;
|
getDPDb(dpd,10); encode|=dpd<<4;
|
||||||
getDPDf(dpd, 9); encode|=dpd>>6;
|
getDPDb(dpd, 9); encode|=dpd>>6;
|
||||||
DFWORD(df, 0)=encode;
|
DFWORD(df, 0)=encode;
|
||||||
|
|
||||||
encode=dpd<<26;
|
encode=dpd<<26;
|
||||||
getDPDf(dpd, 8); encode|=dpd<<16;
|
getDPDb(dpd, 8); encode|=dpd<<16;
|
||||||
getDPDf(dpd, 7); encode|=dpd<<6;
|
getDPDb(dpd, 7); encode|=dpd<<6;
|
||||||
getDPDf(dpd, 6); encode|=dpd>>4;
|
getDPDb(dpd, 6); encode|=dpd>>4;
|
||||||
DFWORD(df, 1)=encode;
|
DFWORD(df, 1)=encode;
|
||||||
|
|
||||||
encode=dpd<<28;
|
encode=dpd<<28;
|
||||||
getDPDf(dpd, 5); encode|=dpd<<18;
|
getDPDb(dpd, 5); encode|=dpd<<18;
|
||||||
getDPDf(dpd, 4); encode|=dpd<<8;
|
getDPDb(dpd, 4); encode|=dpd<<8;
|
||||||
getDPDf(dpd, 3); encode|=dpd>>2;
|
getDPDb(dpd, 3); encode|=dpd>>2;
|
||||||
DFWORD(df, 2)=encode;
|
DFWORD(df, 2)=encode;
|
||||||
|
|
||||||
encode=dpd<<30;
|
encode=dpd<<30;
|
||||||
getDPDf(dpd, 2); encode|=dpd<<20;
|
getDPDb(dpd, 2); encode|=dpd<<20;
|
||||||
getDPDf(dpd, 1); encode|=dpd<<10;
|
getDPDb(dpd, 1); encode|=dpd<<10;
|
||||||
getDPDf(dpd, 0); encode|=dpd;
|
getDPDb(dpd, 0); encode|=dpd;
|
||||||
DFWORD(df, 3)=encode;
|
DFWORD(df, 3)=encode;
|
||||||
#endif
|
#endif
|
||||||
/* decFloatShow(df, "final"); */
|
/* decFloatShow(df, "fromB"); */
|
||||||
return df;
|
return df;
|
||||||
} /* decFloatFromBCD */
|
} /* decFloatFromBCD */
|
||||||
|
|
||||||
|
@ -701,6 +704,70 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
|
||||||
return decFloatFromBCD(df, exp, bcdar+1, sig);
|
return decFloatFromBCD(df, exp, bcdar+1, sig);
|
||||||
} /* decFloatFromPacked */
|
} /* 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 */
|
/* decFloatFromString -- conversion from numeric string */
|
||||||
/* */
|
/* */
|
||||||
|
@ -730,6 +797,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
|
||||||
const char *cfirst=string; /* -> first character of decimal part */
|
const char *cfirst=string; /* -> first character of decimal part */
|
||||||
const char *c; /* work */
|
const char *c; /* work */
|
||||||
uByte *ub; /* .. */
|
uByte *ub; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
bcdnum num; /* collects data for finishing */
|
bcdnum num; /* collects data for finishing */
|
||||||
uInt error=DEC_Conversion_syntax; /* assume the worst */
|
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, */
|
||||||
|
@ -832,8 +900,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
|
||||||
/* as usual, go by fours when safe; NB it has been asserted */
|
/* as usual, go by fours when safe; NB it has been asserted */
|
||||||
/* that a '.' does not have the same mask as a digit */
|
/* that a '.' does not have the same mask as a digit */
|
||||||
if (c<=clast-3 /* safe for four */
|
if (c<=clast-3 /* safe for four */
|
||||||
&& (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* test four */
|
&& (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* test four */
|
||||||
UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */
|
UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */
|
||||||
ub+=4;
|
ub+=4;
|
||||||
c+=4;
|
c+=4;
|
||||||
continue;
|
continue;
|
||||||
|
@ -846,7 +914,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
|
||||||
}
|
}
|
||||||
} /* had dot */
|
} /* had dot */
|
||||||
/* Now no dot; do this by fours (where safe) */
|
/* 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');
|
for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0');
|
||||||
num.lsd=buffer+digits-1; /* record new LSD */
|
num.lsd=buffer+digits-1; /* record new LSD */
|
||||||
} /* fits */
|
} /* fits */
|
||||||
|
@ -871,8 +939,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
|
||||||
for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
|
for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
|
||||||
/* (see commentary just above) */
|
/* (see commentary just above) */
|
||||||
if (c<=clast-3 /* safe for four */
|
if (c<=clast-3 /* safe for four */
|
||||||
&& (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
|
&& (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
|
||||||
UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */
|
UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */
|
||||||
ub+=4;
|
ub+=4;
|
||||||
c+=3; /* [will become 4] */
|
c+=3; /* [will become 4] */
|
||||||
continue;
|
continue;
|
||||||
|
@ -1174,6 +1242,9 @@ char * decFloatToEngString(const decFloat *df, char *string){
|
||||||
char *s, *t; /* .. (source, target) */
|
char *s, *t; /* .. (source, target) */
|
||||||
Int pre, e; /* work */
|
Int pre, e; /* work */
|
||||||
const uByte *u; /* .. */
|
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 */
|
/* Source words; macro handles endianness */
|
||||||
uInt sourhi=DFWORD(df, 0); /* word with sign */
|
uInt sourhi=DFWORD(df, 0); /* word with sign */
|
||||||
|
@ -1231,9 +1302,9 @@ char * decFloatToEngString(const decFloat *df, char *string){
|
||||||
/* and are safe because the last item in the array is of length */
|
/* and are safe because the last item in the array is of length */
|
||||||
/* three and has the length byte following.) */
|
/* three and has the length byte following.) */
|
||||||
#define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \
|
#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)) { \
|
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
|
#if DECPMAX==7
|
||||||
dpd2char(sourhi>>10); /* declet 1 */
|
dpd2char(sourhi>>10); /* declet 1 */
|
||||||
|
@ -1310,8 +1381,8 @@ char * decFloatToEngString(const decFloat *df, char *string){
|
||||||
/* because there is still space for exponent */
|
/* because there is still space for exponent */
|
||||||
s=dotat+ROUNDDOWN4(c-dotat); /* source */
|
s=dotat+ROUNDDOWN4(c-dotat); /* source */
|
||||||
t=s+1; /* target */
|
t=s+1; /* target */
|
||||||
/* open the gap */
|
/* open the gap [cannot use memcpy] */
|
||||||
for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
|
for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
|
||||||
*dotat='.';
|
*dotat='.';
|
||||||
c++; /* length increased by one */
|
c++; /* length increased by one */
|
||||||
} /* need dot? */
|
} /* need dot? */
|
||||||
|
@ -1326,19 +1397,19 @@ char * decFloatToEngString(const decFloat *df, char *string){
|
||||||
/* backoff if too far to the right */
|
/* backoff if too far to the right */
|
||||||
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
|
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
|
||||||
/* now shift the entire coefficient to the right, being careful not */
|
/* now shift the entire coefficient to the right, being careful not */
|
||||||
/* to access to the left of string */
|
/* to access to the left of string [cannot use memcpy] */
|
||||||
for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s);
|
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... */
|
/* 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);
|
for(; s>=cstart; s--, t--) *(t+3)=*(s);
|
||||||
/* now have fill 0. through 0.00000; use overlaps to avoid tests */
|
/* now have fill 0. through 0.00000; use overlaps to avoid tests */
|
||||||
if (pre>=4) {
|
if (pre>=4) {
|
||||||
UINTAT(cstart+pre-4)=UINTAT("0000");
|
memcpy(cstart+pre-4, "0000", 4);
|
||||||
UINTAT(cstart)=UINTAT("0.00");
|
memcpy(cstart, "0.00", 4);
|
||||||
}
|
}
|
||||||
else { /* 2 or 3 */
|
else { /* 2 or 3 */
|
||||||
*(cstart+pre-1)='0';
|
*(cstart+pre-1)='0';
|
||||||
USHORTAT(cstart)=USHORTAT("0.");
|
memcpy(cstart, "0.", 2);
|
||||||
}
|
}
|
||||||
c+=pre; /* to end */
|
c+=pre; /* to end */
|
||||||
}
|
}
|
||||||
|
@ -1346,7 +1417,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
|
||||||
/* finally add the E-part, if needed; it will never be 0, and has */
|
/* finally add the E-part, if needed; it will never be 0, and has */
|
||||||
/* a maximum length of 3 or 4 digits (asserted above) */
|
/* a maximum length of 3 or 4 digits (asserted above) */
|
||||||
if (e!=0) {
|
if (e!=0) {
|
||||||
USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */
|
memcpy(c, "E+", 2); /* starts with E, assume + */
|
||||||
c++;
|
c++;
|
||||||
if (e<0) {
|
if (e<0) {
|
||||||
*c='-'; /* oops, need '-' */
|
*c='-'; /* oops, need '-' */
|
||||||
|
@ -1358,12 +1429,12 @@ char * decFloatToEngString(const decFloat *df, char *string){
|
||||||
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 */
|
/* copy fixed 4 characters [is safe], starting at non-zero */
|
||||||
/* and with character mask to convert BCD to char */
|
/* 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 */
|
c+=*(u+3); /* bump pointer appropriately */
|
||||||
#elif DECEMAXD==4
|
#elif DECEMAXD==4
|
||||||
if (e<1000) { /* 3 (or fewer) digits case */
|
if (e<1000) { /* 3 (or fewer) digits case */
|
||||||
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
|
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 */
|
c+=*(u+3); /* bump pointer appropriately */
|
||||||
}
|
}
|
||||||
else { /* 4-digits */
|
else { /* 4-digits */
|
||||||
|
@ -1371,7 +1442,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
|
||||||
Int rem=e-(1000*thou); /* e%1000 */
|
Int rem=e-(1000*thou); /* e%1000 */
|
||||||
*c++=(char)('0'+(char)thou); /* the thousands digit */
|
*c++=(char)('0'+(char)thou); /* the thousands digit */
|
||||||
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
|
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+=3; /* bump pointer, always 3 digits */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1450,6 +1521,9 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
char *s, *t; /* .. (source, target) */
|
char *s, *t; /* .. (source, target) */
|
||||||
Int pre, e; /* work */
|
Int pre, e; /* work */
|
||||||
const uByte *u; /* .. */
|
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 */
|
/* Source words; macro handles endianness */
|
||||||
uInt sourhi=DFWORD(df, 0); /* word with sign */
|
uInt sourhi=DFWORD(df, 0); /* word with sign */
|
||||||
|
@ -1467,7 +1541,11 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
msd=DECCOMBMSD[comb]; /* decode the combination field */
|
msd=DECCOMBMSD[comb]; /* decode the combination field */
|
||||||
exp=DECCOMBEXP[comb]; /* .. */
|
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 */
|
if (exp==DECFLOAT_Inf) { /* infinity */
|
||||||
strcpy(c, "Infinity");
|
strcpy(c, "Infinity");
|
||||||
return string; /* easy */
|
return string; /* easy */
|
||||||
|
@ -1487,9 +1565,6 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
/* otherwise drop through to add integer; set correct exp etc. */
|
/* otherwise drop through to add integer; set correct exp etc. */
|
||||||
exp=0; msd=0; /* setup for following code */
|
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 */
|
/* convert the digits of the significand to characters */
|
||||||
cstart=c; /* save start of coefficient */
|
cstart=c; /* save start of coefficient */
|
||||||
|
@ -1506,9 +1581,9 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
/* and are safe because the last item in the array is of length */
|
/* and are safe because the last item in the array is of length */
|
||||||
/* three and has the length byte following.) */
|
/* three and has the length byte following.) */
|
||||||
#define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \
|
#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)) { \
|
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
|
#if DECPMAX==7
|
||||||
dpd2char(sourhi>>10); /* declet 1 */
|
dpd2char(sourhi>>10); /* declet 1 */
|
||||||
|
@ -1556,12 +1631,13 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
|
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
|
||||||
char *dotat=cstart+pre;
|
char *dotat=cstart+pre;
|
||||||
if (dotat<c) { /* if embedded dot needed... */
|
if (dotat<c) { /* if embedded dot needed... */
|
||||||
|
/* [memmove is a disaster, here] */
|
||||||
/* move by fours; there must be space for junk at the end */
|
/* 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 */
|
s=dotat+ROUNDDOWN4(c-dotat); /* source */
|
||||||
t=s+1; /* target */
|
t=s+1; /* target */
|
||||||
/* open the gap */
|
/* open the gap [cannot use memcpy] */
|
||||||
for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
|
for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
|
||||||
*dotat='.';
|
*dotat='.';
|
||||||
c++; /* length increased by one */
|
c++; /* length increased by one */
|
||||||
} /* need dot? */
|
} /* need dot? */
|
||||||
|
@ -1569,7 +1645,7 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
/* finally add the E-part, if needed; it will never be 0, and has */
|
/* finally add the E-part, if needed; it will never be 0, and has */
|
||||||
/* a maximum length of 3 or 4 digits (asserted above) */
|
/* a maximum length of 3 or 4 digits (asserted above) */
|
||||||
if (e!=0) {
|
if (e!=0) {
|
||||||
USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */
|
memcpy(c, "E+", 2); /* starts with E, assume + */
|
||||||
c++;
|
c++;
|
||||||
if (e<0) {
|
if (e<0) {
|
||||||
*c='-'; /* oops, need '-' */
|
*c='-'; /* oops, need '-' */
|
||||||
|
@ -1581,12 +1657,12 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
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 */
|
/* copy fixed 4 characters [is safe], starting at non-zero */
|
||||||
/* and with character mask to convert BCD to char */
|
/* 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 */
|
c+=*(u+3); /* bump pointer appropriately */
|
||||||
#elif DECEMAXD==4
|
#elif DECEMAXD==4
|
||||||
if (e<1000) { /* 3 (or fewer) digits case */
|
if (e<1000) { /* 3 (or fewer) digits case */
|
||||||
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
|
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 */
|
c+=*(u+3); /* bump pointer appropriately */
|
||||||
}
|
}
|
||||||
else { /* 4-digits */
|
else { /* 4-digits */
|
||||||
|
@ -1594,7 +1670,7 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
Int rem=e-(1000*thou); /* e%1000 */
|
Int rem=e-(1000*thou); /* e%1000 */
|
||||||
*c++=(char)('0'+(char)thou); /* the thousands digit */
|
*c++=(char)('0'+(char)thou); /* the thousands digit */
|
||||||
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
|
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+=3; /* bump pointer, always 3 digits */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1618,19 +1694,19 @@ char * decFloatToString(const decFloat *df, char *string){
|
||||||
/* backoff if too far to the right */
|
/* backoff if too far to the right */
|
||||||
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
|
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
|
||||||
/* now shift the entire coefficient to the right, being careful not */
|
/* now shift the entire coefficient to the right, being careful not */
|
||||||
/* to access to the left of string */
|
/* to access to the left of string [cannot use memcpy] */
|
||||||
for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s);
|
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... */
|
/* 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);
|
for(; s>=cstart; s--, t--) *(t+3)=*(s);
|
||||||
/* now have fill 0. through 0.00000; use overlaps to avoid tests */
|
/* now have fill 0. through 0.00000; use overlaps to avoid tests */
|
||||||
if (pre>=4) {
|
if (pre>=4) {
|
||||||
UINTAT(cstart+pre-4)=UINTAT("0000");
|
memcpy(cstart+pre-4, "0000", 4);
|
||||||
UINTAT(cstart)=UINTAT("0.00");
|
memcpy(cstart, "0.00", 4);
|
||||||
}
|
}
|
||||||
else { /* 2 or 3 */
|
else { /* 2 or 3 */
|
||||||
*(cstart+pre-1)='0';
|
*(cstart+pre-1)='0';
|
||||||
USHORTAT(cstart)=USHORTAT("0.");
|
memcpy(cstart, "0.", 2);
|
||||||
}
|
}
|
||||||
*(c+pre)='\0'; /* terminate */
|
*(c+pre)='\0'; /* terminate */
|
||||||
return string;
|
return string;
|
||||||
|
@ -1723,6 +1799,7 @@ decFloat * decFloatZero(decFloat *df){
|
||||||
void decShowNum(const bcdnum *num, const char *tag) {
|
void decShowNum(const bcdnum *num, const char *tag) {
|
||||||
const char *csign="+"; /* sign character */
|
const char *csign="+"; /* sign character */
|
||||||
uByte *ub; /* work */
|
uByte *ub; /* work */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
if (num->sign==DECFLOAT_Sign) csign="-";
|
if (num->sign==DECFLOAT_Sign) csign="-";
|
||||||
|
|
||||||
printf(">%s> ", tag);
|
printf(">%s> ", tag);
|
||||||
|
@ -1747,7 +1824,7 @@ decFloat * decFloatZero(decFloat *df){
|
||||||
if (e==0) *c++='0'; /* 0-length case */
|
if (e==0) *c++='0'; /* 0-length case */
|
||||||
else if (e<1000) { /* 3 (or fewer) digits case */
|
else if (e<1000) { /* 3 (or fewer) digits case */
|
||||||
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
|
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 */
|
c+=*(u+3); /* bump pointer appropriately */
|
||||||
}
|
}
|
||||||
else { /* 4-digits */
|
else { /* 4-digits */
|
||||||
|
@ -1755,7 +1832,7 @@ decFloat * decFloatZero(decFloat *df){
|
||||||
Int rem=e-(1000*thou); /* e%1000 */
|
Int rem=e-(1000*thou); /* e%1000 */
|
||||||
*c++=(char)('0'+(char)thou); /* the thousands digit */
|
*c++=(char)('0'+(char)thou); /* the thousands digit */
|
||||||
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
|
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+=3; /* bump pointer, always 3 digits */
|
||||||
}
|
}
|
||||||
*c='\0'; /* add terminator */
|
*c='\0'; /* add terminator */
|
||||||
|
|
|
@ -41,12 +41,10 @@
|
||||||
#include "decContext.h" /* context and base types */
|
#include "decContext.h" /* context and base types */
|
||||||
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
||||||
|
|
||||||
#if DECCHECK
|
|
||||||
/* compile-time endian tester [assumes sizeof(Int)>1] */
|
/* compile-time endian tester [assumes sizeof(Int)>1] */
|
||||||
static const Int mfcone=1; /* constant 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 */
|
#define LITEND *mfctop /* named flag; 1=little-endian */
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* round-for-reround digits */
|
/* round-for-reround digits */
|
||||||
|
@ -80,9 +78,9 @@ decContext *decContextClearStatus(decContext *context, uInt mask) {
|
||||||
/* context is the structure to be initialized */
|
/* context is the structure to be initialized */
|
||||||
/* kind selects the required set of default values, one of: */
|
/* kind selects the required set of default values, one of: */
|
||||||
/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
|
/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
|
||||||
/* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */
|
/* DEC_INIT_DECIMAL32 -- select IEEE 754 defaults, 32-bit */
|
||||||
/* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */
|
/* DEC_INIT_DECIMAL64 -- select IEEE 754 defaults, 64-bit */
|
||||||
/* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */
|
/* DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit */
|
||||||
/* For any other value a valid context is returned, but with */
|
/* For any other value a valid context is returned, but with */
|
||||||
/* Invalid_operation set in the status field. */
|
/* Invalid_operation set in the status field. */
|
||||||
/* returns a context structure with the appropriate initial values. */
|
/* returns a context structure with the appropriate initial values. */
|
||||||
|
@ -142,15 +140,6 @@ decContext * decContextDefault(decContext *context, Int kind) {
|
||||||
decContextSetStatus(context, DEC_Invalid_operation); /* trap */
|
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 */
|
return context;} /* decContextDefault */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
@ -389,6 +378,36 @@ const char *decContextStatusToString(const decContext *context) {
|
||||||
return DEC_Condition_MU; /* Multiple errors */
|
return DEC_Condition_MU; /* Multiple errors */
|
||||||
} /* decContextStatusToString */
|
} /* 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 */
|
/* decContextTestSavedStatus -- test bits in saved status */
|
||||||
/* */
|
/* */
|
||||||
|
|
|
@ -56,15 +56,21 @@
|
||||||
#define DECCFULLNAME "Decimal Context Descriptor" /* Verbose 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 <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 */
|
/* Extended flags setting -- set this to 0 to use only IEEE flags */
|
||||||
|
#if !defined(DECEXTFLAG)
|
||||||
#define DECEXTFLAG 1 /* 1=enable extended flags */
|
#define DECEXTFLAG 1 /* 1=enable extended flags */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Conditional code flag -- set this to 0 for best performance */
|
/* Conditional code flag -- set this to 0 for best performance */
|
||||||
|
#if !defined(DECSUBSET)
|
||||||
#define DECSUBSET 0 /* 1=enable subset arithmetic */
|
#define DECSUBSET 0 /* 1=enable subset arithmetic */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Context for operations, with associated constants */
|
/* Context for operations, with associated constants */
|
||||||
enum rounding {
|
enum rounding {
|
||||||
|
@ -102,9 +108,9 @@
|
||||||
#define DEC_MIN_EMIN -999999999
|
#define DEC_MIN_EMIN -999999999
|
||||||
#define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */
|
#define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */
|
||||||
|
|
||||||
/* Classifications for decimal numbers, aligned with 754r (note */
|
/* Classifications for decimal numbers, aligned with 754 (note that */
|
||||||
/* that 'normal' and 'subnormal' are meaningful only with a */
|
/* 'normal' and 'subnormal' are meaningful only with a decContext */
|
||||||
/* decContext or a fixed size format). */
|
/* or a fixed size format). */
|
||||||
enum decClass {
|
enum decClass {
|
||||||
DEC_CLASS_SNAN,
|
DEC_CLASS_SNAN,
|
||||||
DEC_CLASS_QNAN,
|
DEC_CLASS_QNAN,
|
||||||
|
@ -170,30 +176,30 @@
|
||||||
#define DEC_Underflow 0x00000004
|
#define DEC_Underflow 0x00000004
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* IEEE 854 groupings for the flags */
|
/* IEEE 754 groupings for the flags */
|
||||||
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */
|
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */
|
||||||
/* are not in IEEE 854] */
|
/* are not in IEEE 754] */
|
||||||
#define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero)
|
#define DEC_IEEE_754_Division_by_zero (DEC_Division_by_zero)
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
#define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits)
|
#define DEC_IEEE_754_Inexact (DEC_Inexact | DEC_Lost_digits)
|
||||||
#else
|
#else
|
||||||
#define DEC_IEEE_854_Inexact (DEC_Inexact)
|
#define DEC_IEEE_754_Inexact (DEC_Inexact)
|
||||||
#endif
|
#endif
|
||||||
#define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \
|
#define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax | \
|
||||||
DEC_Division_impossible | \
|
DEC_Division_impossible | \
|
||||||
DEC_Division_undefined | \
|
DEC_Division_undefined | \
|
||||||
DEC_Insufficient_storage | \
|
DEC_Insufficient_storage | \
|
||||||
DEC_Invalid_context | \
|
DEC_Invalid_context | \
|
||||||
DEC_Invalid_operation)
|
DEC_Invalid_operation)
|
||||||
#define DEC_IEEE_854_Overflow (DEC_Overflow)
|
#define DEC_IEEE_754_Overflow (DEC_Overflow)
|
||||||
#define DEC_IEEE_854_Underflow (DEC_Underflow)
|
#define DEC_IEEE_754_Underflow (DEC_Underflow)
|
||||||
|
|
||||||
/* flags which are normally errors (result is qNaN, infinite, or 0) */
|
/* flags which are normally errors (result is qNaN, infinite, or 0) */
|
||||||
#define DEC_Errors (DEC_IEEE_854_Division_by_zero | \
|
#define DEC_Errors (DEC_IEEE_754_Division_by_zero | \
|
||||||
DEC_IEEE_854_Invalid_operation | \
|
DEC_IEEE_754_Invalid_operation | \
|
||||||
DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow)
|
DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)
|
||||||
/* flags which cause a result to become qNaN */
|
/* 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) */
|
/* flags which are normally for information only (finite results) */
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
|
@ -203,6 +209,13 @@
|
||||||
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
|
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
|
||||||
#endif
|
#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 */
|
/* Name strings for the exceptional conditions */
|
||||||
#define DEC_Condition_CS "Conversion syntax"
|
#define DEC_Condition_CS "Conversion syntax"
|
||||||
#define DEC_Condition_DZ "Division by zero"
|
#define DEC_Condition_DZ "Division by zero"
|
||||||
|
@ -251,6 +264,7 @@
|
||||||
extern decContext * decContextSetStatusFromStringQuiet(decContext *, const char *);
|
extern decContext * decContextSetStatusFromStringQuiet(decContext *, const char *);
|
||||||
extern decContext * decContextSetStatusQuiet(decContext *, uint32_t);
|
extern decContext * decContextSetStatusQuiet(decContext *, uint32_t);
|
||||||
extern const char * decContextStatusToString(const decContext *);
|
extern const char * decContextStatusToString(const decContext *);
|
||||||
|
extern int32_t decContextTestEndian(uint8_t);
|
||||||
extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
|
extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
|
||||||
extern uint32_t decContextTestStatus(decContext *, uint32_t);
|
extern uint32_t decContextTestStatus(decContext *, uint32_t);
|
||||||
extern decContext * decContextZeroStatus(decContext *);
|
extern decContext * decContextZeroStatus(decContext *);
|
||||||
|
|
|
@ -30,10 +30,9 @@
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
/* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
|
/* 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 DPDecimal.html on the General Decimal Arithmetic page. */
|
||||||
/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */
|
|
||||||
|
|
||||||
#include "decDPDSymbols.h"
|
#include "decDPDSymbols.h"
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
#define decFloatFromBCD decDoubleFromBCD
|
#define decFloatFromBCD decDoubleFromBCD
|
||||||
#define decFloatFromInt32 decDoubleFromInt32
|
#define decFloatFromInt32 decDoubleFromInt32
|
||||||
#define decFloatFromPacked decDoubleFromPacked
|
#define decFloatFromPacked decDoubleFromPacked
|
||||||
|
#define decFloatFromPackedChecked decDoubleFromPackedChecked
|
||||||
#define decFloatFromString decDoubleFromString
|
#define decFloatFromString decDoubleFromString
|
||||||
#define decFloatFromUInt32 decDoubleFromUInt32
|
#define decFloatFromUInt32 decDoubleFromUInt32
|
||||||
#define decFloatFromWider decDoubleFromWider
|
#define decFloatFromWider decDoubleFromWider
|
||||||
|
@ -145,10 +146,7 @@
|
||||||
#define decFloatSameQuantum decDoubleSameQuantum
|
#define decFloatSameQuantum decDoubleSameQuantum
|
||||||
#define decFloatVersion decDoubleVersion
|
#define decFloatVersion decDoubleVersion
|
||||||
|
|
||||||
|
|
||||||
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
||||||
#include "decCommon.c" /* non-arithmetic decFloat routines */
|
#include "decCommon.c" /* non-arithmetic decFloat routines */
|
||||||
#include "decBasic.c" /* basic formats routines */
|
#include "decBasic.c" /* basic formats routines */
|
||||||
|
|
||||||
/* Below here will move to shared file as completed */
|
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decDouble.h -- Decimal 64-bit format module header */
|
/* decDouble.h -- Decimal 64-bit format module header */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Please see decFloats.h for an overview and documentation details. */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#if !defined(DECDOUBLE)
|
#if !defined(DECDOUBLE)
|
||||||
#define DECDOUBLE
|
#define DECDOUBLE
|
||||||
|
@ -58,11 +56,14 @@
|
||||||
#include "decContext.h"
|
#include "decContext.h"
|
||||||
#include "decQuad.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 {
|
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];
|
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;
|
} decDouble;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
@ -75,6 +76,7 @@
|
||||||
extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t);
|
extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t);
|
||||||
extern decDouble * decDoubleFromInt32(decDouble *, int32_t);
|
extern decDouble * decDoubleFromInt32(decDouble *, int32_t);
|
||||||
extern decDouble * decDoubleFromPacked(decDouble *, int32_t, const uint8_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 * decDoubleFromString(decDouble *, const char *, decContext *);
|
||||||
extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t);
|
extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t);
|
||||||
extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *);
|
extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *);
|
||||||
|
@ -160,7 +162,8 @@
|
||||||
|
|
||||||
/* decNumber conversions; these are implemented as macros so as not */
|
/* decNumber conversions; these are implemented as macros so as not */
|
||||||
/* to force a dependency on decimal64 and decNumber in decDouble. */
|
/* 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 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
|
#endif
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Decimal Number arithmetic module */
|
/* Decimal Number arithmetic module */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* This module comprises the routines for General Decimal Arithmetic */
|
/* This module comprises the routines for arbitrary-precision General */
|
||||||
/* as defined in the specification which may be found on the */
|
/* Decimal Arithmetic as defined in the specification which may be */
|
||||||
/* http://www2.hursley.ibm.com/decimal web pages. It implements both */
|
/* found on the General Decimal Arithmetic pages. It implements both */
|
||||||
/* the full ('extended') arithmetic and the simpler ('subset') */
|
/* the full ('extended') arithmetic and the simpler ('subset') */
|
||||||
/* arithmetic. */
|
/* arithmetic. */
|
||||||
/* */
|
/* */
|
||||||
|
@ -41,10 +41,21 @@
|
||||||
/* */
|
/* */
|
||||||
/* 1. This code is ANSI C89 except: */
|
/* 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 */
|
/* uint64_t types may be used. To avoid these, set DECUSE64=0 */
|
||||||
/* and DECDPUN<=4 (see documentation). */
|
/* 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 */
|
/* 2. The decNumber format which this library uses is optimized for */
|
||||||
/* efficient processing of relatively short numbers; in particular */
|
/* efficient processing of relatively short numbers; in particular */
|
||||||
/* it allows the use of fixed sized structures and minimizes copy */
|
/* it allows the use of fixed sized structures and minimizes copy */
|
||||||
|
@ -262,7 +273,7 @@ static Int decShiftToLeast(Unit *, Int, Int);
|
||||||
static Int decShiftToMost(Unit *, Int, Int);
|
static Int decShiftToMost(Unit *, Int, Int);
|
||||||
static void decStatus(decNumber *, uInt, decContext *);
|
static void decStatus(decNumber *, uInt, decContext *);
|
||||||
static void decToString(const decNumber *, char[], Flag);
|
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,
|
static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
|
||||||
Unit *, Int);
|
Unit *, Int);
|
||||||
static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
|
static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
|
||||||
|
@ -1156,7 +1167,7 @@ decNumber * decNumberFMA(decNumber *res, const decNumber *lhs,
|
||||||
}
|
}
|
||||||
#if DECCHECK
|
#if DECCHECK
|
||||||
else { /* multiply was OK */
|
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
|
#endif
|
||||||
/* add the third operand and result -> res, and all is done */
|
/* add the third operand and result -> res, and all is done */
|
||||||
|
@ -1301,7 +1312,7 @@ decNumber * decNumberLn(decNumber *res, const decNumber *rhs,
|
||||||
} /* decNumberLn */
|
} /* decNumberLn */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decNumberLogB - get adjusted exponent, by 754r rules */
|
/* decNumberLogB - get adjusted exponent, by 754 rules */
|
||||||
/* */
|
/* */
|
||||||
/* This computes C = adjustedexponent(A) */
|
/* This computes C = adjustedexponent(A) */
|
||||||
/* */
|
/* */
|
||||||
|
@ -1338,7 +1349,7 @@ decNumber * decNumberLogB(decNumber *res, const decNumber *rhs,
|
||||||
else if (decNumberIsZero(rhs)) {
|
else if (decNumberIsZero(rhs)) {
|
||||||
decNumberZero(res); /* prepare for Infinity */
|
decNumberZero(res); /* prepare for Infinity */
|
||||||
res->bits=DECNEG|DECINF; /* -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 */
|
else { /* finite non-zero */
|
||||||
Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
|
Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
|
||||||
|
@ -1519,7 +1530,7 @@ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decNumberMax -- compare two Numbers and return the maximum */
|
/* 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) */
|
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
|
||||||
/* lhs is A */
|
/* lhs is A */
|
||||||
|
@ -1542,7 +1553,7 @@ decNumber * decNumberMax(decNumber *res, const decNumber *lhs,
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decNumberMaxMag -- compare and return the maximum by magnitude */
|
/* 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) */
|
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
|
||||||
/* lhs is A */
|
/* lhs is A */
|
||||||
|
@ -1565,7 +1576,7 @@ decNumber * decNumberMaxMag(decNumber *res, const decNumber *lhs,
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decNumberMin -- compare two Numbers and return the minimum */
|
/* 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) */
|
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
|
||||||
/* lhs is A */
|
/* lhs is A */
|
||||||
|
@ -1588,7 +1599,7 @@ decNumber * decNumberMin(decNumber *res, const decNumber *lhs,
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decNumberMinMag -- compare and return the minimum by magnitude */
|
/* 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) */
|
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
|
||||||
/* lhs is A */
|
/* lhs is A */
|
||||||
|
@ -1650,7 +1661,7 @@ decNumber * decNumberMinus(decNumber *res, const decNumber *rhs,
|
||||||
/* rhs is 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,
|
decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
|
||||||
decContext *set) {
|
decContext *set) {
|
||||||
|
@ -1686,7 +1697,7 @@ decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
|
||||||
/* rhs is 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,
|
decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
|
||||||
decContext *set) {
|
decContext *set) {
|
||||||
|
@ -1718,14 +1729,15 @@ decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
|
||||||
/* decNumberNextToward -- next towards rhs */
|
/* decNumberNextToward -- next towards rhs */
|
||||||
/* */
|
/* */
|
||||||
/* This computes C = A +/- infinitesimal, rounded towards */
|
/* 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. */
|
/* res is C, the result. C may be A or B. */
|
||||||
/* lhs is A */
|
/* lhs is A */
|
||||||
/* rhs is B */
|
/* 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,
|
decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs,
|
||||||
const decNumber *rhs, decContext *set) {
|
const decNumber *rhs, decContext *set) {
|
||||||
|
@ -2242,7 +2254,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs,
|
||||||
decCopyFit(res, dac, set, &residue, &status);
|
decCopyFit(res, dac, set, &residue, &status);
|
||||||
decFinish(res, set, &residue, &status); /* final cleanup */
|
decFinish(res, set, &residue, &status); /* final cleanup */
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
if (!set->extended) decTrim(res, set, 0, &dropped); /* trailing zeros */
|
if (!set->extended) decTrim(res, set, 0, 1, &dropped); /* trailing zeros */
|
||||||
#endif
|
#endif
|
||||||
} while(0); /* end protected */
|
} while(0); /* end protected */
|
||||||
|
|
||||||
|
@ -2337,7 +2349,8 @@ decNumber * decNumberReduce(decNumber *res, const decNumber *rhs,
|
||||||
/* reduce result to the requested length and copy to result */
|
/* reduce result to the requested length and copy to result */
|
||||||
decCopyFit(res, rhs, set, &residue, &status); /* copy & round */
|
decCopyFit(res, rhs, set, &residue, &status); /* copy & round */
|
||||||
decFinish(res, set, &residue, &status); /* cleanup/set flags */
|
decFinish(res, set, &residue, &status); /* cleanup/set flags */
|
||||||
decTrim(res, set, 1, &dropped); /* normalize in place */
|
decTrim(res, set, 1, 0, &dropped); /* normalize in place */
|
||||||
|
/* [may clamp] */
|
||||||
} while(0); /* end protected */
|
} while(0); /* end protected */
|
||||||
|
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
|
@ -2849,7 +2862,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate the ideal (preferred) exponent [floor(exp/2)] */
|
/* 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.] */
|
/* generates a compiler warning. Generated code is the same.] */
|
||||||
ideal=(rhs->exponent&~1)/2; /* target */
|
ideal=(rhs->exponent&~1)/2; /* target */
|
||||||
|
|
||||||
|
@ -2876,6 +2889,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
|
||||||
/* b -- intermediate temporary result (same size as a) */
|
/* b -- intermediate temporary result (same size as a) */
|
||||||
/* if any is too long for local storage, then allocate */
|
/* if any is too long for local storage, then allocate */
|
||||||
workp=MAXI(set->digits+1, rhs->digits); /* actual rounding precision */
|
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 */
|
maxp=workp+2; /* largest working precision */
|
||||||
|
|
||||||
needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
|
needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
|
||||||
|
@ -2905,6 +2919,8 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
|
||||||
|
|
||||||
/* set up working context */
|
/* set up working context */
|
||||||
decContextDefault(&workset, DEC_INIT_DECIMAL64);
|
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 */
|
/* [Until further notice, no error is possible and status bits */
|
||||||
/* (Rounded, etc.) should be ignored, not accumulated.] */
|
/* (Rounded, etc.) should be ignored, not accumulated.] */
|
||||||
|
@ -2945,6 +2961,7 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
|
||||||
a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
|
a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */
|
decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */
|
||||||
decAddOp(a, a, t, &workset, 0, &ignore); /* ..+t */
|
decAddOp(a, a, t, &workset, 0, &ignore); /* ..+t */
|
||||||
/* [a is now the initial approximation for sqrt(f), calculated with */
|
/* [a is now the initial approximation for sqrt(f), calculated with */
|
||||||
|
@ -2956,16 +2973,14 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
|
||||||
t->lsu[0]=5; /* .. */
|
t->lsu[0]=5; /* .. */
|
||||||
t->exponent=-1; /* .. */
|
t->exponent=-1; /* .. */
|
||||||
workset.digits=3; /* initial p */
|
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] */
|
/* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */
|
||||||
workset.digits=workset.digits*2-2;
|
workset.digits=MINI(workset.digits*2-2, maxp);
|
||||||
if (workset.digits>maxp) workset.digits=maxp;
|
|
||||||
/* a = 0.5 * (a + f/a) */
|
/* a = 0.5 * (a + f/a) */
|
||||||
/* [calculated at p then rounded to currentprecision] */
|
/* [calculated at p then rounded to currentprecision] */
|
||||||
decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a */
|
decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a */
|
||||||
decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */
|
decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */
|
||||||
decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */
|
decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */
|
||||||
if (a->digits==maxp) break; /* have required digits */
|
|
||||||
} /* loop */
|
} /* loop */
|
||||||
|
|
||||||
/* Here, 0.1 <= a < 1 [Hull], and a has maxp digits */
|
/* Here, 0.1 <= a < 1 [Hull], and a has maxp digits */
|
||||||
|
@ -2975,7 +2990,6 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
|
||||||
approxset=*set; /* get emin, emax, etc. */
|
approxset=*set; /* get emin, emax, etc. */
|
||||||
approxset.round=DEC_ROUND_HALF_EVEN;
|
approxset.round=DEC_ROUND_HALF_EVEN;
|
||||||
a->exponent+=exp/2; /* set correct exponent */
|
a->exponent+=exp/2; /* set correct exponent */
|
||||||
|
|
||||||
rstatus=0; /* clear status */
|
rstatus=0; /* clear status */
|
||||||
residue=0; /* .. and accumulator */
|
residue=0; /* .. and accumulator */
|
||||||
decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */
|
decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */
|
||||||
|
@ -3040,13 +3054,13 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
|
||||||
/* count droppable zeros [after any subnormal rounding] by */
|
/* count droppable zeros [after any subnormal rounding] by */
|
||||||
/* trimming a copy */
|
/* trimming a copy */
|
||||||
decNumberCopy(b, a);
|
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 */
|
/* Set Inexact and Rounded. The answer can only be exact if */
|
||||||
/* it is short enough so that squaring it could fit in workp digits, */
|
/* it is short enough so that squaring it could fit in workp */
|
||||||
/* and it cannot have trailing zeros due to clamping, so these are */
|
/* digits, so this is the only (relatively rare) condition that */
|
||||||
/* the only (relatively rare) conditions a careful check is needed */
|
/* a careful check is needed */
|
||||||
if (b->digits*2-1 > workp && !set->clamp) { /* cannot fit */
|
if (b->digits*2-1 > workp) { /* cannot fit */
|
||||||
status|=DEC_Inexact|DEC_Rounded;
|
status|=DEC_Inexact|DEC_Rounded;
|
||||||
}
|
}
|
||||||
else { /* could be exact/unrounded */
|
else { /* could be exact/unrounded */
|
||||||
|
@ -3064,6 +3078,13 @@ decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
|
||||||
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 */
|
if (todrop<0) status|=DEC_Rounded; /* ideally would add 0s */
|
||||||
else { /* unrounded */
|
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 */
|
if (dropped<todrop) { /* clamp to those available */
|
||||||
todrop=dropped;
|
todrop=dropped;
|
||||||
status|=DEC_Clamped;
|
status|=DEC_Clamped;
|
||||||
|
@ -3432,7 +3453,7 @@ decNumber * decNumberCopySign(decNumber *res, const decNumber *lhs,
|
||||||
/* bcd must have at least dn->digits bytes. No error is possible; if */
|
/* 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. */
|
/* 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 */
|
uByte *ub=bcd+dn->digits-1; /* -> lsd */
|
||||||
const Unit *up=dn->lsu; /* Unit pointer, -> lsu */
|
const Unit *up=dn->lsu; /* Unit pointer, -> lsu */
|
||||||
|
|
||||||
|
@ -3532,7 +3553,8 @@ Int decNumberIsSubnormal(const decNumber *dn, decContext *set) {
|
||||||
/* returns dn */
|
/* returns dn */
|
||||||
/* */
|
/* */
|
||||||
/* All fields are updated as required. This is a utility operation, */
|
/* 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) {
|
decNumber * decNumberTrim(decNumber *dn) {
|
||||||
Int dropped; /* work */
|
Int dropped; /* work */
|
||||||
|
@ -3541,7 +3563,7 @@ decNumber * decNumberTrim(decNumber *dn) {
|
||||||
if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
|
if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
|
||||||
#endif
|
#endif
|
||||||
decContextDefault(&set, DEC_INIT_BASE); /* clamp=0 */
|
decContextDefault(&set, DEC_INIT_BASE); /* clamp=0 */
|
||||||
return decTrim(dn, &set, 0, &dropped);
|
return decTrim(dn, &set, 0, 1, &dropped);
|
||||||
} /* decNumberTrim */
|
} /* decNumberTrim */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
@ -3857,7 +3879,7 @@ static decNumber * decAddOp(decNumber *res, const decNumber *lhs,
|
||||||
#endif
|
#endif
|
||||||
/* exponent will be the lower of the two */
|
/* exponent will be the lower of the two */
|
||||||
adjust=lexp-res->exponent; /* adjustment needed [if -ve] */
|
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 */
|
if (adjust<0) res->exponent=lexp; /* set exponent */
|
||||||
/* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */
|
/* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */
|
||||||
if (diffsign) {
|
if (diffsign) {
|
||||||
|
@ -4206,7 +4228,7 @@ static decNumber * decDivideOp(decNumber *res,
|
||||||
Int accunits; /* count of units accumulated */
|
Int accunits; /* count of units accumulated */
|
||||||
Int accdigits; /* count of digits 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 *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 */
|
Unit *msu1; /* -> msu of var1 */
|
||||||
|
@ -4761,7 +4783,7 @@ static decNumber * decDivideOp(decNumber *res,
|
||||||
|
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
/* If a divide then strip trailing zeros if subset [after round] */
|
/* 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
|
#endif
|
||||||
} while(0); /* end protected */
|
} while(0); /* end protected */
|
||||||
|
|
||||||
|
@ -5426,7 +5448,7 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs,
|
||||||
/* just a sanity check; comment out test to show always */
|
/* just a sanity check; comment out test to show always */
|
||||||
if (iterations>p+3)
|
if (iterations>p+3)
|
||||||
printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
|
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
|
#endif
|
||||||
} /* h<=8 */
|
} /* h<=8 */
|
||||||
|
|
||||||
|
@ -5766,7 +5788,7 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs,
|
||||||
/* just a sanity check; remove the test to show always */
|
/* just a sanity check; remove the test to show always */
|
||||||
if (iterations>24)
|
if (iterations>24)
|
||||||
printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
|
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
|
#endif
|
||||||
|
|
||||||
/* Copy and round the result to res */
|
/* Copy and round the result to res */
|
||||||
|
@ -5937,7 +5959,7 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
decFinalize(res, set, &residue, status); /* set subnormal flags */
|
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 */
|
||||||
|
|
||||||
|
@ -5958,12 +5980,12 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
|
||||||
/* COMPSIG -- as COMPARE except that a quiet NaN raises */
|
/* COMPSIG -- as COMPARE except that a quiet NaN raises */
|
||||||
/* Invalid operation. */
|
/* Invalid operation. */
|
||||||
/* COMPMAX -- returns the larger of the operands, using the */
|
/* COMPMAX -- returns the larger of the operands, using the */
|
||||||
/* 754r maxnum operation */
|
/* 754 maxnum operation */
|
||||||
/* COMPMAXMAG -- ditto, comparing absolute values */
|
/* COMPMAXMAG -- ditto, comparing absolute values */
|
||||||
/* COMPMIN -- the 754r minnum operation */
|
/* COMPMIN -- the 754 minnum operation */
|
||||||
/* COMPMINMAG -- ditto, comparing absolute values */
|
/* COMPMINMAG -- ditto, comparing absolute values */
|
||||||
/* COMTOTAL -- returns the signum (as a number) giving the */
|
/* COMTOTAL -- returns the signum (as a number) giving the */
|
||||||
/* result of a comparison using 754r total ordering */
|
/* 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) */
|
/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
|
||||||
/* lhs is A */
|
/* lhs is A */
|
||||||
|
@ -6049,7 +6071,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
|
||||||
|
|
||||||
else if (merged & DECSNAN); /* sNaN -> qNaN */
|
else if (merged & DECSNAN); /* sNaN -> qNaN */
|
||||||
else { /* here if MIN or MAX and one or two quiet NaNs */
|
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)) {
|
if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
|
||||||
/* just one NaN; force choice to be the non-NaN operand */
|
/* just one NaN; force choice to be the non-NaN operand */
|
||||||
op=COMPMAX;
|
op=COMPMAX;
|
||||||
|
@ -6091,7 +6113,7 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
|
||||||
/* choose the operand for the result */
|
/* choose the operand for the result */
|
||||||
const decNumber *choice;
|
const decNumber *choice;
|
||||||
if (result==0) { /* operands are numerically equal */
|
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 slhs=(lhs->bits & DECNEG);
|
||||||
uByte srhs=(rhs->bits & DECNEG);
|
uByte srhs=(rhs->bits & DECNEG);
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
|
@ -6556,6 +6578,7 @@ static Int decUnitAddSub(const Unit *a, Int alength,
|
||||||
/* dn is the number to trim or normalize */
|
/* dn is the number to trim or normalize */
|
||||||
/* set is the context to use to check for clamp */
|
/* set is the context to use to check for clamp */
|
||||||
/* all is 1 to remove all trailing zeros, 0 for just fraction ones */
|
/* 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 */
|
/* dropped returns the number of discarded trailing zeros */
|
||||||
/* returns dn */
|
/* returns dn */
|
||||||
/* */
|
/* */
|
||||||
|
@ -6565,7 +6588,7 @@ static Int decUnitAddSub(const Unit *a, Int alength,
|
||||||
/* so special values are unchanged and no error is possible. */
|
/* so special values are unchanged and no error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
|
static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
|
||||||
Int *dropped) {
|
Flag noclamp, Int *dropped) {
|
||||||
Int d, exp; /* work */
|
Int d, exp; /* work */
|
||||||
uInt cut; /* .. */
|
uInt cut; /* .. */
|
||||||
Unit *up; /* -> current Unit */
|
Unit *up; /* -> current Unit */
|
||||||
|
@ -6611,7 +6634,7 @@ static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
|
||||||
if (d==0) return dn; /* none to drop */
|
if (d==0) return dn; /* none to drop */
|
||||||
|
|
||||||
/* may need to limit drop if clamping */
|
/* may need to limit drop if clamping */
|
||||||
if (set->clamp) {
|
if (set->clamp && !noclamp) {
|
||||||
Int maxd=set->emax-set->digits+1-dn->exponent;
|
Int maxd=set->emax-set->digits+1-dn->exponent;
|
||||||
if (maxd<=0) return dn; /* nothing possible */
|
if (maxd<=0) return dn; /* nothing possible */
|
||||||
if (d>maxd) d=maxd;
|
if (d>maxd) d=maxd;
|
||||||
|
@ -7319,7 +7342,7 @@ static void decFinalize(decNumber *dn, decContext *set, Int *residue,
|
||||||
/* */
|
/* */
|
||||||
/* This sets the sign of a number and sets its value to either */
|
/* This sets the sign of a number and sets its value to either */
|
||||||
/* Infinity or the maximum finite value, depending on the sign of */
|
/* 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) {
|
static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) {
|
||||||
Flag needmax=0; /* result is maximum finite value */
|
Flag needmax=0; /* result is maximum finite value */
|
||||||
|
@ -7403,7 +7426,6 @@ static void decSetMaxValue(decNumber *dn, decContext *set) {
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
|
static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
|
||||||
uInt *status) {
|
uInt *status) {
|
||||||
Int dnexp; /* saves original exponent */
|
|
||||||
decContext workset; /* work */
|
decContext workset; /* work */
|
||||||
Int etiny, adjust; /* .. */
|
Int etiny, adjust; /* .. */
|
||||||
|
|
||||||
|
@ -7448,7 +7470,6 @@ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
|
||||||
|
|
||||||
/* adjust>0, so need to rescale the result so exponent becomes Etiny */
|
/* adjust>0, so need to rescale the result so exponent becomes Etiny */
|
||||||
/* [this code is similar to that in rescale] */
|
/* [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.digits=dn->digits-adjust; /* set requested length */
|
||||||
workset.emin-=adjust; /* and adjust emin to match */
|
workset.emin-=adjust; /* and adjust emin to match */
|
||||||
|
@ -7456,7 +7477,7 @@ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
|
||||||
decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
|
decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
|
||||||
decApplyRound(dn, &workset, *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] */
|
/* [independent of whether trapped] */
|
||||||
if (*status&DEC_Inexact) *status|=DEC_Underflow;
|
if (*status&DEC_Inexact) *status|=DEC_Underflow;
|
||||||
|
|
||||||
|
@ -8071,16 +8092,15 @@ static void decCheckInexact(const decNumber *dn, decContext *set) {
|
||||||
static void *decMalloc(size_t n) {
|
static void *decMalloc(size_t n) {
|
||||||
uInt size=n+12; /* true size */
|
uInt size=n+12; /* true size */
|
||||||
void *alloc; /* -> allocated storage */
|
void *alloc; /* -> allocated storage */
|
||||||
uInt *j; /* work */
|
uByte *b, *b0; /* work */
|
||||||
uByte *b, *b0; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
|
|
||||||
alloc=malloc(size); /* -> allocated storage */
|
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 */
|
b0=(uByte *)alloc; /* as bytes */
|
||||||
decAllocBytes+=n; /* account for storage */
|
decAllocBytes+=n; /* account for storage */
|
||||||
j=(uInt *)alloc; /* -> first four bytes */
|
UBFROMUI(alloc, n); /* save n */
|
||||||
*j=n; /* save n */
|
/* printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n); */
|
||||||
/* printf(" alloc ++ dAB: %ld (%d)\n", decAllocBytes, n); */
|
|
||||||
for (b=b0+4; b<b0+8; b++) *b=DECFENCE;
|
for (b=b0+4; b<b0+8; b++) *b=DECFENCE;
|
||||||
for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;
|
for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;
|
||||||
return b0+8; /* -> play area */
|
return b0+8; /* -> play area */
|
||||||
|
@ -8099,20 +8119,20 @@ static void *decMalloc(size_t n) {
|
||||||
/* is, offset by 8). */
|
/* is, offset by 8). */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
static void decFree(void *alloc) {
|
static void decFree(void *alloc) {
|
||||||
uInt *j, n; /* pointer, original length */
|
uInt n; /* original length */
|
||||||
uByte *b, *b0; /* work */
|
uByte *b, *b0; /* work */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
|
|
||||||
if (alloc==NULL) return; /* allowed; it's a nop */
|
if (alloc==NULL) return; /* allowed; it's a nop */
|
||||||
b0=(uByte *)alloc; /* as bytes */
|
b0=(uByte *)alloc; /* as bytes */
|
||||||
b0-=8; /* -> true start of storage */
|
b0-=8; /* -> true start of storage */
|
||||||
j=(uInt *)b0; /* -> first four bytes */
|
n=UBTOUI(b0); /* lift length */
|
||||||
n=*j; /* lift */
|
|
||||||
for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)
|
for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)
|
||||||
printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b,
|
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)
|
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,
|
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 */
|
free(b0); /* drop the storage */
|
||||||
decAllocBytes-=n; /* account for storage */
|
decAllocBytes-=n; /* account for storage */
|
||||||
/* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n); */
|
/* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n); */
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
#if !defined(DECNUMBERLOC)
|
#if !defined(DECNUMBERLOC)
|
||||||
#define 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 */
|
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
#include <stdlib.h> /* for abs */
|
#include <stdlib.h> /* for abs */
|
||||||
|
@ -54,19 +54,33 @@
|
||||||
#define DECLITEND 1
|
#define DECLITEND 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(DECLITEND)
|
||||||
|
#define DECLITEND 1 /* 1=little-endian, 0=big-endian */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Conditional code flag -- set this to 1 for best performance */
|
/* Conditional code flag -- set this to 1 for best performance */
|
||||||
|
#if !defined(DECUSE64)
|
||||||
#define DECUSE64 1 /* 1=use int64s, 0=int32 & smaller only */
|
#define DECUSE64 1 /* 1=use int64s, 0=int32 & smaller only */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Conditional check flags -- set these to 0 for best performance */
|
/* Conditional check flags -- set these to 0 for best performance */
|
||||||
|
#if !defined(DECCHECK)
|
||||||
#define DECCHECK 0 /* 1 to enable robust checking */
|
#define DECCHECK 0 /* 1 to enable robust checking */
|
||||||
|
#endif
|
||||||
|
#if !defined(DECALLOC)
|
||||||
#define DECALLOC 0 /* 1 to enable memory accounting */
|
#define DECALLOC 0 /* 1 to enable memory accounting */
|
||||||
|
#endif
|
||||||
|
#if !defined(DECTRACE)
|
||||||
#define DECTRACE 0 /* 1 to trace certain internals, etc. */
|
#define DECTRACE 0 /* 1 to trace certain internals, etc. */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Tuning parameter for decNumber (arbitrary precision) module */
|
/* Tuning parameter for decNumber (arbitrary precision) module */
|
||||||
|
#if !defined(DECBUFFER)
|
||||||
#define DECBUFFER 36 /* Size basis for local buffers. This */
|
#define DECBUFFER 36 /* Size basis for local buffers. This */
|
||||||
/* should be a common maximum precision */
|
/* should be a common maximum precision */
|
||||||
/* rounded up to a multiple of 4; must */
|
/* rounded up to a multiple of 4; must */
|
||||||
/* be zero or positive. */
|
/* be zero or positive. */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* Definitions for all modules (general-purpose) */
|
/* Definitions for all modules (general-purpose) */
|
||||||
|
@ -90,6 +104,7 @@
|
||||||
/* Development-use definitions */
|
/* Development-use definitions */
|
||||||
typedef long int LI; /* for printf arguments only */
|
typedef long int LI; /* for printf arguments only */
|
||||||
#define DECNOINT 0 /* 1 to check no internal use of 'int' */
|
#define DECNOINT 0 /* 1 to check no internal use of 'int' */
|
||||||
|
/* or stdint types */
|
||||||
#if DECNOINT
|
#if DECNOINT
|
||||||
/* if these interfere with your C includes, do not set DECNOINT */
|
/* if these interfere with your C includes, do not set DECNOINT */
|
||||||
#define int ? /* enable to ensure that plain C 'int' */
|
#define int ? /* enable to ensure that plain C 'int' */
|
||||||
|
@ -100,7 +115,7 @@
|
||||||
extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
|
extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
|
||||||
extern const uInt DECPOWERS[10]; /* powers of ten table */
|
extern const uInt DECPOWERS[10]; /* powers of ten table */
|
||||||
/* The following are included from decDPD.h */
|
/* The following are included from decDPD.h */
|
||||||
#include "decDPDSymbols.h"
|
#include "decDPDSymbols.h"
|
||||||
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
|
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
|
||||||
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
|
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
|
||||||
extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */
|
extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */
|
||||||
|
@ -126,17 +141,27 @@
|
||||||
|
|
||||||
/* ROUNDUP -- round an integer up to a multiple of n */
|
/* ROUNDUP -- round an integer up to a multiple of n */
|
||||||
#define ROUNDUP(i, n) ((((i)+(n)-1)/n)*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 */
|
/* ROUNDDOWN -- round an integer down to a multiple of n */
|
||||||
#define ROUNDDOWN(i, n) (((i)/n)*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 */
|
/* References to multi-byte sequences under different sizes; these */
|
||||||
/* Refer to a uInt from four bytes starting at a char* or uByte*, */
|
/* require locally declared variables, but do not violate strict */
|
||||||
/* etc. */
|
/* aliasing or alignment (as did the UINTAT simple cast to uInt). */
|
||||||
#define UINTAT(b) (*((uInt *)(b)))
|
/* Variables needed are uswork, uiwork, etc. [so do not use at same */
|
||||||
#define USHORTAT(b) (*((uShort *)(b)))
|
/* level in an expression, e.g., UBTOUI(x)==UBTOUI(y) may fail]. */
|
||||||
#define UBYTEAT(b) (*((uByte *)(b)))
|
|
||||||
|
/* Return a uInt, etc., from bytes starting at a char* or uByte* */
|
||||||
|
#define UBTOUS(b) (memcpy((void *)&uswork, b, 2), uswork)
|
||||||
|
#define UBTOUI(b) (memcpy((void *)&uiwork, b, 4), uiwork)
|
||||||
|
|
||||||
|
/* Store a uInt, etc., into bytes starting at a char* or uByte*. */
|
||||||
|
/* Returns i, evaluated, for convenience; has to use uiwork because */
|
||||||
|
/* i may be an expression. */
|
||||||
|
#define UBFROMUS(b, i) (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork)
|
||||||
|
#define UBFROMUI(b, i) (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork)
|
||||||
|
|
||||||
/* X10 and X100 -- multiply integer i by 10 or 100 */
|
/* X10 and X100 -- multiply integer i by 10 or 100 */
|
||||||
/* [shifts are usually faster than multiply; could be conditional] */
|
/* [shifts are usually faster than multiply; could be conditional] */
|
||||||
|
@ -308,12 +333,12 @@
|
||||||
#define DECWORDS (DECBYTES/4)
|
#define DECWORDS (DECBYTES/4)
|
||||||
#define DECWWORDS (DECWBYTES/4)
|
#define DECWWORDS (DECWBYTES/4)
|
||||||
#if DECLITEND
|
#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)])
|
#define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
|
||||||
#else
|
#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])
|
#define DFWWORD(dfw, off) ((dfw)->words[off])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -412,21 +437,31 @@
|
||||||
|| ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
|
|| ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
|
||||||
|
|
||||||
/* Macro to test whether a full-length (length DECPMAX) BCD8 */
|
/* Macro to test whether a full-length (length DECPMAX) BCD8 */
|
||||||
/* coefficient is zero */
|
/* coefficient, starting at uByte u, is all zeros */
|
||||||
/* test just the LSWord first, then the remainder */
|
/* 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
|
#if DECPMAX==7
|
||||||
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
|
#define ISCOEFFZERO(u) ( \
|
||||||
&& UINTAT((u)+DECPMAX-7)==0)
|
UBTOUI((u)+DECPMAX-4)==0 \
|
||||||
|
&& UBTOUS((u)+DECPMAX-6)==0 \
|
||||||
|
&& *(u)==0)
|
||||||
#elif DECPMAX==16
|
#elif DECPMAX==16
|
||||||
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
|
#define ISCOEFFZERO(u) ( \
|
||||||
&& (UINTAT((u)+DECPMAX-8)+UINTAT((u)+DECPMAX-12) \
|
UBTOUI((u)+DECPMAX-4)==0 \
|
||||||
+UINTAT((u)+DECPMAX-16))==0)
|
&& UBTOUI((u)+DECPMAX-8)==0 \
|
||||||
|
&& UBTOUI((u)+DECPMAX-12)==0 \
|
||||||
|
&& UBTOUI(u)==0)
|
||||||
#elif DECPMAX==34
|
#elif DECPMAX==34
|
||||||
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
|
#define ISCOEFFZERO(u) ( \
|
||||||
&& (UINTAT((u)+DECPMAX-8) +UINTAT((u)+DECPMAX-12) \
|
UBTOUI((u)+DECPMAX-4)==0 \
|
||||||
+UINTAT((u)+DECPMAX-16)+UINTAT((u)+DECPMAX-20) \
|
&& UBTOUI((u)+DECPMAX-8)==0 \
|
||||||
+UINTAT((u)+DECPMAX-24)+UINTAT((u)+DECPMAX-28) \
|
&& UBTOUI((u)+DECPMAX-12)==0 \
|
||||||
+UINTAT((u)+DECPMAX-32)+USHORTAT((u)+DECPMAX-34))==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
|
#endif
|
||||||
|
|
||||||
/* Macros and masks for the exponent continuation field and MSD */
|
/* Macros and masks for the exponent continuation field and MSD */
|
||||||
|
@ -448,20 +483,15 @@
|
||||||
#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
|
#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
|
||||||
|
|
||||||
/* Macros to decode the coefficient in a finite decFloat *df into */
|
/* 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 */
|
/* In-line sequence to convert least significant 10 bits of uInt */
|
||||||
/* to three BCD8 digits starting at uByte u. Note that an extra */
|
/* dpd to three BCD8 digits starting at uByte u. Note that an */
|
||||||
/* byte is written to the right of the three digits because this */
|
/* extra byte is written to the right of the three digits because */
|
||||||
/* moves four at a time for speed; the alternative macro moves */
|
/* four bytes are moved at a time for speed; the alternative */
|
||||||
/* exactly three bytes */
|
/* macro moves exactly three bytes (usually slower). */
|
||||||
#define dpd2bcd8(u, dpd) { \
|
#define dpd2bcd8(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 4)
|
||||||
UINTAT(u)=UINTAT(&DPD2BCD8[((dpd)&0x3ff)*4]);}
|
#define dpd2bcd83(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 3)
|
||||||
|
|
||||||
#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 */
|
/* Decode the declets. After extracting each one, it is decoded */
|
||||||
/* to BCD8 using a table lookup (also used for variable-length */
|
/* to BCD8 using a table lookup (also used for variable-length */
|
||||||
|
@ -597,8 +627,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Macros to decode the coefficient in a finite decFloat *df into */
|
/* Macros to decode the coefficient in a finite decFloat *df into */
|
||||||
/* a base-thousand uInt array, with the least-significant 0-999 */
|
/* a base-thousand uInt array (of size DECLETS+1, to allow for */
|
||||||
/* 'digit' at offset 0. */
|
/* the MSD), with the least-significant 0-999 'digit' at offset 0.*/
|
||||||
|
|
||||||
/* Decode the declets. After extracting each one, it is decoded */
|
/* Decode the declets. After extracting each one, it is decoded */
|
||||||
/* to binary using a table lookup. */
|
/* to binary using a table lookup. */
|
||||||
|
@ -640,9 +670,72 @@
|
||||||
(buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \
|
(buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \
|
||||||
(buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff]; \
|
(buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff]; \
|
||||||
(buf)[11]=DECCOMBMSD[sourhi>>26];}
|
(buf)[11]=DECCOMBMSD[sourhi>>26];}
|
||||||
|
|
||||||
#endif
|
#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) */
|
/* Set a decFloat to the maximum positive finite number (Nmax) */
|
||||||
#if DECPMAX==7
|
#if DECPMAX==7
|
||||||
#define DFSETNMAX(df) \
|
#define DFSETNMAX(df) \
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#define decFloatFromBCD decQuadFromBCD
|
#define decFloatFromBCD decQuadFromBCD
|
||||||
#define decFloatFromInt32 decQuadFromInt32
|
#define decFloatFromInt32 decQuadFromInt32
|
||||||
#define decFloatFromPacked decQuadFromPacked
|
#define decFloatFromPacked decQuadFromPacked
|
||||||
|
#define decFloatFromPackedChecked decQuadFromPackedChecked
|
||||||
#define decFloatFromString decQuadFromString
|
#define decFloatFromString decQuadFromString
|
||||||
#define decFloatFromUInt32 decQuadFromUInt32
|
#define decFloatFromUInt32 decQuadFromUInt32
|
||||||
#define decFloatFromWider decQuadFromWider
|
#define decFloatFromWider decQuadFromWider
|
||||||
|
@ -139,7 +140,6 @@
|
||||||
#define decFloatSameQuantum decQuadSameQuantum
|
#define decFloatSameQuantum decQuadSameQuantum
|
||||||
#define decFloatVersion decQuadVersion
|
#define decFloatVersion decQuadVersion
|
||||||
|
|
||||||
|
|
||||||
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
||||||
#include "decCommon.c" /* non-arithmetic decFloat routines */
|
#include "decCommon.c" /* non-arithmetic decFloat routines */
|
||||||
#include "decBasic.c" /* basic formats routines */
|
#include "decBasic.c" /* basic formats routines */
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decQuad.h -- Decimal 128-bit format module header */
|
/* 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, */
|
/* 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. */
|
||||||
|
|
||||||
|
@ -59,11 +57,14 @@
|
||||||
/* Required include */
|
/* Required include */
|
||||||
#include "decContext.h"
|
#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 {
|
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];
|
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;
|
} decQuad;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
@ -99,6 +100,7 @@
|
||||||
extern decQuad * decQuadFromBCD(decQuad *, int32_t, const uint8_t *, int32_t);
|
extern decQuad * decQuadFromBCD(decQuad *, int32_t, const uint8_t *, int32_t);
|
||||||
extern decQuad * decQuadFromInt32(decQuad *, int32_t);
|
extern decQuad * decQuadFromInt32(decQuad *, int32_t);
|
||||||
extern decQuad * decQuadFromPacked(decQuad *, int32_t, const uint8_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 * decQuadFromString(decQuad *, const char *, decContext *);
|
||||||
extern decQuad * decQuadFromUInt32(decQuad *, uint32_t);
|
extern decQuad * decQuadFromUInt32(decQuad *, uint32_t);
|
||||||
extern int32_t decQuadGetCoefficient(const decQuad *, uint8_t *);
|
extern int32_t decQuadGetCoefficient(const decQuad *, uint8_t *);
|
||||||
|
@ -182,7 +184,8 @@
|
||||||
|
|
||||||
/* decNumber conversions; these are implemented as macros so as not */
|
/* decNumber conversions; these are implemented as macros so as not */
|
||||||
/* to force a dependency on decimal128 and decNumber in decQuad. */
|
/* 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 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
|
#endif
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decSingle.c -- decSingle operations module */
|
/* 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 */
|
#include "decSingle.h" /* public includes */
|
||||||
|
@ -61,6 +59,7 @@
|
||||||
/* Utility (binary results, extractors, etc.) */
|
/* Utility (binary results, extractors, etc.) */
|
||||||
#define decFloatFromBCD decSingleFromBCD
|
#define decFloatFromBCD decSingleFromBCD
|
||||||
#define decFloatFromPacked decSingleFromPacked
|
#define decFloatFromPacked decSingleFromPacked
|
||||||
|
#define decFloatFromPackedChecked decSingleFromPackedChecked
|
||||||
#define decFloatFromString decSingleFromString
|
#define decFloatFromString decSingleFromString
|
||||||
#define decFloatFromWider decSingleFromWider
|
#define decFloatFromWider decSingleFromWider
|
||||||
#define decFloatGetCoefficient decSingleGetCoefficient
|
#define decFloatGetCoefficient decSingleGetCoefficient
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decSingle.h -- Decimal 32-bit format module header */
|
/* decSingle.h -- Decimal 32-bit format module header */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Please see decFloats.h for an overview and documentation details. */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#if !defined(DECSINGLE)
|
#if !defined(DECSINGLE)
|
||||||
#define DECSINGLE
|
#define DECSINGLE
|
||||||
|
@ -59,7 +57,7 @@
|
||||||
#include "decQuad.h"
|
#include "decQuad.h"
|
||||||
#include "decDouble.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 {
|
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];
|
uint16_t shorts[DECSINGLE_Bytes/2];
|
||||||
|
@ -75,6 +73,7 @@
|
||||||
/* Utilities (binary argument(s) or result, extractors, etc.) */
|
/* Utilities (binary argument(s) or result, extractors, etc.) */
|
||||||
extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t);
|
extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t);
|
||||||
extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_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 * decSingleFromString(decSingle *, const char *, decContext *);
|
||||||
extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *);
|
extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *);
|
||||||
extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *);
|
extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *);
|
||||||
|
@ -97,7 +96,8 @@
|
||||||
|
|
||||||
/* decNumber conversions; these are implemented as macros so as not */
|
/* decNumber conversions; these are implemented as macros so as not */
|
||||||
/* to force a dependency on decimal32 and decNumber in decSingle. */
|
/* 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 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
|
#endif
|
||||||
|
|
|
@ -89,8 +89,8 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
|
||||||
Int ae; /* adjusted exponent */
|
Int ae; /* adjusted exponent */
|
||||||
decNumber dw; /* work */
|
decNumber dw; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
uInt *pu; /* .. */
|
|
||||||
uInt comb, exp; /* .. */
|
uInt comb, exp; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uInt targar[4]={0,0,0,0}; /* target 128-bit */
|
uInt targar[4]={0,0,0,0}; /* target 128-bit */
|
||||||
#define targhi targar[3] /* name the word with the sign */
|
#define targhi targar[3] /* name the word with the sign */
|
||||||
#define targmh targar[2] /* name the words */
|
#define targmh targar[2] /* name the words */
|
||||||
|
@ -172,18 +172,19 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
|
||||||
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
|
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
|
||||||
|
|
||||||
/* now write to storage; this is endian */
|
/* now write to storage; this is endian */
|
||||||
pu=(uInt *)d128->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
pu[0]=targlo; /* directly store the low int */
|
/* lo -> hi */
|
||||||
pu[1]=targml; /* then the mid-low */
|
UBFROMUI(d128->bytes, targlo);
|
||||||
pu[2]=targmh; /* then the mid-high */
|
UBFROMUI(d128->bytes+4, targml);
|
||||||
pu[3]=targhi; /* then the high int */
|
UBFROMUI(d128->bytes+8, targmh);
|
||||||
|
UBFROMUI(d128->bytes+12, targhi);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pu[0]=targhi; /* directly store the high int */
|
/* hi -> lo */
|
||||||
pu[1]=targmh; /* then the mid-high */
|
UBFROMUI(d128->bytes, targhi);
|
||||||
pu[2]=targml; /* then the mid-low */
|
UBFROMUI(d128->bytes+4, targmh);
|
||||||
pu[3]=targlo; /* then the low int */
|
UBFROMUI(d128->bytes+8, targml);
|
||||||
|
UBFROMUI(d128->bytes+12, targlo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
||||||
|
@ -201,8 +202,8 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
|
||||||
uInt msd; /* coefficient MSD */
|
uInt msd; /* coefficient MSD */
|
||||||
uInt exp; /* exponent top two bits */
|
uInt exp; /* exponent top two bits */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
const uInt *pu; /* work */
|
Int need; /* work */
|
||||||
Int need; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
uInt sourar[4]; /* source 128-bit */
|
uInt sourar[4]; /* source 128-bit */
|
||||||
#define sourhi sourar[3] /* name the word with the sign */
|
#define sourhi sourar[3] /* name the word with the sign */
|
||||||
#define sourmh sourar[2] /* and the mid-high word */
|
#define sourmh sourar[2] /* and the mid-high word */
|
||||||
|
@ -210,18 +211,17 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
|
||||||
#define sourlo sourar[0] /* and the lowest word */
|
#define sourlo sourar[0] /* and the lowest word */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d128->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
sourlo=pu[0]; /* directly load the low int */
|
sourlo=UBTOUI(d128->bytes ); /* directly load the low int */
|
||||||
sourml=pu[1]; /* then the mid-low */
|
sourml=UBTOUI(d128->bytes+4 ); /* then the mid-low */
|
||||||
sourmh=pu[2]; /* then the mid-high */
|
sourmh=UBTOUI(d128->bytes+8 ); /* then the mid-high */
|
||||||
sourhi=pu[3]; /* then the high int */
|
sourhi=UBTOUI(d128->bytes+12); /* then the high int */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sourhi=pu[0]; /* directly load the high int */
|
sourhi=UBTOUI(d128->bytes ); /* directly load the high int */
|
||||||
sourmh=pu[1]; /* then the mid-high */
|
sourmh=UBTOUI(d128->bytes+4 ); /* then the mid-high */
|
||||||
sourml=pu[2]; /* then the mid-low */
|
sourml=UBTOUI(d128->bytes+8 ); /* then the mid-low */
|
||||||
sourlo=pu[3]; /* then the low int */
|
sourlo=UBTOUI(d128->bytes+12); /* then the low int */
|
||||||
}
|
}
|
||||||
|
|
||||||
comb=(sourhi>>26)&0x1f; /* combination field */
|
comb=(sourhi>>26)&0x1f; /* combination field */
|
||||||
|
@ -291,11 +291,11 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
char *cstart; /* coefficient start */
|
char *cstart; /* coefficient start */
|
||||||
char *c; /* output pointer in string */
|
char *c; /* output pointer in string */
|
||||||
const uInt *pu; /* work */
|
const uByte *u; /* work */
|
||||||
char *s, *t; /* .. (source, target) */
|
char *s, *t; /* .. (source, target) */
|
||||||
Int dpd; /* .. */
|
Int dpd; /* .. */
|
||||||
Int pre, e; /* .. */
|
Int pre, e; /* .. */
|
||||||
const uByte *u; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
|
|
||||||
uInt sourar[4]; /* source 128-bit */
|
uInt sourar[4]; /* source 128-bit */
|
||||||
#define sourhi sourar[3] /* name the word with the sign */
|
#define sourhi sourar[3] /* name the word with the sign */
|
||||||
|
@ -304,18 +304,17 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
#define sourlo sourar[0] /* and the lowest word */
|
#define sourlo sourar[0] /* and the lowest word */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d128->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
sourlo=pu[0]; /* directly load the low int */
|
sourlo=UBTOUI(d128->bytes ); /* directly load the low int */
|
||||||
sourml=pu[1]; /* then the mid-low */
|
sourml=UBTOUI(d128->bytes+4 ); /* then the mid-low */
|
||||||
sourmh=pu[2]; /* then the mid-high */
|
sourmh=UBTOUI(d128->bytes+8 ); /* then the mid-high */
|
||||||
sourhi=pu[3]; /* then the high int */
|
sourhi=UBTOUI(d128->bytes+12); /* then the high int */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sourhi=pu[0]; /* directly load the high int */
|
sourhi=UBTOUI(d128->bytes ); /* directly load the high int */
|
||||||
sourmh=pu[1]; /* then the mid-high */
|
sourmh=UBTOUI(d128->bytes+4 ); /* then the mid-high */
|
||||||
sourml=pu[2]; /* then the mid-low */
|
sourml=UBTOUI(d128->bytes+8 ); /* then the mid-low */
|
||||||
sourlo=pu[3]; /* then the low int */
|
sourlo=UBTOUI(d128->bytes+12); /* then the low int */
|
||||||
}
|
}
|
||||||
|
|
||||||
c=string; /* where result will go */
|
c=string; /* where result will go */
|
||||||
|
@ -483,7 +482,7 @@ decimal128 * decimal128FromString(decimal128 *result, const char *string,
|
||||||
/* returns 1 if the encoding of d128 is canonical, 0 otherwise */
|
/* returns 1 if the encoding of d128 is canonical, 0 otherwise */
|
||||||
/* No error is possible. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
uint32_t decimal128IsCanonical(const decimal128 *d128) {
|
uInt decimal128IsCanonical(const decimal128 *d128) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal128 canon; /* .. */
|
decimal128 canon; /* .. */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
|
@ -532,9 +531,9 @@ decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
|
||||||
/* This assumes range has been checked and exponent previously 0; */
|
/* This assumes range has been checked and exponent previously 0; */
|
||||||
/* type of exponent must be unsigned */
|
/* type of exponent must be unsigned */
|
||||||
#define decimal128SetExpCon(d, e) { \
|
#define decimal128SetExpCon(d, e) { \
|
||||||
(d)->bytes[0]|=(uint8_t)((e)>>10); \
|
(d)->bytes[0]|=(uByte)((e)>>10); \
|
||||||
(d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2); \
|
(d)->bytes[1] =(uByte)(((e)&0x3fc)>>2); \
|
||||||
(d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);}
|
(d)->bytes[2]|=(uByte)(((e)&0x03)<<6);}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */
|
/* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */
|
||||||
|
|
|
@ -76,13 +76,13 @@
|
||||||
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
|
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "decimal128Local.h"
|
#include "decimal128Local.h"
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* Routines */
|
/* Routines */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "decimal128Symbols.h"
|
#include "decimal128Symbols.h"
|
||||||
|
|
||||||
/* String conversions */
|
/* String conversions */
|
||||||
decimal128 * decimal128FromString(decimal128 *, const char *, decContext *);
|
decimal128 * decimal128FromString(decimal128 *, const char *, decContext *);
|
||||||
|
|
|
@ -89,8 +89,8 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
|
||||||
Int ae; /* adjusted exponent */
|
Int ae; /* adjusted exponent */
|
||||||
decNumber dw; /* work */
|
decNumber dw; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
uInt *pu; /* .. */
|
|
||||||
uInt comb, exp; /* .. */
|
uInt comb, exp; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uInt targ=0; /* target 32-bit */
|
uInt targ=0; /* target 32-bit */
|
||||||
|
|
||||||
/* If the number has too many digits, or the exponent could be */
|
/* If the number has too many digits, or the exponent could be */
|
||||||
|
@ -175,8 +175,7 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
|
||||||
if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
|
if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
|
||||||
|
|
||||||
/* now write to storage; this is endian */
|
/* now write to storage; this is endian */
|
||||||
pu=(uInt *)d32->bytes; /* overlay */
|
UBFROMUI(d32->bytes, targ); /* directly store the int */
|
||||||
*pu=targ; /* directly store the int */
|
|
||||||
|
|
||||||
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
||||||
/* decimal32Show(d32); */
|
/* decimal32Show(d32); */
|
||||||
|
@ -194,11 +193,10 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
|
||||||
uInt exp; /* exponent top two bits */
|
uInt exp; /* exponent top two bits */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
uInt sour; /* source 32-bit */
|
uInt sour; /* source 32-bit */
|
||||||
const uInt *pu; /* work */
|
uInt uiwork; /* for macros */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d32->bytes; /* overlay */
|
sour=UBTOUI(d32->bytes); /* directly load the int */
|
||||||
sour=*pu; /* directly load the int */
|
|
||||||
|
|
||||||
comb=(sour>>26)&0x1f; /* combination field */
|
comb=(sour>>26)&0x1f; /* combination field */
|
||||||
|
|
||||||
|
@ -264,16 +262,15 @@ char * decimal32ToString(const decimal32 *d32, char *string){
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
char *cstart; /* coefficient start */
|
char *cstart; /* coefficient start */
|
||||||
char *c; /* output pointer in string */
|
char *c; /* output pointer in string */
|
||||||
const uInt *pu; /* work */
|
const uByte *u; /* work */
|
||||||
const uByte *u; /* .. */
|
|
||||||
char *s, *t; /* .. (source, target) */
|
char *s, *t; /* .. (source, target) */
|
||||||
Int dpd; /* .. */
|
Int dpd; /* .. */
|
||||||
Int pre, e; /* .. */
|
Int pre, e; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uInt sour; /* source 32-bit */
|
uInt sour; /* source 32-bit */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d32->bytes; /* overlay */
|
sour=UBTOUI(d32->bytes); /* directly load the int */
|
||||||
sour=*pu; /* directly load the int */
|
|
||||||
|
|
||||||
c=string; /* where result will go */
|
c=string; /* where result will go */
|
||||||
if (((Int)sour)<0) *c++='-'; /* handle sign */
|
if (((Int)sour)<0) *c++='-'; /* handle sign */
|
||||||
|
@ -412,7 +409,7 @@ decimal32 * decimal32FromString(decimal32 *result, const char *string,
|
||||||
/* 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. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
uint32_t decimal32IsCanonical(const decimal32 *d32) {
|
uInt decimal32IsCanonical(const decimal32 *d32) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal32 canon; /* .. */
|
decimal32 canon; /* .. */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
|
@ -460,8 +457,8 @@ decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
|
||||||
/* This assumes range has been checked and exponent previously 0; */
|
/* This assumes range has been checked and exponent previously 0; */
|
||||||
/* type of exponent must be unsigned */
|
/* type of exponent must be unsigned */
|
||||||
#define decimal32SetExpCon(d, e) { \
|
#define decimal32SetExpCon(d, e) { \
|
||||||
(d)->bytes[0]|=(uint8_t)((e)>>4); \
|
(d)->bytes[0]|=(uByte)((e)>>4); \
|
||||||
(d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);}
|
(d)->bytes[1]|=(uByte)(((e)&0x0F)<<4);}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */
|
/* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
/* Routines */
|
/* Routines */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "decimal32Symbols.h"
|
#include "decimal32Symbols.h"
|
||||||
|
|
||||||
/* String conversions */
|
/* String conversions */
|
||||||
decimal32 * decimal32FromString(decimal32 *, const char *, decContext *);
|
decimal32 * decimal32FromString(decimal32 *, const char *, decContext *);
|
||||||
|
|
|
@ -95,8 +95,8 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
|
||||||
Int ae; /* adjusted exponent */
|
Int ae; /* adjusted exponent */
|
||||||
decNumber dw; /* work */
|
decNumber dw; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
uInt *pu; /* .. */
|
|
||||||
uInt comb, exp; /* .. */
|
uInt comb, exp; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uInt targar[2]={0, 0}; /* target 64-bit */
|
uInt targar[2]={0, 0}; /* target 64-bit */
|
||||||
#define targhi targar[1] /* name the word with the sign */
|
#define targhi targar[1] /* name the word with the sign */
|
||||||
#define targlo targar[0] /* and the other */
|
#define targlo targar[0] /* and the other */
|
||||||
|
@ -193,14 +193,15 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
|
||||||
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
|
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
|
||||||
|
|
||||||
/* now write to storage; this is now always endian */
|
/* now write to storage; this is now always endian */
|
||||||
pu=(uInt *)d64->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
pu[0]=targar[0]; /* directly store the low int */
|
/* lo int then hi */
|
||||||
pu[1]=targar[1]; /* then the high int */
|
UBFROMUI(d64->bytes, targar[0]);
|
||||||
|
UBFROMUI(d64->bytes+4, targar[1]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pu[0]=targar[1]; /* directly store the high int */
|
/* hi int then lo */
|
||||||
pu[1]=targar[0]; /* then the low int */
|
UBFROMUI(d64->bytes, targar[1]);
|
||||||
|
UBFROMUI(d64->bytes+4, targar[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
||||||
|
@ -218,21 +219,20 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
|
||||||
uInt msd; /* coefficient MSD */
|
uInt msd; /* coefficient MSD */
|
||||||
uInt exp; /* exponent top two bits */
|
uInt exp; /* exponent top two bits */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
const uInt *pu; /* work */
|
Int need; /* work */
|
||||||
Int need; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
uInt sourar[2]; /* source 64-bit */
|
uInt sourar[2]; /* source 64-bit */
|
||||||
#define sourhi sourar[1] /* name the word with the sign */
|
#define sourhi sourar[1] /* name the word with the sign */
|
||||||
#define sourlo sourar[0] /* and the lower word */
|
#define sourlo sourar[0] /* and the lower word */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d64->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
sourlo=pu[0]; /* directly load the low int */
|
sourlo=UBTOUI(d64->bytes ); /* directly load the low int */
|
||||||
sourhi=pu[1]; /* then the high int */
|
sourhi=UBTOUI(d64->bytes+4); /* then the high int */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sourhi=pu[0]; /* directly load the high int */
|
sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
|
||||||
sourlo=pu[1]; /* then the low int */
|
sourlo=UBTOUI(d64->bytes+4); /* then the low int */
|
||||||
}
|
}
|
||||||
|
|
||||||
comb=(sourhi>>26)&0x1f; /* combination field */
|
comb=(sourhi>>26)&0x1f; /* combination field */
|
||||||
|
@ -307,25 +307,24 @@ char * decimal64ToString(const decimal64 *d64, char *string){
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
char *cstart; /* coefficient start */
|
char *cstart; /* coefficient start */
|
||||||
char *c; /* output pointer in string */
|
char *c; /* output pointer in string */
|
||||||
const uInt *pu; /* work */
|
const uByte *u; /* work */
|
||||||
char *s, *t; /* .. (source, target) */
|
char *s, *t; /* .. (source, target) */
|
||||||
Int dpd; /* .. */
|
Int dpd; /* .. */
|
||||||
Int pre, e; /* .. */
|
Int pre, e; /* .. */
|
||||||
const uByte *u; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
|
|
||||||
uInt sourar[2]; /* source 64-bit */
|
uInt sourar[2]; /* source 64-bit */
|
||||||
#define sourhi sourar[1] /* name the word with the sign */
|
#define sourhi sourar[1] /* name the word with the sign */
|
||||||
#define sourlo sourar[0] /* and the lower word */
|
#define sourlo sourar[0] /* and the lower word */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d64->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
sourlo=pu[0]; /* directly load the low int */
|
sourlo=UBTOUI(d64->bytes ); /* directly load the low int */
|
||||||
sourhi=pu[1]; /* then the high int */
|
sourhi=UBTOUI(d64->bytes+4); /* then the high int */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sourhi=pu[0]; /* directly load the high int */
|
sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
|
||||||
sourlo=pu[1]; /* then the low int */
|
sourlo=UBTOUI(d64->bytes+4); /* then the low int */
|
||||||
}
|
}
|
||||||
|
|
||||||
c=string; /* where result will go */
|
c=string; /* where result will go */
|
||||||
|
@ -472,7 +471,7 @@ decimal64 * decimal64FromString(decimal64 *result, const char *string,
|
||||||
/* 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. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
uint32_t decimal64IsCanonical(const decimal64 *d64) {
|
uInt decimal64IsCanonical(const decimal64 *d64) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal64 canon; /* .. */
|
decimal64 canon; /* .. */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
|
@ -520,8 +519,8 @@ decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
|
||||||
/* This assumes range has been checked and exponent previously 0; */
|
/* This assumes range has been checked and exponent previously 0; */
|
||||||
/* type of exponent must be unsigned */
|
/* type of exponent must be unsigned */
|
||||||
#define decimal64SetExpCon(d, e) { \
|
#define decimal64SetExpCon(d, e) { \
|
||||||
(d)->bytes[0]|=(uint8_t)((e)>>6); \
|
(d)->bytes[0]|=(uByte)((e)>>6); \
|
||||||
(d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);}
|
(d)->bytes[1]|=(uByte)(((e)&0x3F)<<2);}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
|
/* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
/* Routines */
|
/* Routines */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "decimal64Symbols.h"
|
#include "decimal64Symbols.h"
|
||||||
|
|
||||||
/* String conversions */
|
/* String conversions */
|
||||||
decimal64 * decimal64FromString(decimal64 *, const char *, decContext *);
|
decimal64 * decimal64FromString(decimal64 *, const char *, decContext *);
|
||||||
|
|
Loading…
Reference in a new issue