aboutsummaryrefslogtreecommitdiff
path: root/libdecnumber/decCommon.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdecnumber/decCommon.c')
-rw-r--r--libdecnumber/decCommon.c431
1 files changed, 254 insertions, 177 deletions
diff --git a/libdecnumber/decCommon.c b/libdecnumber/decCommon.c
index fa16e79..845b914 100644
--- a/libdecnumber/decCommon.c
+++ b/libdecnumber/decCommon.c
@@ -104,15 +104,15 @@ static decFloat * decFinalize(decFloat *, bcdnum *, decContext *);
static Flag decBiStr(const char *, const char *, const char *);
/* Macros and private tables; those which are not format-dependent */
-/* are only included if decQuad is being built. */
+/* are only included if decQuad is being built. */
/* ------------------------------------------------------------------ */
/* Combination field lookup tables (uInts to save measurable work) */
/* */
-/* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */
+/* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */
/* 10), shifted left for format, or DECFLOAT_Inf/NaN */
/* DECCOMBWEXP - The same, for the next-wider format (unless QUAD) */
-/* DECCOMBMSD - 4-bit most-significant-digit */
+/* DECCOMBMSD - 4-bit most-significant-digit */
/* [0 if the index is a special (Infinity or NaN)] */
/* DECCOMBFROM - 5-bit combination field from EXP top bits and MSD */
/* (placed in uInt so no shift is needed) */
@@ -123,7 +123,7 @@ static Flag decBiStr(const char *, const char *, const char *);
/* DECCOMBFROM is indexed by expTopTwoBits*16 + msd */
/* */
/* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are */
-/* only included once, when QUAD is being built */
+/* only included once, when QUAD is being built */
/* ------------------------------------------------------------------ */
static const uInt DECCOMBEXP[64]={
0, 0, 0, 0, 0, 0, 0, 0,
@@ -161,7 +161,7 @@ static const uInt DECCOMBWEXP[64]={
#if QUAD
const uInt DECCOMBMSD[64]={
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0};
@@ -223,7 +223,7 @@ static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
/* returns df */
/* */
/* The num descriptor may point to a bcd8 string of any length; this */
-/* string may have leading insignificant zeros. If it has more than */
+/* string may have leading insignificant zeros. If it has more than */
/* DECPMAX digits then the final digit can be a round-for-reround */
/* digit (i.e., it may include a sticky bit residue). */
/* */
@@ -248,8 +248,9 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
decContext *set) {
uByte *ub; /* work */
uInt dpd; /* .. */
- uByte *umsd=num->msd; /* local copy */
- uByte *ulsd=num->lsd; /* .. */
+ uInt uiwork; /* for macros */
+ uByte *umsd=num->msd; /* local copy */
+ uByte *ulsd=num->lsd; /* .. */
uInt encode; /* encoding accumulator */
Int length; /* coefficient length */
@@ -275,11 +276,11 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
length=(uInt)(ulsd-umsd+1); /* coefficient length */
if (!NUMISSPECIAL(num)) {
- Int drop; /* digits to be dropped */
+ Int drop; /* digits to be dropped */
/* skip leading insignificant zeros to calculate an exact length */
/* [this is quite expensive] */
if (*umsd==0) {
- for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4;
+ for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4;
for (; *umsd==0 && umsd<ulsd;) umsd++;
length=ulsd-umsd+1; /* recalculate */
}
@@ -305,12 +306,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
roundat=umsd+length-drop;
reround=*roundat;
for (ub=roundat+1; ub<=ulsd; ub++) {
- if (*ub!=0) { /* non-zero to be discarded */
+ if (*ub!=0) { /* non-zero to be discarded */
reround=DECSTICKYTAB[reround]; /* apply sticky bit */
break; /* [remainder don't-care] */
}
} /* check stickies */
- ulsd=roundat-1; /* new LSD */
+ ulsd=roundat-1; /* new LSD */
}
else { /* edge case */
if (drop==length) {
@@ -322,7 +323,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
reround=0;
}
for (ub=roundat+1; ub<=ulsd; ub++) {
- if (*ub!=0) { /* non-zero to be discarded */
+ if (*ub!=0) { /* non-zero to be discarded */
reround=DECSTICKYTAB[reround]; /* apply sticky bit */
break; /* [remainder don't-care] */
}
@@ -331,7 +332,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
ulsd=umsd; /* .. */
}
- if (reround!=0) { /* discarding non-zero */
+ if (reround!=0) { /* discarding non-zero */
uInt bump=0;
set->status|=DEC_Inexact;
/* if adjusted exponent [exp+digits-1] is < EMIN then num is */
@@ -342,7 +343,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* next decide whether increment of the coefficient is needed */
if (set->round==DEC_ROUND_HALF_EVEN) { /* fastpath slowest case */
if (reround>5) bump=1; /* >0.5 goes up */
- else if (reround==5) /* exactly 0.5000 .. */
+ else if (reround==5) /* exactly 0.5000 .. */
bump=*ulsd & 0x01; /* .. up iff [new] lsd is odd */
} /* r-h-e */
else switch (set->round) {
@@ -382,13 +383,15 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
#endif
break;}
} /* switch (not r-h-e) */
- /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */
+ /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */
if (bump!=0) { /* need increment */
/* increment the coefficient; this might end up with 1000... */
/* (after the all nines case) */
ub=ulsd;
- for(; ub-3>=umsd && UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0;
+ for(; ub-3>=umsd && UBTOUI(ub-3)==0x09090909; ub-=4) {
+ UBFROMUI(ub-3, 0); /* to 00000000 */
+ }
/* [note ub could now be to left of msd, and it is not safe */
/* to write to the the left of the msd] */
/* now at most 3 digits left to non-9 (usually just the one) */
@@ -436,7 +439,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */
/* Overflow -- these could go straight to encoding, here, but */
/* instead num is adjusted to keep the code cleaner */
- Flag needmax=0; /* 1 for finite result */
+ Flag needmax=0; /* 1 for finite result */
set->status|=(DEC_Overflow | DEC_Inexact);
switch (set->round) {
case DEC_ROUND_DOWN: {
@@ -453,12 +456,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
break;} /* r-f */
default: break; /* Infinity in all other cases */
}
- if (!needmax) { /* easy .. set Infinity */
+ if (!needmax) { /* easy .. set Infinity */
num->exponent=DECFLOAT_Inf;
*umsd=0; /* be clean: coefficient to 0 */
ulsd=umsd; /* .. */
}
- else { /* return Nmax */
+ else { /* return Nmax */
umsd=allnines; /* use constant array */
ulsd=allnines+DECPMAX-1;
num->exponent=DECEMAX-(DECPMAX-1);
@@ -475,8 +478,8 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
uByte *t=buffer; /* safe target */
uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
/* printf("folddown shift=%ld\n", (LI)shift); */
- for (; s<=ulsd; s+=4, t+=4) UINTAT(t)=UINTAT(s);
- for (t=tlsd-shift+1; t<=tlsd; t+=4) UINTAT(t)=0; /* pad */
+ for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s));
+ for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0); /* pad 0s */
num->exponent-=shift;
umsd=buffer;
ulsd=tlsd;
@@ -492,23 +495,23 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/*------------------------------------------------------------------*/
/* Following code does not alter coefficient (could be allnines array) */
+ /* fast path possible when DECPMAX digits */
if (length==DECPMAX) {
return decFloatFromBCD(df, num->exponent, umsd, num->sign);
- }
+ } /* full-length */
- /* Here when length is short */
+ /* slower path when not a full-length number; must care about length */
+ /* [coefficient length here will be < DECPMAX] */
if (!NUMISSPECIAL(num)) { /* is still finite */
/* encode the combination field and exponent continuation */
uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */
uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */
- /* [msd=0] */
+ /* [msd==0] */
/* look up the combination field and make high word */
encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */
encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
}
else encode=num->exponent; /* special [already in word] */
- /* [coefficient length here will be < DECPMAX] */
-
encode|=num->sign; /* add sign */
/* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
@@ -519,7 +522,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* working pointer, uInt *ub. */
/* As not full-length then chances are there are many leading zeros */
/* [and there may be a partial triad] */
- #define getDPD(dpd, n) ub=ulsd-(3*(n))-2; \
+ #define getDPDt(dpd, n) ub=ulsd-(3*(n))-2; \
if (ub<umsd-2) dpd=0; \
else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; \
else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];}
@@ -528,48 +531,48 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* according to endianness; in all cases complete the sign word */
/* first */
#if DECPMAX==7
- getDPD(dpd, 1);
+ getDPDt(dpd, 1);
encode|=dpd<<10;
- getDPD(dpd, 0);
+ getDPDt(dpd, 0);
encode|=dpd;
DFWORD(df, 0)=encode; /* just the one word */
#elif DECPMAX==16
- getDPD(dpd, 4); encode|=dpd<<8;
- getDPD(dpd, 3); encode|=dpd>>2;
+ getDPDt(dpd, 4); encode|=dpd<<8;
+ getDPDt(dpd, 3); encode|=dpd>>2;
DFWORD(df, 0)=encode;
encode=dpd<<30;
- getDPD(dpd, 2); encode|=dpd<<20;
- getDPD(dpd, 1); encode|=dpd<<10;
- getDPD(dpd, 0); encode|=dpd;
+ getDPDt(dpd, 2); encode|=dpd<<20;
+ getDPDt(dpd, 1); encode|=dpd<<10;
+ getDPDt(dpd, 0); encode|=dpd;
DFWORD(df, 1)=encode;
#elif DECPMAX==34
- getDPD(dpd,10); encode|=dpd<<4;
- getDPD(dpd, 9); encode|=dpd>>6;
+ getDPDt(dpd,10); encode|=dpd<<4;
+ getDPDt(dpd, 9); encode|=dpd>>6;
DFWORD(df, 0)=encode;
encode=dpd<<26;
- getDPD(dpd, 8); encode|=dpd<<16;
- getDPD(dpd, 7); encode|=dpd<<6;
- getDPD(dpd, 6); encode|=dpd>>4;
+ getDPDt(dpd, 8); encode|=dpd<<16;
+ getDPDt(dpd, 7); encode|=dpd<<6;
+ getDPDt(dpd, 6); encode|=dpd>>4;
DFWORD(df, 1)=encode;
encode=dpd<<28;
- getDPD(dpd, 5); encode|=dpd<<18;
- getDPD(dpd, 4); encode|=dpd<<8;
- getDPD(dpd, 3); encode|=dpd>>2;
+ getDPDt(dpd, 5); encode|=dpd<<18;
+ getDPDt(dpd, 4); encode|=dpd<<8;
+ getDPDt(dpd, 3); encode|=dpd>>2;
DFWORD(df, 2)=encode;
encode=dpd<<30;
- getDPD(dpd, 2); encode|=dpd<<20;
- getDPD(dpd, 1); encode|=dpd<<10;
- getDPD(dpd, 0); encode|=dpd;
+ getDPDt(dpd, 2); encode|=dpd<<20;
+ getDPDt(dpd, 1); encode|=dpd<<10;
+ getDPDt(dpd, 0); encode|=dpd;
DFWORD(df, 3)=encode;
#endif
/* printf("Status: %08lx\n", (LI)set->status); */
- /* decFloatShow(df, "final"); */
+ /* decFloatShow(df, "final2"); */
return df;
} /* decFinalize */
@@ -579,12 +582,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
/* df is the target decFloat */
/* exp is the in-range unbiased exponent, q, or a special value in */
/* the form returned by decFloatGetExponent */
-/* bcdar holds DECPMAX digits to set the coefficient from, one */
+/* bcdar holds DECPMAX digits to set the coefficient from, one */
/* digit in each byte (BCD8 encoding); the first (MSD) is ignored */
/* if df is a NaN; all are ignored if df is infinite. */
-/* All bytes must be in 0-9; results undefined otherwise. */
+/* All bytes must be in 0-9; results are undefined otherwise. */
/* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */
-/* returns df, which will be canonical */
+/* returns df, which will be canonical */
/* */
/* No error is possible, and no status will be set. */
/* ------------------------------------------------------------------ */
@@ -609,53 +612,53 @@ decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
/* and put the corresponding DPD code into dpd. */
/* Use of a working pointer, uInt *ub, is assumed. */
- #define getDPDf(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \
+ #define getDPDb(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \
dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];
/* place the declets in the encoding words and copy to result (df), */
/* according to endianness; in all cases complete the sign word */
/* first */
#if DECPMAX==7
- getDPDf(dpd, 1);
+ getDPDb(dpd, 1);
encode|=dpd<<10;
- getDPDf(dpd, 0);
+ getDPDb(dpd, 0);
encode|=dpd;
DFWORD(df, 0)=encode; /* just the one word */
#elif DECPMAX==16
- getDPDf(dpd, 4); encode|=dpd<<8;
- getDPDf(dpd, 3); encode|=dpd>>2;
+ getDPDb(dpd, 4); encode|=dpd<<8;
+ getDPDb(dpd, 3); encode|=dpd>>2;
DFWORD(df, 0)=encode;
encode=dpd<<30;
- getDPDf(dpd, 2); encode|=dpd<<20;
- getDPDf(dpd, 1); encode|=dpd<<10;
- getDPDf(dpd, 0); encode|=dpd;
+ getDPDb(dpd, 2); encode|=dpd<<20;
+ getDPDb(dpd, 1); encode|=dpd<<10;
+ getDPDb(dpd, 0); encode|=dpd;
DFWORD(df, 1)=encode;
#elif DECPMAX==34
- getDPDf(dpd,10); encode|=dpd<<4;
- getDPDf(dpd, 9); encode|=dpd>>6;
+ getDPDb(dpd,10); encode|=dpd<<4;
+ getDPDb(dpd, 9); encode|=dpd>>6;
DFWORD(df, 0)=encode;
encode=dpd<<26;
- getDPDf(dpd, 8); encode|=dpd<<16;
- getDPDf(dpd, 7); encode|=dpd<<6;
- getDPDf(dpd, 6); encode|=dpd>>4;
+ getDPDb(dpd, 8); encode|=dpd<<16;
+ getDPDb(dpd, 7); encode|=dpd<<6;
+ getDPDb(dpd, 6); encode|=dpd>>4;
DFWORD(df, 1)=encode;
encode=dpd<<28;
- getDPDf(dpd, 5); encode|=dpd<<18;
- getDPDf(dpd, 4); encode|=dpd<<8;
- getDPDf(dpd, 3); encode|=dpd>>2;
+ getDPDb(dpd, 5); encode|=dpd<<18;
+ getDPDb(dpd, 4); encode|=dpd<<8;
+ getDPDb(dpd, 3); encode|=dpd>>2;
DFWORD(df, 2)=encode;
encode=dpd<<30;
- getDPDf(dpd, 2); encode|=dpd<<20;
- getDPDf(dpd, 1); encode|=dpd<<10;
- getDPDf(dpd, 0); encode|=dpd;
+ getDPDb(dpd, 2); encode|=dpd<<20;
+ getDPDb(dpd, 1); encode|=dpd<<10;
+ getDPDb(dpd, 0); encode|=dpd;
DFWORD(df, 3)=encode;
#endif
- /* decFloatShow(df, "final"); */
+ /* decFloatShow(df, "fromB"); */
return df;
} /* decFloatFromBCD */
@@ -671,7 +674,7 @@ decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
/* and QUAD the first (pad) nibble is also ignored in all cases. */
/* All coefficient nibbles must be in 0-9 and sign in A-F; results */
/* are undefined otherwise. */
-/* returns df, which will be canonical */
+/* returns df, which will be canonical */
/* */
/* No error is possible, and no status will be set. */
/* ------------------------------------------------------------------ */
@@ -691,7 +694,7 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
*op++=*ip>>4;
*op++=(uByte)(*ip&0x0f); /* [final nibble is sign] */
}
- op--; /* -> sign byte */
+ op--; /* -> sign byte */
if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
if (EXPISSPECIAL(exp)) { /* Infinity or NaN */
@@ -702,7 +705,71 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
} /* decFloatFromPacked */
/* ------------------------------------------------------------------ */
-/* decFloatFromString -- conversion from numeric string */
+/* decFloatFromPackedChecked -- set from exponent and packed; checked */
+/* */
+/* df is the target decFloat */
+/* exp is the in-range unbiased exponent, q, or a special value in */
+/* the form returned by decFloatGetExponent */
+/* packed holds DECPMAX packed decimal digits plus a sign nibble */
+/* (all 6 codes are OK); the first (MSD) must be 0 if df is a NaN */
+/* and all digits must be 0 if df is infinite. For DOUBLE and */
+/* QUAD the first (pad) nibble must be 0. */
+/* All coefficient nibbles must be in 0-9 and sign in A-F. */
+/* returns df, which will be canonical or NULL if any of the */
+/* requirements are not met (if this case df is unchanged); that */
+/* is, the input data must be as returned by decFloatToPacked, */
+/* except that all six sign codes are acccepted. */
+/* */
+/* No status will be set. */
+/* ------------------------------------------------------------------ */
+decFloat * decFloatFromPackedChecked(decFloat *df, Int exp,
+ const uByte *packed) {
+ uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */
+ const uByte *ip; /* .. */
+ uByte *op; /* .. */
+ Int sig=0; /* sign */
+
+ /* expand coefficient and sign to BCDAR */
+ #if SINGLE
+ op=bcdar+1; /* no pad digit */
+ #else
+ op=bcdar; /* first (pad) digit here */
+ #endif
+ for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) {
+ *op=*ip>>4;
+ if (*op>9) return NULL;
+ op++;
+ *op=(uByte)(*ip&0x0f); /* [final nibble is sign] */
+ if (*op>9 && ip<packed+((DECPMAX+2)/2)-1) return NULL;
+ op++;
+ }
+ op--; /* -> sign byte */
+ if (*op<=9) return NULL; /* bad sign */
+ if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
+
+ #if !SINGLE
+ if (bcdar[0]!=0) return NULL; /* bad pad nibble */
+ #endif
+
+ if (EXPISNAN(exp)) { /* a NaN */
+ if (bcdar[1]!=0) return NULL; /* bad msd */
+ } /* NaN */
+ else if (EXPISINF(exp)) { /* is infinite */
+ Int i;
+ for (i=0; i<DECPMAX; i++) {
+ if (bcdar[i+1]!=0) return NULL; /* should be all zeros */
+ }
+ } /* infinity */
+ else { /* finite */
+ /* check the exponent is in range */
+ if (exp>DECEMAX-DECPMAX+1) return NULL;
+ if (exp<DECEMIN-DECPMAX+1) return NULL;
+ }
+ return decFloatFromBCD(df, exp, bcdar+1, sig);
+ } /* decFloatFromPacked */
+
+/* ------------------------------------------------------------------ */
+/* decFloatFromString -- conversion from numeric string */
/* */
/* result is the decFloat format number which gets the result of */
/* the conversion */
@@ -710,12 +777,12 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
/* number (which may be a special value), \0-terminated */
/* If there are too many significant digits in the */
/* coefficient it will be rounded. */
-/* set is the context */
+/* set is the context */
/* returns result */
/* */
/* The length of the coefficient and the size of the exponent are */
/* checked by this routine, so the correct error (Underflow or */
-/* Overflow) can be reported or rounding applied, as necessary. */
+/* Overflow) can be reported or rounding applied, as necessary. */
/* */
/* There is no limit to the coefficient length for finite inputs; */
/* NaN payloads must be integers with no more than DECPMAX-1 digits. */
@@ -726,20 +793,21 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
decFloat * decFloatFromString(decFloat *result, const char *string,
decContext *set) {
Int digits; /* count of digits in coefficient */
- const char *dotchar=NULL; /* where dot was found [NULL if none] */
- const char *cfirst=string; /* -> first character of decimal part */
- const char *c; /* work */
+ const char *dotchar=NULL; /* where dot was found [NULL if none] */
+ const char *cfirst=string; /* -> first character of decimal part */
+ const char *c; /* work */
uByte *ub; /* .. */
+ uInt uiwork; /* for macros */
bcdnum num; /* collects data for finishing */
uInt error=DEC_Conversion_syntax; /* assume the worst */
- uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */
+ uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */
/* some common rounding, +3, & pad */
#if DECTRACE
/* printf("FromString %s ...\n", string); */
#endif
for(;;) { /* once-only 'loop' */
- num.sign=0; /* assume non-negative */
+ num.sign=0; /* assume non-negative */
num.msd=buffer; /* MSD is here always */
/* detect and validate the coefficient, including any leading, */
@@ -810,7 +878,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
exp-=(Int)(clast-dotchar); /* adjust exponent */
/* [the '.' can now be ignored] */
}
- num.exponent=exp; /* exponent is good; store it */
+ num.exponent=exp; /* exponent is good; store it */
/* Here when whole string has been inspected and syntax is good */
/* cfirst->first digit or dot, clast->last digit or dot */
@@ -832,8 +900,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
/* as usual, go by fours when safe; NB it has been asserted */
/* that a '.' does not have the same mask as a digit */
if (c<=clast-3 /* safe for four */
- && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* test four */
- UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */
+ && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* test four */
+ UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */
ub+=4;
c+=4;
continue;
@@ -846,7 +914,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
}
} /* had dot */
/* Now no dot; do this by fours (where safe) */
- for (; c<=clast-3; c+=4, ub+=4) UINTAT(ub)=UINTAT(c)&0x0f0f0f0f;
+ for (; c<=clast-3; c+=4, ub+=4) UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);
for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0');
num.lsd=buffer+digits-1; /* record new LSD */
} /* fits */
@@ -857,7 +925,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
if (*cfirst=='.') cfirst++; /* step past dot at start */
if (*cfirst=='0') { /* [cfirst always -> digit] */
for (; cfirst<clast; cfirst++) {
- if (*cfirst!='0') { /* non-zero found */
+ if (*cfirst!='0') { /* non-zero found */
if (*cfirst=='.') continue; /* [ignore] */
break; /* done */
}
@@ -871,8 +939,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
/* (see commentary just above) */
if (c<=clast-3 /* safe for four */
- && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
- UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */
+ && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
+ UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */
ub+=4;
c+=3; /* [will become 4] */
continue;
@@ -881,7 +949,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
*ub++=(uByte)(*c-'0');
}
ub--; /* -> LSD */
- for (; c<=clast; c++) { /* inspect remaining chars */
+ for (; c<=clast; c++) { /* inspect remaining chars */
if (*c!='0') { /* sticky bit needed */
if (*c=='.') continue; /* [ignore] */
*ub=DECSTICKYTAB[*ub]; /* update round-for-reround */
@@ -925,7 +993,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
*ub=(uByte)(*c-'0'); /* good bcd8 */
}
if (*c!='\0') break; /* not all digits, or too many */
- num.lsd=ub-1; /* record new LSD */
+ num.lsd=ub-1; /* record new LSD */
}
} /* NaN or sNaN */
error=0; /* syntax is OK */
@@ -938,8 +1006,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
if (error!=0) {
set->status|=error;
- num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */
- num.sign=0; /* .. with 0 sign */
+ num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */
+ num.sign=0; /* .. with 0 sign */
buffer[0]=0; /* .. and coefficient */
num.lsd=buffer; /* .. */
/* decShowNum(&num, "oops"); */
@@ -957,7 +1025,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
/* result is the decFloat format number which gets the result of */
/* the conversion */
/* wider is the decFloatWider format number which will be narrowed */
-/* set is the context */
+/* set is the context */
/* returns result */
/* */
/* Narrowing can cause rounding, overflow, etc., but not Invalid */
@@ -968,7 +1036,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
decContext *set) {
bcdnum num; /* collects data for finishing */
- uByte bcdar[DECWPMAX]; /* room for wider coefficient */
+ uByte bcdar[DECWPMAX]; /* room for wider coefficient */
uInt widerhi=DFWWORD(wider, 0); /* top word */
Int exp;
@@ -979,7 +1047,7 @@ decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
num.sign=widerhi&0x80000000; /* extract sign [DECFLOAT_Sign=Neg] */
/* decode the wider combination field to exponent */
- exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */
+ exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */
/* if it is a special there's nothing to do unless sNaN; if it's */
/* finite then add the (wider) exponent continuation and unbias */
if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */
@@ -1001,7 +1069,7 @@ decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
/* returns the sign of the coefficient (DECFLOAT_Sign if negative, */
/* 0 otherwise) */
/* */
-/* No error is possible, and no status will be set. If df is a */
+/* No error is possible, and no status will be set. If df is a */
/* special value the array is set to zeros (for Infinity) or to the */
/* payload of a qNaN or sNaN. */
/* ------------------------------------------------------------------ */
@@ -1015,12 +1083,12 @@ Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) {
} /* decFloatGetCoefficient */
/* ------------------------------------------------------------------ */
-/* decFloatGetExponent -- get unbiased exponent */
+/* decFloatGetExponent -- get unbiased exponent */
/* */
/* df is the decFloat from which to extract the exponent */
/* returns the exponent, q. */
/* */
-/* No error is possible, and no status will be set. If df is a */
+/* No error is possible, and no status will be set. If df is a */
/* special value the first seven bits of the decFloat are returned, */
/* left adjusted and with the first (sign) bit set to 0 (followed by */
/* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN). */
@@ -1034,11 +1102,11 @@ Int decFloatGetExponent(const decFloat *df) {
/* decFloatSetCoefficient -- set coefficient from BCD8 */
/* */
/* df is the target decFloat (and source of exponent/special value) */
-/* bcdar holds DECPMAX digits to set the coefficient from, one */
+/* bcdar holds DECPMAX digits to set the coefficient from, one */
/* digit in each byte (BCD8 encoding); the first (MSD) is ignored */
/* if df is a NaN; all are ignored if df is infinite. */
/* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */
-/* returns df, which will be canonical */
+/* returns df, which will be canonical */
/* */
/* No error is possible, and no status will be set. */
/* ------------------------------------------------------------------ */
@@ -1060,18 +1128,18 @@ decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar,
} /* decFloatSetCoefficient */
/* ------------------------------------------------------------------ */
-/* decFloatSetExponent -- set exponent or special value */
+/* decFloatSetExponent -- set exponent or special value */
/* */
/* df is the target decFloat (and source of coefficient/payload) */
/* set is the context for reporting status */
/* exp is the unbiased exponent, q, or a special value in the form */
/* returned by decFloatGetExponent */
-/* returns df, which will be canonical */
+/* returns df, which will be canonical */
/* */
-/* No error is possible, but Overflow or Underflow might occur. */
+/* No error is possible, but Overflow or Underflow might occur. */
/* ------------------------------------------------------------------ */
decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) {
- uByte bcdcopy[DECPMAX]; /* for coefficient */
+ uByte bcdcopy[DECPMAX]; /* for coefficient */
bcdnum num; /* work */
num.exponent=exp;
num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */
@@ -1095,15 +1163,15 @@ uInt decFloatRadix(const decFloat *df) {
} /* decFloatRadix */
/* ------------------------------------------------------------------ */
-/* decFloatShow -- printf a decFloat in hexadecimal and decimal */
-/* df is the decFloat to show */
+/* decFloatShow -- printf a decFloat in hexadecimal and decimal */
+/* df is the decFloat to show */
/* tag is a tag string displayed with the number */
/* */
/* This is a debug aid; the precise format of the string may change. */
/* ------------------------------------------------------------------ */
void decFloatShow(const decFloat *df, const char *tag) {
char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */
- char buff[DECSTRING]; /* for value in decimal */
+ char buff[DECSTRING]; /* for value in decimal */
Int i, j=0;
for (i=0; i<DECBYTES; i++) {
@@ -1126,7 +1194,7 @@ void decFloatShow(const decFloat *df, const char *tag) {
/* */
/* df is the source decFloat */
/* exp will be set to the unbiased exponent, q, or to a special */
-/* value in the form returned by decFloatGetExponent */
+/* value in the form returned by decFloatGetExponent */
/* bcdar is where DECPMAX bytes will be written, one BCD digit in */
/* each byte (BCD8 encoding); if df is a NaN the first byte will */
/* be zero, and if it is infinite they will all be zero */
@@ -1156,7 +1224,7 @@ Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) {
/* ------------------------------------------------------------------ */
/* decFloatToEngString -- conversion to numeric string, engineering */
/* */
-/* df is the decFloat format number to convert */
+/* df is the decFloat format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least DECPMAX+9 characters (the worst case is */
@@ -1169,11 +1237,14 @@ char * decFloatToEngString(const decFloat *df, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
- char *cstart; /* coefficient start */
+ char *cstart; /* coefficient start */
char *c; /* output pointer in string */
char *s, *t; /* .. (source, target) */
Int pre, e; /* work */
const uByte *u; /* .. */
+ uInt uiwork; /* for macros [one compiler needs */
+ /* volatile here to avoid bug, but */
+ /* that doubles execution time] */
/* Source words; macro handles endianness */
uInt sourhi=DFWORD(df, 0); /* word with sign */
@@ -1188,12 +1259,12 @@ char * decFloatToEngString(const decFloat *df, char *string){
c=string; /* where result will go */
if (((Int)sourhi)<0) *c++='-'; /* handle sign */
comb=sourhi>>26; /* sign+combination field */
- msd=DECCOMBMSD[comb]; /* decode the combination field */
- exp=DECCOMBEXP[comb]; /* .. */
+ msd=DECCOMBMSD[comb]; /* decode the combination field */
+ exp=DECCOMBEXP[comb]; /* .. */
if (EXPISSPECIAL(exp)) { /* special */
if (exp==DECFLOAT_Inf) { /* infinity */
- strcpy(c, "Inf");
+ strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
@@ -1225,44 +1296,44 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* are the three encoded BCD8 digits followed by a 1-byte length */
/* (significant digits, except that 000 has length 0). This allows */
/* us to left-align the first declet with non-zero content, then */
- /* the remaining ones are full 3-char length. Fixed-length copies */
+ /* the remaining ones are full 3-char length. Fixed-length copies */
/* are used because variable-length memcpy causes a subroutine call */
- /* in at least two compilers. (The copies are length 4 for speed */
+ /* in at least two compilers. (The copies are length 4 for speed */
/* and are safe because the last item in the array is of length */
/* three and has the length byte following.) */
#define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \
- if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \
+ if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
else if (*(u+3)) { \
- UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);}
+ UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
#if DECPMAX==7
- dpd2char(sourhi>>10); /* declet 1 */
+ dpd2char(sourhi>>10); /* declet 1 */
dpd2char(sourhi); /* declet 2 */
#elif DECPMAX==16
dpd2char(sourhi>>8); /* declet 1 */
dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
- dpd2char(sourlo>>20); /* declet 3 */
- dpd2char(sourlo>>10); /* declet 4 */
+ dpd2char(sourlo>>20); /* declet 3 */
+ dpd2char(sourlo>>10); /* declet 4 */
dpd2char(sourlo); /* declet 5 */
#elif DECPMAX==34
dpd2char(sourhi>>4); /* declet 1 */
dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
- dpd2char(sourmh>>16); /* declet 3 */
+ dpd2char(sourmh>>16); /* declet 3 */
dpd2char(sourmh>>6); /* declet 4 */
dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
- dpd2char(sourml>>18); /* declet 6 */
+ dpd2char(sourml>>18); /* declet 6 */
dpd2char(sourml>>8); /* declet 7 */
dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
- dpd2char(sourlo>>20); /* declet 9 */
- dpd2char(sourlo>>10); /* declet 10 */
+ dpd2char(sourlo>>20); /* declet 9 */
+ dpd2char(sourlo>>10); /* declet 10 */
dpd2char(sourlo); /* declet 11 */
#endif
if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */
- if (exp==0) { /* integer or NaN case -- easy */
+ if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string;
}
@@ -1275,7 +1346,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
- if (e!=0) { /* engineering: may need to adjust */
+ if (e!=0) { /* engineering: may need to adjust */
Int adj; /* adjustment */
/* The C remainder operator is undefined for negative numbers, so */
/* a positive remainder calculation must be used here */
@@ -1310,8 +1381,8 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* because there is still space for exponent */
s=dotat+ROUNDDOWN4(c-dotat); /* source */
t=s+1; /* target */
- /* open the gap */
- for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
+ /* open the gap [cannot use memcpy] */
+ for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
*dotat='.';
c++; /* length increased by one */
} /* need dot? */
@@ -1321,24 +1392,24 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have
E, but only for 0.00E+3 kind of case -- with plenty of spare
space in this case */
- pre=-pre+2; /* gap width, including "0." */
+ pre=-pre+2; /* gap width, including "0." */
t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */
/* backoff if too far to the right */
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
/* now shift the entire coefficient to the right, being careful not */
- /* to access to the left of string */
- for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s);
+ /* to access to the left of string [cannot use memcpy] */
+ for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
/* for Quads and Singles there may be a character or two left... */
s+=3; /* where next would come from */
for(; s>=cstart; s--, t--) *(t+3)=*(s);
/* now have fill 0. through 0.00000; use overlaps to avoid tests */
if (pre>=4) {
- UINTAT(cstart+pre-4)=UINTAT("0000");
- UINTAT(cstart)=UINTAT("0.00");
+ memcpy(cstart+pre-4, "0000", 4);
+ memcpy(cstart, "0.00", 4);
}
else { /* 2 or 3 */
*(cstart+pre-1)='0';
- USHORTAT(cstart)=USHORTAT("0.");
+ memcpy(cstart, "0.", 2);
}
c+=pre; /* to end */
}
@@ -1346,7 +1417,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 or 4 digits (asserted above) */
if (e!=0) {
- USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */
+ memcpy(c, "E+", 2); /* starts with E, assume + */
c++;
if (e<0) {
*c='-'; /* oops, need '-' */
@@ -1355,15 +1426,15 @@ char * decFloatToEngString(const decFloat *df, char *string){
c++;
/* Three-character exponents are easy; 4-character a little trickier */
#if DECEMAXD<=3
- u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
+ u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
/* copy fixed 4 characters [is safe], starting at non-zero */
/* and with character mask to convert BCD to char */
- UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK;
+ UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
c+=*(u+3); /* bump pointer appropriately */
#elif DECEMAXD==4
if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
- UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
+ UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
else { /* 4-digits */
@@ -1371,7 +1442,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
- UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
+ UBFROMUI(c, UBTOUI(u)|CHARMASK);/* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
#endif
@@ -1386,7 +1457,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
/* */
/* df is the source decFloat */
/* exp will be set to the unbiased exponent, q, or to a special */
-/* value in the form returned by decFloatGetExponent */
+/* value in the form returned by decFloatGetExponent */
/* packed is where DECPMAX nibbles will be written with the sign as */
/* final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */
/* of zero, and an infinity is all zeros. decDouble and decQuad */
@@ -1432,7 +1503,7 @@ Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) {
/* ------------------------------------------------------------------ */
/* decFloatToString -- conversion to numeric string */
/* */
-/* df is the decFloat format number to convert */
+/* df is the decFloat format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least DECPMAX+9 characters (the worst case is */
@@ -1445,11 +1516,14 @@ char * decFloatToString(const decFloat *df, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
- char *cstart; /* coefficient start */
+ char *cstart; /* coefficient start */
char *c; /* output pointer in string */
char *s, *t; /* .. (source, target) */
Int pre, e; /* work */
const uByte *u; /* .. */
+ uInt uiwork; /* for macros [one compiler needs */
+ /* volatile here to avoid bug, but */
+ /* that doubles execution time] */
/* Source words; macro handles endianness */
uInt sourhi=DFWORD(df, 0); /* word with sign */
@@ -1464,10 +1538,14 @@ char * decFloatToString(const decFloat *df, char *string){
c=string; /* where result will go */
if (((Int)sourhi)<0) *c++='-'; /* handle sign */
comb=sourhi>>26; /* sign+combination field */
- msd=DECCOMBMSD[comb]; /* decode the combination field */
- exp=DECCOMBEXP[comb]; /* .. */
+ msd=DECCOMBMSD[comb]; /* decode the combination field */
+ exp=DECCOMBEXP[comb]; /* .. */
- if (EXPISSPECIAL(exp)) { /* special */
+ if (!EXPISSPECIAL(exp)) { /* finite */
+ /* complete exponent; top two bits are in place */
+ exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */
+ }
+ else { /* IS special */
if (exp==DECFLOAT_Inf) { /* infinity */
strcpy(c, "Infinity");
return string; /* easy */
@@ -1487,9 +1565,6 @@ char * decFloatToString(const decFloat *df, char *string){
/* otherwise drop through to add integer; set correct exp etc. */
exp=0; msd=0; /* setup for following code */
}
- else { /* complete exponent; top two bits are in place */
- exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */
- }
/* convert the digits of the significand to characters */
cstart=c; /* save start of coefficient */
@@ -1500,38 +1575,38 @@ char * decFloatToString(const decFloat *df, char *string){
/* are the three encoded BCD8 digits followed by a 1-byte length */
/* (significant digits, except that 000 has length 0). This allows */
/* us to left-align the first declet with non-zero content, then */
- /* the remaining ones are full 3-char length. Fixed-length copies */
+ /* the remaining ones are full 3-char length. Fixed-length copies */
/* are used because variable-length memcpy causes a subroutine call */
- /* in at least two compilers. (The copies are length 4 for speed */
+ /* in at least two compilers. (The copies are length 4 for speed */
/* and are safe because the last item in the array is of length */
/* three and has the length byte following.) */
#define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \
- if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \
+ if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
else if (*(u+3)) { \
- UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);}
+ UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
#if DECPMAX==7
- dpd2char(sourhi>>10); /* declet 1 */
+ dpd2char(sourhi>>10); /* declet 1 */
dpd2char(sourhi); /* declet 2 */
#elif DECPMAX==16
dpd2char(sourhi>>8); /* declet 1 */
dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
- dpd2char(sourlo>>20); /* declet 3 */
- dpd2char(sourlo>>10); /* declet 4 */
+ dpd2char(sourlo>>20); /* declet 3 */
+ dpd2char(sourlo>>10); /* declet 4 */
dpd2char(sourlo); /* declet 5 */
#elif DECPMAX==34
dpd2char(sourhi>>4); /* declet 1 */
dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
- dpd2char(sourmh>>16); /* declet 3 */
+ dpd2char(sourmh>>16); /* declet 3 */
dpd2char(sourmh>>6); /* declet 4 */
dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
- dpd2char(sourml>>18); /* declet 6 */
+ dpd2char(sourml>>18); /* declet 6 */
dpd2char(sourml>>8); /* declet 7 */
dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
- dpd2char(sourlo>>20); /* declet 9 */
- dpd2char(sourlo>>10); /* declet 10 */
+ dpd2char(sourlo>>20); /* declet 9 */
+ dpd2char(sourlo>>10); /* declet 10 */
dpd2char(sourlo); /* declet 11 */
#endif
@@ -1556,12 +1631,13 @@ char * decFloatToString(const decFloat *df, char *string){
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
+ /* [memmove is a disaster, here] */
/* move by fours; there must be space for junk at the end */
- /* because there is still space for exponent */
+ /* because exponent is still possible */
s=dotat+ROUNDDOWN4(c-dotat); /* source */
t=s+1; /* target */
- /* open the gap */
- for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
+ /* open the gap [cannot use memcpy] */
+ for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
*dotat='.';
c++; /* length increased by one */
} /* need dot? */
@@ -1569,10 +1645,10 @@ char * decFloatToString(const decFloat *df, char *string){
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 or 4 digits (asserted above) */
if (e!=0) {
- USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */
+ memcpy(c, "E+", 2); /* starts with E, assume + */
c++;
if (e<0) {
- *c='-'; /* oops, need '-' */
+ *c='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
c++;
@@ -1581,21 +1657,21 @@ char * decFloatToString(const decFloat *df, char *string){
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
/* copy fixed 4 characters [is safe], starting at non-zero */
/* and with character mask to convert BCD to char */
- UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK;
+ UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
c+=*(u+3); /* bump pointer appropriately */
#elif DECEMAXD==4
if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
- UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
+ UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
- else { /* 4-digits */
+ else { /* 4-digits */
Int thou=((e>>3)*1049)>>17; /* e/1000 */
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
- UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
- c+=3; /* bump pointer, always 3 digits */
+ UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
+ c+=3; /* bump pointer, always 3 digits */
}
#endif
}
@@ -1618,19 +1694,19 @@ char * decFloatToString(const decFloat *df, char *string){
/* backoff if too far to the right */
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
/* now shift the entire coefficient to the right, being careful not */
- /* to access to the left of string */
- for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s);
+ /* to access to the left of string [cannot use memcpy] */
+ for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
/* for Quads and Singles there may be a character or two left... */
- s+=3; /* where next would come from */
+ s+=3; /* where next would come from */
for(; s>=cstart; s--, t--) *(t+3)=*(s);
/* now have fill 0. through 0.00000; use overlaps to avoid tests */
if (pre>=4) {
- UINTAT(cstart+pre-4)=UINTAT("0000");
- UINTAT(cstart)=UINTAT("0.00");
+ memcpy(cstart+pre-4, "0000", 4);
+ memcpy(cstart, "0.00", 4);
}
else { /* 2 or 3 */
*(cstart+pre-1)='0';
- USHORTAT(cstart)=USHORTAT("0.");
+ memcpy(cstart, "0.", 2);
}
*(c+pre)='\0'; /* terminate */
return string;
@@ -1665,7 +1741,7 @@ decFloatWider * decFloatToWider(const decFloat *source, decFloatWider *wider) {
code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */
code|=DFWORD(source, 0)&0x80000000; /* add sign */
DFWWORD(wider, 0)=code; /* .. and place top word in wider */
- msd=GETMSD(source); /* get source coefficient MSD [0-9] */
+ msd=GETMSD(source); /* get source coefficient MSD [0-9] */
}
/* Copy the coefficient and clear any 'unused' words to left */
#if SINGLE
@@ -1723,6 +1799,7 @@ decFloat * decFloatZero(decFloat *df){
void decShowNum(const bcdnum *num, const char *tag) {
const char *csign="+"; /* sign character */
uByte *ub; /* work */
+ uInt uiwork; /* for macros */
if (num->sign==DECFLOAT_Sign) csign="-";
printf(">%s> ", tag);
@@ -1747,7 +1824,7 @@ decFloat * decFloatZero(decFloat *df){
if (e==0) *c++='0'; /* 0-length case */
else if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
- UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
+ UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
else { /* 4-digits */
@@ -1755,7 +1832,7 @@ decFloat * decFloatZero(decFloat *df){
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
- UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
+ UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
*c='\0'; /* add terminator */