OSDN Git Service

* decNumber.c, decNumber.h, decNumberLocal.h, decDouble.c,
authorbje <bje@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 29 Mar 2009 00:33:22 +0000 (00:33 +0000)
committerbje <bje@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 29 Mar 2009 00:33:22 +0000 (00:33 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145222 138bc75d-0d04-0410-961f-82ee72b054a4

23 files changed:
libdecnumber/ChangeLog
libdecnumber/decBasic.c
libdecnumber/decCommon.c
libdecnumber/decContext.c
libdecnumber/decContext.h
libdecnumber/decDPD.h
libdecnumber/decDouble.c
libdecnumber/decDouble.h
libdecnumber/decNumber.c
libdecnumber/decNumber.h
libdecnumber/decNumberLocal.h
libdecnumber/decPacked.c
libdecnumber/decPacked.h
libdecnumber/decQuad.c
libdecnumber/decQuad.h
libdecnumber/decSingle.c
libdecnumber/decSingle.h
libdecnumber/dpd/decimal128.c
libdecnumber/dpd/decimal128.h
libdecnumber/dpd/decimal32.c
libdecnumber/dpd/decimal32.h
libdecnumber/dpd/decimal64.c
libdecnumber/dpd/decimal64.h

index 21943b9..d49bfb5 100644 (file)
@@ -1,3 +1,12 @@
+2009-03-29  Ben Elliston  <bje@au.ibm.com>
+
+       * decNumber.c, decNumber.h, decNumberLocal.h, decDouble.c,
+       decDouble.h, decSingle.c, decContext.c, decSingle.h, decPacked.c,
+       decCommon.c, decContext.h, decQuad.c, decPacked.h, decQuad.h,
+       decDPD.h, decBasic.c: Upgrade to decNumber 3.61.
+       * dpd/decimal128.h, dpd/decimal32.c, dpd/decimal32.h,
+       dpd/decimal64.c, dpd/decimal128.c, dpd/decimal64.h: Likewise.
+
 2009-02-10  Joseph Myers  <joseph@codesourcery.com>
 
        * Makefile.in (clean): Don't remove makedepend$(EXEEXT).
index fddba97..06aa8ba 100644 (file)
@@ -32,8 +32,8 @@
 /* decBasic.c -- common base code for Basic decimal types            */
 /* ------------------------------------------------------------------ */
 /* This module comprises code that is shared between decDouble and    */
-/* decQuad (but not decSingle).         The main arithmetic operations are   */
-/* here (Add, Subtract, Multiply, FMA, and Division operators).              */
+/* decQuad (but not decSingle).  The main arithmetic operations are   */
+/* here (Add, Subtract, Multiply, FMA, and Division operators).       */
 /*                                                                   */
 /* Unlike decNumber, parameterization takes place at compile time     */
 /* rather than at runtime.  The parameters are set in the decDouble.c */
@@ -59,7 +59,7 @@
 #define DIVIDE     0x80000000     /* Divide operations [as flags] */
 #define REMAINDER   0x40000000    /* .. */
 #define DIVIDEINT   0x20000000    /* .. */
-#define REMNEAR            0x10000000     /* .. */
+#define REMNEAR     0x10000000    /* .. */
 
 /* Private functions (local, used only by routines in this module) */
 static decFloat *decDivide(decFloat *, const decFloat *,
@@ -81,7 +81,7 @@ static uInt    decToInt32(const decFloat *, decContext *, enum rounding,
 /* decCanonical -- copy a decFloat, making canonical                 */
 /*                                                                   */
 /*   result gets the canonicalized df                                */
-/*   df            is the decFloat to copy and make canonical                */
+/*   df     is the decFloat to copy and make canonical               */
 /*   returns result                                                  */
 /*                                                                   */
 /* This is exposed via decFloatCanonical for Double and Quad only.    */
@@ -141,14 +141,14 @@ static decFloat * decCanonical(decFloat *result, const decFloat *df) {
       uoff-=32;
       dpd|=encode<<(10-uoff);     /* get pending bits */
       }
-    dpd&=0x3ff;                           /* clear uninteresting bits */
+    dpd&=0x3ff;                   /* clear uninteresting bits */
     if (dpd<0x16e) continue;      /* must be canonical */
     canon=BIN2DPD[DPD2BIN[dpd]];   /* determine canonical declet */
     if (canon==dpd) continue;     /* have canonical declet */
     /* need to replace declet */
     if (uoff>=10) {               /* all within current word */
       encode&=~(0x3ff<<(uoff-10)); /* clear the 10 bits ready for replace */
-      encode|=canon<<(uoff-10);           /* insert the canonical form */
+      encode|=canon<<(uoff-10);    /* insert the canonical form */
       DFWORD(result, inword)=encode;   /* .. and save */
       continue;
       }
@@ -167,16 +167,16 @@ static decFloat * decCanonical(decFloat *result, const decFloat *df) {
 /* decDivide -- divide operations                                    */
 /*                                                                   */
 /*   result gets the result of dividing dfl by dfr:                  */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
-/*   op            is the operation selector                                 */
+/*   op     is the operation selector                                */
 /*   returns result                                                  */
 /*                                                                   */
 /* op is one of DIVIDE, REMAINDER, DIVIDEINT, or REMNEAR.            */
 /* ------------------------------------------------------------------ */
 #define DIVCOUNT  0               /* 1 to instrument subtractions counter */
-#define DIVBASE          BILLION          /* the base used for divide */
+#define DIVBASE   ((uInt)BILLION)  /* the base used for divide */
 #define DIVOPLEN  DECPMAX9        /* operand length ('digits' base 10**9) */
 #define DIVACCLEN (DIVOPLEN*3)    /* accumulator length (ditto) */
 static decFloat * decDivide(decFloat *result, const decFloat *dfl,
@@ -184,17 +184,18 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
   decFloat quotient;              /* for remainders */
   bcdnum num;                     /* for final conversion */
   uInt  acc[DIVACCLEN];           /* coefficent in base-billion .. */
-  uInt  div[DIVOPLEN];            /* divisor in base-billion .. */
+  uInt  div[DIVOPLEN];            /* divisor in base-billion .. */
   uInt  quo[DIVOPLEN+1];          /* quotient in base-billion .. */
-  uByte         bcdacc[(DIVOPLEN+1)*9+2]; /* for quotient in BCD, +1, +1 */
+  uByte  bcdacc[(DIVOPLEN+1)*9+2]; /* for quotient in BCD, +1, +1 */
   uInt  *msua, *msud, *msuq;      /* -> msu of acc, div, and quo */
   Int   divunits, accunits;       /* lengths */
   Int   quodigits;                /* digits in quotient */
   uInt  *lsua, *lsuq;             /* -> current acc and quo lsus */
   Int   length, multiplier;       /* work */
   uInt  carry, sign;              /* .. */
-  uInt  *ua, *ud, *uq;            /* .. */
-  uByte         *ub;                      /* .. */
+  uInt  *ua, *ud, *uq;            /* .. */
+  uByte  *ub;                     /* .. */
+  uInt  uiwork;                   /* for macros */
   uInt  divtop;                   /* top unit of div adjusted for estimating */
   #if DIVCOUNT
   static uInt maxcount=0;         /* worst-seen subtractions count */
@@ -235,7 +236,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
     if (op&(REMAINDER|REMNEAR)) return decInvalid(result, set); /* bad rem */
     set->status|=DEC_Division_by_zero;
     DFWORD(result, 0)=num.sign;
-    return decInfinity(result, result);             /* x/0 -> signed Infinity */
+    return decInfinity(result, result);      /* x/0 -> signed Infinity */
     }
   num.exponent=GETEXPUN(dfl)-GETEXPUN(dfr);  /* ideal exponent */
   if (DFISZERO(dfl)) {                      /* 0/x (x!=0) */
@@ -246,7 +247,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
       DFWORD(result, 0)|=num.sign;          /* add sign */
       return result;
       }
-    if (!(op&DIVIDE)) {                             /* a remainder */
+    if (!(op&DIVIDE)) {                     /* a remainder */
       /* exponent is the minimum of the operands */
       num.exponent=MINI(GETEXPUN(dfl), GETEXPUN(dfr));
       /* if the result is zero the sign shall be sign of dfl */
@@ -289,7 +290,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
   #endif
 
   /* set msu and lsu pointers */
-  msua=acc+DIVACCLEN-1;              /* [leading zeros removed below] */
+  msua=acc+DIVACCLEN-1;       /* [leading zeros removed below] */
   msuq=quo+DIVOPLEN;
   /*[loop for div will terminate because operands are non-zero] */
   for (msud=div+DIVOPLEN-1; *msud==0;) msud--;
@@ -298,7 +299,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
   /* This moves one position towards the least possible for each */
   /* iteration */
   divunits=(Int)(msud-div+1); /* precalculate */
-  lsua=msua-divunits+1;              /* initial working lsu of acc */
+  lsua=msua-divunits+1;       /* initial working lsu of acc */
   lsuq=msuq;                 /* and of quo */
 
   /* set up the estimator for the multiplier; this is the msu of div, */
@@ -371,7 +372,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
        for (ud=msud, ua=msua; ud>div; ud--, ua--) if (*ud!=*ua) break;
        /* [now at first mismatch or lsu] */
        if (*ud>*ua) break;                       /* next time... */
-       if (*ud==*ua) {                           /* all compared equal */
+       if (*ud==*ua) {                           /* all compared equal */
          *lsuq+=1;                               /* increment result */
          msua=lsua;                              /* collapse acc units */
          *msua=0;                                /* .. to a zero */
@@ -418,10 +419,11 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
            }
           else if (divunits==1) {
            mul=(uLong)*msua * DIVBASE + *(msua-1);
-           mul/=*msud;       /* no more to the right */
+           mul/=*msud;       /* no more to the right */
            }
           else {
-           mul=(uLong)(*msua) * (uInt)(DIVBASE<<2) + (*(msua-1)<<2);
+           mul=(uLong)(*msua) * (uInt)(DIVBASE<<2)
+               + (*(msua-1)<<2);
            mul/=divtop;      /* [divtop already allows for sticky bits] */
            }
          multiplier=(Int)mul;
@@ -540,10 +542,10 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
   /* most significant end [offset by one into bcdacc to leave room */
   /* for a possible carry digit if rounding for REMNEAR is needed] */
   for (uq=msuq, ub=bcdacc+1; uq>=lsuq; uq--, ub+=9) {
-    uInt top, mid, rem;                        /* work */
+    uInt top, mid, rem;                /* work */
     if (*uq==0) {                      /* no split needed */
-      UINTAT(ub)=0;                    /* clear 9 BCD8s */
-      UINTAT(ub+4)=0;                  /* .. */
+      UBFROMUI(ub, 0);                 /* clear 9 BCD8s */
+      UBFROMUI(ub+4, 0);               /* .. */
       *(ub+8)=0;                       /* .. */
       continue;
       }
@@ -558,11 +560,11 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
     mid=rem/divsplit6;
     rem=rem%divsplit6;
     /* lay out the nine BCD digits (plus one unwanted byte) */
-    UINTAT(ub) =UINTAT(&BIN2BCD8[top*4]);
-    UINTAT(ub+3)=UINTAT(&BIN2BCD8[mid*4]);
-    UINTAT(ub+6)=UINTAT(&BIN2BCD8[rem*4]);
+    UBFROMUI(ub,   UBTOUI(&BIN2BCD8[top*4]));
+    UBFROMUI(ub+3, UBTOUI(&BIN2BCD8[mid*4]));
+    UBFROMUI(ub+6, UBTOUI(&BIN2BCD8[rem*4]));
     } /* BCD conversion loop */
-  ub--;                                        /* -> lsu */
+  ub--;                                /* -> lsu */
 
   /* complete the bcdnum; quodigits is correct, so the position of */
   /* the first non-zero is known */
@@ -642,7 +644,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
        num.msd--;                           /* use the 0 .. */
        num.lsd=num.msd;                     /* .. at the new MSD place */
        }
-      if (reround!=0) {                             /* discarding non-zero */
+      if (reround!=0) {                     /* discarding non-zero */
        uInt bump=0;
        /* rounding is DEC_ROUND_HALF_EVEN always */
        if (reround>5) bump=1;               /* >0.5 goes up */
@@ -651,7 +653,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
        if (bump!=0) {                       /* need increment */
          /* increment the coefficient; this might end up with 1000... */
          ub=num.lsd;
-         for (; UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0;
+         for (; UBTOUI(ub-3)==0x09090909; ub-=4) UBFROMUI(ub-3, 0);
          for (; *ub==9; ub--) *ub=0;        /* at most 3 more */
          *ub+=1;
          if (ub<num.msd) num.msd--;         /* carried */
@@ -680,7 +682,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
 /*                                                                   */
 /*   num    gets the result of multiplying dfl and dfr               */
 /*   bcdacc .. with the coefficient in this array                    */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*                                                                   */
 /* This effects the multiplication of two decFloats, both known to be */
@@ -695,7 +697,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
 /* variables (Ints and uInts) or smaller; the other uses uLongs (for */
 /* multiplication and addition only).  Both implementations cover */
 /* both arithmetic sizes (DOUBLE and QUAD) in order to allow timing */
-/* comparisons.         In any one compilation only one implementation for */
+/* comparisons.  In any one compilation only one implementation for */
 /* each size can be used, and if DECUSE64 is 0 then use of the 32-bit */
 /* version is forced. */
 /* */
@@ -704,7 +706,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
 /* during lazy carry splitting because the initial quotient estimate */
 /* (est) can exceed 32 bits. */
 
-#define MULTBASE  BILLION         /* the base used for multiply */
+#define MULTBASE  ((uInt)BILLION)  /* the base used for multiply */
 #define MULOPLEN  DECPMAX9        /* operand length ('digits' base 10**9) */
 #define MULACCLEN (MULOPLEN*2)             /* accumulator length (ditto) */
 #define LEADZEROS (MULACCLEN*9 - DECPMAX*2) /* leading zeros always */
@@ -723,11 +725,12 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
   uInt  bufl[MULOPLEN];           /* left  coefficient (base-billion) */
   uInt  bufr[MULOPLEN];           /* right coefficient (base-billion) */
   uInt  *ui, *uj;                 /* work */
-  uByte         *ub;                      /* .. */
+  uByte  *ub;                     /* .. */
+  uInt  uiwork;                   /* for macros */
 
   #if DECUSE64
-  uLong         accl[MULACCLEN];          /* lazy accumulator (base-billion+) */
-  uLong         *pl;                      /* work -> lazy accumulator */
+  uLong  accl[MULACCLEN];         /* lazy accumulator (base-billion+) */
+  uLong  *pl;                     /* work -> lazy accumulator */
   uInt  acc[MULACCLEN];           /* coefficent in base-billion .. */
   #else
   uInt  acc[MULACCLEN*2];         /* accumulator in base-billion .. */
@@ -760,7 +763,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
   /* zero the accumulator */
   #if MULACCLEN==4
     accl[0]=0; accl[1]=0; accl[2]=0; accl[3]=0;
-  #else                                             /* use a loop */
+  #else                                     /* use a loop */
     /* MULACCLEN is a multiple of four, asserted above */
     for (pl=accl; pl<accl+MULACCLEN; pl+=4) {
       *pl=0; *(pl+1)=0; *(pl+2)=0; *(pl+3)=0;/* [reduce overhead] */
@@ -812,8 +815,8 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
   /* */
   /*   Type    OPLEN   A   B    maxX    maxError  maxCorrection */
   /*   --------------------------------------------------------- */
-  /*   DOUBLE   2    29  32  <2*10**18    0.63       1 */
-  /*   QUAD     4    30  31  <4*10**18    1.17       2 */
+  /*   DOUBLE   2    29  32  <2*10**18    0.63       1 */
+  /*   QUAD     4    30  31  <4*10**18    1.17       2 */
   /* */
   /* In the OPLEN==2 case there is most choice, but the value for B */
   /* of 32 has a big advantage as then the calculation of the */
@@ -840,7 +843,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
   for (pl=accl, pa=acc; pl<accl+MULACCLEN; pl++, pa++) { /* each column position */
     uInt lo, hop;                      /* work */
     uInt est;                          /* cannot exceed 4E+9 */
-    if (*pl>MULTBASE) {
+    if (*pl>=MULTBASE) {
       /* *pl holds a binary number which needs to be split */
       hop=(uInt)(*pl>>MULSHIFTA);
       est=(uInt)(((uLong)hop*MULMAGIC)>>MULSHIFTB);
@@ -905,7 +908,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
   /* quotient/remainder has to be calculated for base-billion (1E+9). */
   /* For this, Clark & Cowlishaw's quotient estimation approach (also */
   /* used in decNumber) is needed, because 64-bit divide is generally */
-  /* extremely slow on 32-bit machines.         This algorithm splits X */
+  /* extremely slow on 32-bit machines.  This algorithm splits X */
   /* using: */
   /* */
   /*   magic=2**(A+B)/1E+9;   // 'magic number' */
@@ -927,8 +930,8 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
   /* */
   /*   Type    OPLEN   A   B    maxX    maxError  maxCorrection */
   /*   --------------------------------------------------------- */
-  /*   DOUBLE   2    29  32  <2*10**18    0.63       1 */
-  /*   QUAD     4    30  31  <4*10**18    1.17       2 */
+  /*   DOUBLE   2    29  32  <2*10**18    0.63       1 */
+  /*   QUAD     4    30  31  <4*10**18    1.17       2 */
   /* */
   /* In the OPLEN==2 case there is most choice, but the value for B */
   /* of 32 has a big advantage as then the calculation of the */
@@ -952,15 +955,15 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
   printf("\n");
   #endif
 
-  for (pa=acc;; pa++) {                        /* each low uInt */
+  for (pa=acc;; pa++) {                /* each low uInt */
     uInt hi, lo;                       /* words of exact multiply result */
     uInt hop, estlo;                   /* work */
     #if QUAD
-    uInt esthi;                                /* .. */
+    uInt esthi;                        /* .. */
     #endif
 
     lo=*pa;
-    hi=*(pa+MULACCLEN);                        /* top 32 bits */
+    hi=*(pa+MULACCLEN);                /* top 32 bits */
     /* hi and lo now hold a binary number which needs to be split */
 
     #if DOUBLE
@@ -1032,7 +1035,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
       uInt top, mid, rem;              /* work */
       /* *pa is non-zero -- split the base-billion acc digit into */
       /* hi, mid, and low three-digits */
-      #define mulsplit9 1000000                /* divisor */
+      #define mulsplit9 1000000        /* divisor */
       #define mulsplit6 1000           /* divisor */
       /* The splitting is done by simple divides and remainders, */
       /* assuming the compiler will optimize these where useful */
@@ -1042,13 +1045,13 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
       mid=rem/mulsplit6;
       rem=rem%mulsplit6;
       /* lay out the nine BCD digits (plus one unwanted byte) */
-      UINTAT(ub)  =UINTAT(&BIN2BCD8[top*4]);
-      UINTAT(ub+3)=UINTAT(&BIN2BCD8[mid*4]);
-      UINTAT(ub+6)=UINTAT(&BIN2BCD8[rem*4]);
+      UBFROMUI(ub,   UBTOUI(&BIN2BCD8[top*4]));
+      UBFROMUI(ub+3, UBTOUI(&BIN2BCD8[mid*4]));
+      UBFROMUI(ub+6, UBTOUI(&BIN2BCD8[rem*4]));
       }
      else {                            /* *pa==0 */
-      UINTAT(ub)=0;                    /* clear 9 BCD8s */
-      UINTAT(ub+4)=0;                  /* .. */
+      UBFROMUI(ub, 0);                 /* clear 9 BCD8s */
+      UBFROMUI(ub+4, 0);               /* .. */
       *(ub+8)=0;                       /* .. */
       }
     if (pa==acc) break;
@@ -1068,7 +1071,7 @@ static void decFiniteMultiply(bcdnum *num, uByte *bcdacc,
 /* decFloatAbs -- absolute value, heeding NaNs, etc.                 */
 /*                                                                   */
 /*   result gets the canonicalized df with sign 0                    */
-/*   df            is the decFloat to abs                                    */
+/*   df     is the decFloat to abs                                   */
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
@@ -1090,26 +1093,45 @@ decFloat * decFloatAbs(decFloat *result, const decFloat *df,
 /* decFloatAdd -- add two decFloats                                  */
 /*                                                                   */
 /*   result gets the result of adding dfl and dfr:                   */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
 /* ------------------------------------------------------------------ */
+#if QUAD
+/* Table for testing MSDs for fastpath elimination; returns the MSD of */
+/* a decDouble or decQuad (top 6 bits tested) ignoring the sign. */
+/* Infinities return -32 and NaNs return -128 so that summing the two */
+/* MSDs also allows rapid tests for the Specials (see code below). */
+const Int DECTESTMSD[64]={
+  0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5,   6,    7,
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, -32, -128,
+  0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5,   6,    7,
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, -32, -128};
+#else
+/* The table for testing MSDs is shared between the modules */
+extern const Int DECTESTMSD[64];
+#endif
+
 decFloat * decFloatAdd(decFloat *result,
                       const decFloat *dfl, const decFloat *dfr,
                       decContext *set) {
   bcdnum num;                     /* for final conversion */
-  Int   expl, expr;               /* left and right exponents */
-  uInt  *ui, *uj;                 /* work */
-  uByte         *ub;                      /* .. */
+  Int   bexpl, bexpr;             /* left and right biased exponents */
+  uByte  *ub, *us, *ut;           /* work */
+  uInt  uiwork;                   /* for macros */
+  #if QUAD
+  uShort uswork;                  /* .. */
+  #endif
 
   uInt sourhil, sourhir;          /* top words from source decFloats */
-                                  /* [valid only until specials */
-                                  /* handled or exponents decoded] */
+                                  /* [valid only through end of */
+                                  /* fastpath code -- before swap] */
   uInt diffsign;                  /* non-zero if signs differ */
   uInt carry;                     /* carry: 0 or 1 before add loop */
-  Int  overlap;                           /* coefficient overlap (if full) */
+  Int  overlap;                   /* coefficient overlap (if full) */
+  Int  summ;                      /* sum of the MSDs */
   /* the following buffers hold coefficients with various alignments */
   /* (see commentary and diagrams below) */
   uByte acc[4+2+DECPMAX*3+8];
@@ -1117,48 +1139,116 @@ decFloat * decFloatAdd(decFloat *result,
   uByte *umsd, *ulsd;             /* local MSD and LSD pointers */
 
   #if DECLITEND
-    #define CARRYPAT 0x01000000           /* carry=1 pattern */
+    #define CARRYPAT 0x01000000    /* carry=1 pattern */
   #else
-    #define CARRYPAT 0x00000001           /* carry=1 pattern */
+    #define CARRYPAT 0x00000001    /* carry=1 pattern */
   #endif
 
   /* Start decoding the arguments */
-  /* the initial exponents are placed into the opposite Ints to */
+  /* The initial exponents are placed into the opposite Ints to */
   /* that which might be expected; there are two sets of data to */
   /* keep track of (each decFloat and the corresponding exponent), */
   /* and this scheme means that at the swap point (after comparing */
   /* exponents) only one pair of words needs to be swapped */
-  /* whichever path is taken (thereby minimising worst-case path) */
+  /* whichever path is taken (thereby minimising worst-case path). */
+  /* The calculated exponents will be nonsense when the arguments are */
+  /* Special, but are not used in that path */
   sourhil=DFWORD(dfl, 0);         /* LHS top word */
-  expr=DECCOMBEXP[sourhil>>26];           /* get exponent high bits (in place) */
+  summ=DECTESTMSD[sourhil>>26];    /* get first MSD for testing */
+  bexpr=DECCOMBEXP[sourhil>>26];   /* get exponent high bits (in place) */
+  bexpr+=GETECON(dfl);            /* .. + continuation */
+
   sourhir=DFWORD(dfr, 0);         /* RHS top word */
-  expl=DECCOMBEXP[sourhir>>26];
+  summ+=DECTESTMSD[sourhir>>26];   /* sum MSDs for testing */
+  bexpl=DECCOMBEXP[sourhir>>26];
+  bexpl+=GETECON(dfr);
+
+  /* here bexpr has biased exponent from lhs, and vice versa */
 
   diffsign=(sourhil^sourhir)&DECFLOAT_Sign;
 
-  if (EXPISSPECIAL(expl | expr)) { /* either is special? */
-    if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set);
-    /* one or two infinities */
-    /* two infinities with different signs is invalid */
-    if (diffsign && DFISINF(dfl) && DFISINF(dfr))
-      return decInvalid(result, set);
-    if (DFISINF(dfl)) return decInfinity(result, dfl); /* LHS is infinite */
-    return decInfinity(result, dfr);                  /* RHS must be Infinite */
-    }
+  /* now determine whether to take a fast path or the full-function */
+  /* slow path.  The slow path must be taken when: */
+  /*   -- both numbers are finite, and: */
+  /*        the exponents are different, or */
+  /*        the signs are different, or */
+  /*        the sum of the MSDs is >8 (hence might overflow) */
+  /* specialness and the sum of the MSDs can be tested at once using */
+  /* the summ value just calculated, so the test for specials is no */
+  /* longer on the worst-case path (as of 3.60) */
+
+  if (summ<=8) {                  /* MSD+MSD is good, or there is a special */
+    if (summ<0) {                 /* there is a special */
+      /* Inf+Inf would give -64; Inf+finite is -32 or higher */
+      if (summ<-64) return decNaNs(result, dfl, dfr, set);  /* one or two NaNs */
+      /* two infinities with different signs is invalid */
+      if (summ==-64 && diffsign) return decInvalid(result, set);
+      if (DFISINF(dfl)) return decInfinity(result, dfl);    /* LHS is infinite */
+      return decInfinity(result, dfr);                     /* RHS must be Inf */
+      }
+    /* Here when both arguments are finite; fast path is possible */
+    /* (currently only for aligned and same-sign) */
+    if (bexpr==bexpl && !diffsign) {
+      uInt tac[DECLETS+1];             /* base-1000 coefficient */
+      uInt encode;                     /* work */
+
+      /* Get one coefficient as base-1000 and add the other */
+      GETCOEFFTHOU(dfl, tac);          /* least-significant goes to [0] */
+      ADDCOEFFTHOU(dfr, tac);
+      /* here the sum of the MSDs (plus any carry) will be <10 due to */
+      /* the fastpath test earlier */
+
+      /* construct the result; low word is the same for both formats */
+      encode =BIN2DPD[tac[0]];
+      encode|=BIN2DPD[tac[1]]<<10;
+      encode|=BIN2DPD[tac[2]]<<20;
+      encode|=BIN2DPD[tac[3]]<<30;
+      DFWORD(result, (DECBYTES/4)-1)=encode;
+
+      /* collect next two declets (all that remains, for Double) */
+      encode =BIN2DPD[tac[3]]>>2;
+      encode|=BIN2DPD[tac[4]]<<8;
 
-  /* Here when both arguments are finite */
+      #if QUAD
+      /* complete and lay out middling words */
+      encode|=BIN2DPD[tac[5]]<<18;
+      encode|=BIN2DPD[tac[6]]<<28;
+      DFWORD(result, 2)=encode;
+
+      encode =BIN2DPD[tac[6]]>>4;
+      encode|=BIN2DPD[tac[7]]<<6;
+      encode|=BIN2DPD[tac[8]]<<16;
+      encode|=BIN2DPD[tac[9]]<<26;
+      DFWORD(result, 1)=encode;
+
+      /* and final two declets */
+      encode =BIN2DPD[tac[9]]>>6;
+      encode|=BIN2DPD[tac[10]]<<4;
+      #endif
 
-  /* complete exponent gathering (keeping swapped) */
-  expr+=GETECON(dfl)-DECBIAS;     /* .. + continuation and unbias */
-  expl+=GETECON(dfr)-DECBIAS;
-  /* here expr has exponent from lhs, and vice versa */
+      /* add exponent continuation and sign (from either argument) */
+      encode|=sourhil & (ECONMASK | DECFLOAT_Sign);
+
+      /* create lookup index = MSD + top two bits of biased exponent <<4 */
+      tac[DECLETS]|=(bexpl>>DECECONL)<<4;
+      encode|=DECCOMBFROM[tac[DECLETS]]; /* add constructed combination field */
+      DFWORD(result, 0)=encode;         /* complete */
+
+      /* decFloatShow(result, ">"); */
+      return result;
+      } /* fast path OK */
+    /* drop through to slow path */
+    } /* low sum or Special(s) */
+
+  /* Slow path required -- arguments are finite and might overflow,   */
+  /* or require alignment, or might have different signs             */
 
   /* now swap either exponents or argument pointers */
-  if (expl<=expr) {
+  if (bexpl<=bexpr) {
     /* original left is bigger */
-    Int expswap=expl;
-    expl=expr;
-    expr=expswap;
+    Int bexpswap=bexpl;
+    bexpl=bexpr;
+    bexpr=bexpswap;
     /* printf("left bigger\n"); */
     }
    else {
@@ -1167,7 +1257,7 @@ decFloat * decFloatAdd(decFloat *result,
     dfr=dfswap;
     /* printf("right bigger\n"); */
     }
-  /* [here dfl and expl refer to the datum with the larger exponent, */
+  /* [here dfl and bexpl refer to the datum with the larger exponent, */
   /* of if the exponents are equal then the original LHS argument] */
 
   /* if lhs is zero then result will be the rhs (now known to have */
@@ -1209,19 +1299,19 @@ decFloat * decFloatAdd(decFloat *result,
   #if DOUBLE
     #define COFF 4                     /* offset into acc */
   #elif QUAD
-    USHORTAT(acc+4)=0;                 /* prefix 00 */
+    UBFROMUS(acc+4, 0);                /* prefix 00 */
     #define COFF 6                     /* offset into acc */
   #endif
 
   GETCOEFF(dfl, acc+COFF);             /* decode from decFloat */
   ulsd=acc+COFF+DECPMAX-1;
   umsd=acc+4;                          /* [having this here avoids */
-                                       /* weird GCC optimizer failure] */
+
   #if DECTRACE
   {bcdnum tum;
   tum.msd=umsd;
   tum.lsd=ulsd;
-  tum.exponent=expl;
+  tum.exponent=bexpl-DECBIAS;
   tum.sign=DFWORD(dfl, 0) & DECFLOAT_Sign;
   decShowNum(&tum, "dflx");}
   #endif
@@ -1235,16 +1325,16 @@ decFloat * decFloatAdd(decFloat *result,
   carry=0;                             /* assume no carry */
   if (diffsign) {
     carry=CARRYPAT;                    /* for +1 during add */
-    UINTAT(acc+ 4)=0x09090909-UINTAT(acc+ 4);
-    UINTAT(acc+ 8)=0x09090909-UINTAT(acc+ 8);
-    UINTAT(acc+12)=0x09090909-UINTAT(acc+12);
-    UINTAT(acc+16)=0x09090909-UINTAT(acc+16);
+    UBFROMUI(acc+ 4, 0x09090909-UBTOUI(acc+ 4));
+    UBFROMUI(acc+ 8, 0x09090909-UBTOUI(acc+ 8));
+    UBFROMUI(acc+12, 0x09090909-UBTOUI(acc+12));
+    UBFROMUI(acc+16, 0x09090909-UBTOUI(acc+16));
     #if QUAD
-    UINTAT(acc+20)=0x09090909-UINTAT(acc+20);
-    UINTAT(acc+24)=0x09090909-UINTAT(acc+24);
-    UINTAT(acc+28)=0x09090909-UINTAT(acc+28);
-    UINTAT(acc+32)=0x09090909-UINTAT(acc+32);
-    UINTAT(acc+36)=0x09090909-UINTAT(acc+36);
+    UBFROMUI(acc+20, 0x09090909-UBTOUI(acc+20));
+    UBFROMUI(acc+24, 0x09090909-UBTOUI(acc+24));
+    UBFROMUI(acc+28, 0x09090909-UBTOUI(acc+28));
+    UBFROMUI(acc+32, 0x09090909-UBTOUI(acc+32));
+    UBFROMUI(acc+36, 0x09090909-UBTOUI(acc+36));
     #endif
     } /* diffsign */
 
@@ -1252,9 +1342,9 @@ decFloat * decFloatAdd(decFloat *result,
   /* it can be put straight into acc (with an appropriate gap, if */
   /* needed) because no actual addition will be needed (except */
   /* possibly to complete ten's complement) */
-  overlap=DECPMAX-(expl-expr);
+  overlap=DECPMAX-(bexpl-bexpr);
   #if DECTRACE
-  printf("exps: %ld %ld\n", (LI)expl, (LI)expr);
+  printf("exps: %ld %ld\n", (LI)(bexpl-DECBIAS), (LI)(bexpr-DECBIAS));
   printf("Overlap=%ld carry=%08lx\n", (LI)overlap, (LI)carry);
   #endif
 
@@ -1274,13 +1364,13 @@ decFloat * decFloatAdd(decFloat *result,
     /* safe because the lhs is non-zero]. */
     gap=-overlap;
     if (gap>DECPMAX) {
-      expr+=gap-1;
+      bexpr+=gap-1;
       gap=DECPMAX;
       }
     ub=ulsd+gap+1;                     /* where MSD will go */
     /* Fill the gap with 0s; note that there is no addition to do */
-    ui=&UINTAT(acc+COFF+DECPMAX);      /* start of gap */
-    for (; ui<&UINTAT(ub); ui++) *ui=0; /* mind the gap */
+    ut=acc+COFF+DECPMAX;               /* start of gap */
+    for (; ut<ub; ut+=4) UBFROMUI(ut, 0); /* mind the gap */
     if (overlap<-DECPMAX) {            /* gap was > DECPMAX */
       *ub=(uByte)(!DFISZERO(dfr));     /* make sticky digit */
       }
@@ -1294,63 +1384,74 @@ decFloat * decFloatAdd(decFloat *result,
    else {                              /* overlap>0 */
     /* coefficients overlap (perhaps completely, although also */
     /* perhaps only where zeros) */
-    ub=buf+COFF+DECPMAX-overlap;       /* where MSD will go */
-    /* Fill the prefix gap with 0s; 8 will cover most common */
-    /* unalignments, so start with direct assignments (a loop is */
-    /* then used for any remaining -- the loop (and the one in a */
-    /* moment) is not then on the critical path because the number */
-    /* of additions is reduced by (at least) two in this case) */
-    UINTAT(buf+4)=0;                   /* [clears decQuad 00 too] */
-    UINTAT(buf+8)=0;
-    if (ub>buf+12) {
-      ui=&UINTAT(buf+12);              /* start of any remaining */
-      for (; ui<&UINTAT(ub); ui++) *ui=0; /* fill them */
-      }
-    GETCOEFF(dfr, ub);                 /* decode from decFloat */
-
-    /* now move tail of rhs across to main acc; again use direct */
-    /* assignment for 8 digits-worth */
-    UINTAT(acc+COFF+DECPMAX)=UINTAT(buf+COFF+DECPMAX);
-    UINTAT(acc+COFF+DECPMAX+4)=UINTAT(buf+COFF+DECPMAX+4);
-    if (buf+COFF+DECPMAX+8<ub+DECPMAX) {
-      uj=&UINTAT(buf+COFF+DECPMAX+8);  /* source */
-      ui=&UINTAT(acc+COFF+DECPMAX+8);  /* target */
-      for (; uj<&UINTAT(ub+DECPMAX); ui++, uj++) *ui=*uj;
+    if (overlap==DECPMAX) {            /* aligned */
+      ub=buf+COFF;                     /* where msd will go */
+      #if QUAD
+      UBFROMUS(buf+4, 0);              /* clear quad's 00 */
+      #endif
+      GETCOEFF(dfr, ub);               /* decode from decFloat */
       }
+     else {                            /* unaligned */
+      ub=buf+COFF+DECPMAX-overlap;     /* where MSD will go */
+      /* Fill the prefix gap with 0s; 8 will cover most common */
+      /* unalignments, so start with direct assignments (a loop is */
+      /* then used for any remaining -- the loop (and the one in a */
+      /* moment) is not then on the critical path because the number */
+      /* of additions is reduced by (at least) two in this case) */
+      UBFROMUI(buf+4, 0);              /* [clears decQuad 00 too] */
+      UBFROMUI(buf+8, 0);
+      if (ub>buf+12) {
+       ut=buf+12;                      /* start any remaining */
+       for (; ut<ub; ut+=4) UBFROMUI(ut, 0); /* fill them */
+       }
+      GETCOEFF(dfr, ub);               /* decode from decFloat */
+
+      /* now move tail of rhs across to main acc; again use direct */
+      /* copies for 8 digits-worth */
+      UBFROMUI(acc+COFF+DECPMAX,   UBTOUI(buf+COFF+DECPMAX));
+      UBFROMUI(acc+COFF+DECPMAX+4, UBTOUI(buf+COFF+DECPMAX+4));
+      if (buf+COFF+DECPMAX+8<ub+DECPMAX) {
+       us=buf+COFF+DECPMAX+8;          /* source */
+       ut=acc+COFF+DECPMAX+8;          /* target */
+       for (; us<ub+DECPMAX; us+=4, ut+=4) UBFROMUI(ut, UBTOUI(us));
+       }
+      } /* unaligned */
 
     ulsd=acc+(ub-buf+DECPMAX-1);       /* update LSD pointer */
 
-    /* now do the add of the non-tail; this is all nicely aligned, */
+    /* Now do the add of the non-tail; this is all nicely aligned, */
     /* and is over a multiple of four digits (because for Quad two */
-    /* two 0 digits were added on the left); words in both acc and */
+    /* zero digits were added on the left); words in both acc and */
     /* buf (buf especially) will often be zero */
-    /* [byte-by-byte add, here, is about 15% slower than the by-fours] */
+    /* [byte-by-byte add, here, is about 15% slower total effect than */
+    /* the by-fours] */
 
     /* Now effect the add; this is harder on a little-endian */
     /* machine as the inter-digit carry cannot use the usual BCD */
     /* addition trick because the bytes are loaded in the wrong order */
     /* [this loop could be unrolled, but probably scarcely worth it] */
 
-    ui=&UINTAT(acc+COFF+DECPMAX-4);    /* target LSW (acc) */
-    uj=&UINTAT(buf+COFF+DECPMAX-4);    /* source LSW (buf, to add to acc) */
+    ut=acc+COFF+DECPMAX-4;             /* target LSW (acc) */
+    us=buf+COFF+DECPMAX-4;             /* source LSW (buf, to add to acc) */
 
     #if !DECLITEND
-    for (; ui>=&UINTAT(acc+4); ui--, uj--) {
+    for (; ut>=acc+4; ut-=4, us-=4) {  /* big-endian add loop */
       /* bcd8 add */
-      carry+=*uj;                      /* rhs + carry */
+      carry+=UBTOUI(us);               /* rhs + carry */
       if (carry==0) continue;          /* no-op */
-      carry+=*ui;                      /* lhs */
+      carry+=UBTOUI(ut);               /* lhs */
       /* Big-endian BCD adjust (uses internal carry) */
       carry+=0x76f6f6f6;               /* note top nibble not all bits */
-      *ui=(carry & 0x0f0f0f0f) - ((carry & 0x60606060)>>4); /* BCD adjust */
+      /* apply BCD adjust and save */
+      UBFROMUI(ut, (carry & 0x0f0f0f0f) - ((carry & 0x60606060)>>4));
       carry>>=31;                      /* true carry was at far left */
       } /* add loop */
     #else
-    for (; ui>=&UINTAT(acc+4); ui--, uj--) {
+    for (; ut>=acc+4; ut-=4, us-=4) {  /* little-endian add loop */
       /* bcd8 add */
-      carry+=*uj;                      /* rhs + carry */
+      carry+=UBTOUI(us);               /* rhs + carry */
       if (carry==0) continue;          /* no-op [common if unaligned] */
-      carry+=*ui;                      /* lhs */
+      carry+=UBTOUI(ut);               /* lhs */
       /* Little-endian BCD adjust; inter-digit carry must be manual */
       /* because the lsb from the array will be in the most-significant */
       /* byte of carry */
@@ -1359,12 +1460,13 @@ decFloat * decFloatAdd(decFloat *result,
       carry+=(carry & 0x00800000)>>15;
       carry+=(carry & 0x00008000)>>15;
       carry-=(carry & 0x60606060)>>4;  /* BCD adjust back */
-      *ui=carry & 0x0f0f0f0f;          /* clear debris and save */
+      UBFROMUI(ut, carry & 0x0f0f0f0f); /* clear debris and save */
       /* here, final carry-out bit is at 0x00000080; move it ready */
       /* for next word-add (i.e., to 0x01000000) */
       carry=(carry & 0x00000080)<<17;
       } /* add loop */
     #endif
+
     #if DECTRACE
     {bcdnum tum;
     printf("Add done, carry=%08lx, diffsign=%ld\n", (LI)carry, (LI)diffsign);
@@ -1392,36 +1494,36 @@ decFloat * decFloatAdd(decFloat *result,
       *(ulsd+1)=0;
       #endif
       /* there are always at least four coefficient words */
-      UINTAT(umsd)   =0x09090909-UINTAT(umsd);
-      UINTAT(umsd+4) =0x09090909-UINTAT(umsd+4);
-      UINTAT(umsd+8) =0x09090909-UINTAT(umsd+8);
-      UINTAT(umsd+12)=0x09090909-UINTAT(umsd+12);
+      UBFROMUI(umsd,   0x09090909-UBTOUI(umsd));
+      UBFROMUI(umsd+4, 0x09090909-UBTOUI(umsd+4));
+      UBFROMUI(umsd+8, 0x09090909-UBTOUI(umsd+8));
+      UBFROMUI(umsd+12, 0x09090909-UBTOUI(umsd+12));
       #if DOUBLE
        #define BNEXT 16
       #elif QUAD
-       UINTAT(umsd+16)=0x09090909-UINTAT(umsd+16);
-       UINTAT(umsd+20)=0x09090909-UINTAT(umsd+20);
-       UINTAT(umsd+24)=0x09090909-UINTAT(umsd+24);
-       UINTAT(umsd+28)=0x09090909-UINTAT(umsd+28);
-       UINTAT(umsd+32)=0x09090909-UINTAT(umsd+32);
+       UBFROMUI(umsd+16, 0x09090909-UBTOUI(umsd+16));
+       UBFROMUI(umsd+20, 0x09090909-UBTOUI(umsd+20));
+       UBFROMUI(umsd+24, 0x09090909-UBTOUI(umsd+24));
+       UBFROMUI(umsd+28, 0x09090909-UBTOUI(umsd+28));
+       UBFROMUI(umsd+32, 0x09090909-UBTOUI(umsd+32));
        #define BNEXT 36
       #endif
       if (ulsd>=umsd+BNEXT) {          /* unaligned */
        /* eight will handle most unaligments for Double; 16 for Quad */
-       UINTAT(umsd+BNEXT)=0x09090909-UINTAT(umsd+BNEXT);
-       UINTAT(umsd+BNEXT+4)=0x09090909-UINTAT(umsd+BNEXT+4);
+       UBFROMUI(umsd+BNEXT,   0x09090909-UBTOUI(umsd+BNEXT));
+       UBFROMUI(umsd+BNEXT+4, 0x09090909-UBTOUI(umsd+BNEXT+4));
        #if DOUBLE
        #define BNEXTY (BNEXT+8)
        #elif QUAD
-       UINTAT(umsd+BNEXT+8)=0x09090909-UINTAT(umsd+BNEXT+8);
-       UINTAT(umsd+BNEXT+12)=0x09090909-UINTAT(umsd+BNEXT+12);
+       UBFROMUI(umsd+BNEXT+8,  0x09090909-UBTOUI(umsd+BNEXT+8));
+       UBFROMUI(umsd+BNEXT+12, 0x09090909-UBTOUI(umsd+BNEXT+12));
        #define BNEXTY (BNEXT+16)
        #endif
        if (ulsd>=umsd+BNEXTY) {        /* very unaligned */
-         ui=&UINTAT(umsd+BNEXTY);      /* -> continue */
-         for (;;ui++) {
-           *ui=0x09090909-*ui;         /* invert four digits */
-           if (ui>=&UINTAT(ulsd-3)) break; /* all done */
+         ut=umsd+BNEXTY;               /* -> continue */
+         for (;;ut+=4) {
+           UBFROMUI(ut, 0x09090909-UBTOUI(ut)); /* invert four digits */
+           if (ut>=ulsd-3) break;      /* all done */
            }
          }
        }
@@ -1446,10 +1548,10 @@ decFloat * decFloatAdd(decFloat *result,
        umsd=acc+COFF+DECPMAX-1;   /* so far, so zero */
        if (ulsd>umsd) {           /* more to check */
          umsd++;                  /* to align after checked area */
-         for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4;
+         for (; UBTOUI(umsd)==0 && umsd+3<ulsd;) umsd+=4;
          for (; *umsd==0 && umsd<ulsd;) umsd++;
          }
-       if (*umsd==0) {            /* must be true zero (and diffsign) */
+       if (*umsd==0) {            /* must be true zero (and diffsign) */
          num.sign=0;              /* assume + */
          if (set->round==DEC_ROUND_FLOOR) num.sign=DECFLOAT_Sign;
          }
@@ -1468,9 +1570,9 @@ decFloat * decFloatAdd(decFloat *result,
     #endif
     } /* same sign */
 
-  num.msd=umsd;                           /* set MSD .. */
-  num.lsd=ulsd;                           /* .. and LSD */
-  num.exponent=expr;              /* set exponent to smaller */
+  num.msd=umsd;                   /* set MSD .. */
+  num.lsd=ulsd;                   /* .. and LSD */
+  num.exponent=bexpr-DECBIAS;     /* set exponent to smaller, unbiassed */
 
   #if DECTRACE
   decFloatShow(dfl, "dfl");
@@ -1484,12 +1586,12 @@ decFloat * decFloatAdd(decFloat *result,
 /* decFloatAnd -- logical digitwise AND of two decFloats             */
 /*                                                                   */
 /*   result gets the result of ANDing dfl and dfr                    */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result, which will be canonical with sign=0             */
 /*                                                                   */
-/* The operands must be positive, finite with exponent q=0, and              */
+/* The operands must be positive, finite with exponent q=0, and       */
 /* comprise just zeros and ones; if not, Invalid operation results.   */
 /* ------------------------------------------------------------------ */
 decFloat * decFloatAnd(decFloat *result,
@@ -1516,7 +1618,7 @@ decFloat * decFloatAnd(decFloat *result,
 /* decFloatCanonical -- copy a decFloat, making canonical            */
 /*                                                                   */
 /*   result gets the canonicalized df                                */
-/*   df            is the decFloat to copy and make canonical                */
+/*   df     is the decFloat to copy and make canonical               */
 /*   returns result                                                  */
 /*                                                                   */
 /* This works on specials, too; no error or exception is possible.    */
@@ -1528,7 +1630,7 @@ decFloat * decFloatCanonical(decFloat *result, const decFloat *df) {
 /* ------------------------------------------------------------------ */
 /* decFloatClass -- return the class of a decFloat                   */
 /*                                                                   */
-/*   df is the decFloat to test                                              */
+/*   df is the decFloat to test                                      */
 /*   returns the decClass that df falls into                         */
 /* ------------------------------------------------------------------ */
 enum decClass decFloatClass(const decFloat *df) {
@@ -1560,7 +1662,7 @@ enum decClass decFloatClass(const decFloat *df) {
 /* ------------------------------------------------------------------ */
 /* decFloatClassString -- return the class of a decFloat as a string  */
 /*                                                                   */
-/*   df is the decFloat to test                                              */
+/*   df is the decFloat to test                                      */
 /*   returns a constant string describing the class df falls into     */
 /* ------------------------------------------------------------------ */
 const char *decFloatClassString(const decFloat *df) {
@@ -1579,10 +1681,10 @@ const char *decFloatClassString(const decFloat *df) {
   } /* decFloatClassString */
 
 /* ------------------------------------------------------------------ */
-/* decFloatCompare -- compare two decFloats; quiet NaNs allowed              */
+/* decFloatCompare -- compare two decFloats; quiet NaNs allowed       */
 /*                                                                   */
 /*   result gets the result of comparing dfl and dfr                 */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result, which may be -1, 0, 1, or NaN (Unordered)       */
@@ -1606,7 +1708,7 @@ decFloat * decFloatCompare(decFloat *result,
 /* decFloatCompareSignal -- compare two decFloats; all NaNs signal    */
 /*                                                                   */
 /*   result gets the result of comparing dfl and dfr                 */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result, which may be -1, 0, 1, or NaN (Unordered)       */
@@ -1633,17 +1735,21 @@ decFloat * decFloatCompareSignal(decFloat *result,
 /* decFloatCompareTotal -- compare two decFloats with total ordering  */
 /*                                                                   */
 /*   result gets the result of comparing dfl and dfr                 */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   returns result, which may be -1, 0, or 1                        */
 /* ------------------------------------------------------------------ */
 decFloat * decFloatCompareTotal(decFloat *result,
                                const decFloat *dfl, const decFloat *dfr) {
-  Int comp;                                 /* work */
+  Int  comp;                                /* work */
+  uInt uiwork;                              /* for macros */
+  #if QUAD
+  uShort uswork;                            /* .. */
+  #endif
   if (DFISNAN(dfl) || DFISNAN(dfr)) {
     Int nanl, nanr;                         /* work */
     /* morph NaNs to +/- 1 or 2, leave numbers as 0 */
-    nanl=DFISSNAN(dfl)+DFISQNAN(dfl)*2;             /* quiet > signalling */
+    nanl=DFISSNAN(dfl)+DFISQNAN(dfl)*2;      /* quiet > signalling */
     if (DFISSIGNED(dfl)) nanl=-nanl;
     nanr=DFISSNAN(dfr)+DFISQNAN(dfr)*2;
     if (DFISSIGNED(dfr)) nanr=-nanr;
@@ -1654,23 +1760,22 @@ decFloat * decFloatCompareTotal(decFloat *result,
       uByte bufl[DECPMAX+4];                /* for LHS coefficient + foot */
       uByte bufr[DECPMAX+4];                /* for RHS coefficient + foot */
       uByte *ub, *uc;                       /* work */
-      Int sigl;                                     /* signum of LHS */
+      Int sigl;                             /* signum of LHS */
       sigl=(DFISSIGNED(dfl) ? -1 : +1);
 
       /* decode the coefficients */
       /* (shift both right two if Quad to make a multiple of four) */
       #if QUAD
-       ub = bufl;                           /* avoid type-pun violation */
-       USHORTAT(ub)=0;
-       uc = bufr;                           /* avoid type-pun violation */
-       USHORTAT(uc)=0;
+       UBFROMUS(bufl, 0);
+       UBFROMUS(bufr, 0);
       #endif
       GETCOEFF(dfl, bufl+QUAD*2);           /* decode from decFloat */
       GETCOEFF(dfr, bufr+QUAD*2);           /* .. */
       /* all multiples of four, here */
       comp=0;                               /* assume equal */
       for (ub=bufl, uc=bufr; ub<bufl+DECPMAX+QUAD*2; ub+=4, uc+=4) {
-       if (UINTAT(ub)==UINTAT(uc)) continue; /* so far so same */
+       uInt ui=UBTOUI(ub);
+       if (ui==UBTOUI(uc)) continue; /* so far so same */
        /* about to find a winner; go by bytes in case little-endian */
        for (;; ub++, uc++) {
          if (*ub==*uc) continue;
@@ -1696,7 +1801,7 @@ decFloat * decFloatCompareTotal(decFloat *result,
 /* decFloatCompareTotalMag -- compare magnitudes with total ordering  */
 /*                                                                   */
 /*   result gets the result of comparing abs(dfl) and abs(dfr)       */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   returns result, which may be -1, 0, or 1                        */
 /* ------------------------------------------------------------------ */
@@ -1747,7 +1852,7 @@ decFloat * decFloatCopyAbs(decFloat *result, const decFloat *dfl) {
 /* ------------------------------------------------------------------ */
 /* decFloatCopyNegate -- copy a decFloat as-is with inverted sign bit */
 /*                                                                   */
-/*   result gets the copy of dfl with sign bit inverted                      */
+/*   result gets the copy of dfl with sign bit inverted              */
 /*   dfl    is the decFloat to copy                                  */
 /*   returns result                                                  */
 /*                                                                   */
@@ -1760,10 +1865,10 @@ decFloat * decFloatCopyNegate(decFloat *result, const decFloat *dfl) {
   } /* decFloatCopyNegate */
 
 /* ------------------------------------------------------------------ */
-/* decFloatCopySign -- copy a decFloat with the sign of another              */
+/* decFloatCopySign -- copy a decFloat with the sign of another       */
 /*                                                                   */
-/*   result gets the result of copying dfl with the sign of dfr              */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   result gets the result of copying dfl with the sign of dfr       */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   returns result                                                  */
 /*                                                                   */
@@ -1795,7 +1900,7 @@ decFloat * decFloatCopySign(decFloat *result,
 /* next one is used when it is known that the declet must be */
 /* non-zero, or is the final zero declet */
 #define dpdlendun(n, form) {dpd=(form)&0x3ff;    \
-  if (dpd==0) return 1;                                  \
+  if (dpd==0) return 1;                          \
   return (DECPMAX-1-3*(n))-(3-DPD2BCD8[dpd*4+3]);}
 
 uInt decFloatDigits(const decFloat *df) {
@@ -1819,7 +1924,7 @@ uInt decFloatDigits(const decFloat *df) {
       } /* [cannot drop through] */
     sourlo=DFWORD(df, 1);  /* sourhi not involved now */
     if (sourlo&0xfff00000) {    /* in one of first two */
-      dpdlenchk(1, sourlo>>30);         /* very rare */
+      dpdlenchk(1, sourlo>>30);  /* very rare */
       dpdlendun(2, sourlo>>20);
       } /* [cannot drop through] */
     dpdlenchk(3, sourlo>>10);
@@ -1850,7 +1955,7 @@ uInt decFloatDigits(const decFloat *df) {
       } /* [cannot drop through] */
     sourlo=DFWORD(df, 3);
     if (sourlo&0xfff00000) {    /* in one of first two */
-      dpdlenchk(7, sourlo>>30);         /* very rare */
+      dpdlenchk(7, sourlo>>30);  /* very rare */
       dpdlendun(8, sourlo>>20);
       } /* [cannot drop through] */
     dpdlenchk(9, sourlo>>10);
@@ -1863,7 +1968,7 @@ uInt decFloatDigits(const decFloat *df) {
 /* decFloatDivide -- divide a decFloat by another                    */
 /*                                                                   */
 /*   result gets the result of dividing dfl by dfr:                  */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -1880,7 +1985,7 @@ decFloat * decFloatDivide(decFloat *result,
 /* decFloatDivideInteger -- integer divide a decFloat by another      */
 /*                                                                   */
 /*   result gets the result of dividing dfl by dfr:                  */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -1896,9 +2001,9 @@ decFloat * decFloatDivideInteger(decFloat *result,
 /* decFloatFMA -- multiply and add three decFloats, fused            */
 /*                                                                   */
 /*   result gets the result of (dfl*dfr)+dff with a single rounding   */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
-/*   dff    is the final decFloat (fhs)                                      */
+/*   dff    is the final decFloat (fhs)                              */
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
@@ -1906,21 +2011,23 @@ decFloat * decFloatDivideInteger(decFloat *result,
 decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
                       const decFloat *dfr, const decFloat *dff,
                       decContext *set) {
+
   /* The accumulator has the bytes needed for FiniteMultiply, plus */
   /* one byte to the left in case of carry, plus DECPMAX+2 to the */
   /* right for the final addition (up to full fhs + round & sticky) */
-  #define FMALEN (1+ (DECPMAX9*18) +DECPMAX+2)
-  uByte         acc[FMALEN];              /* for multiplied coefficient in BCD */
+  #define FMALEN (ROUNDUP4(1+ (DECPMAX9*18+1) +DECPMAX+2))
+  uByte  acc[FMALEN];             /* for multiplied coefficient in BCD */
                                   /* .. and for final result */
   bcdnum mul;                     /* for multiplication result */
   bcdnum fin;                     /* for final operand, expanded */
-  uByte         coe[DECPMAX];             /* dff coefficient in BCD */
+  uByte  coe[ROUNDUP4(DECPMAX)];   /* dff coefficient in BCD */
   bcdnum *hi, *lo;                /* bcdnum with higher/lower exponent */
   uInt  diffsign;                 /* non-zero if signs differ */
-  uInt  hipad;                    /* pad digit for hi if needed */
+  uInt  hipad;                    /* pad digit for hi if needed */
   Int   padding;                  /* excess exponent */
-  uInt  carry;                    /* +1 for ten's complement and during add */
-  uByte         *ub, *uh, *ul;            /* work */
+  uInt  carry;                    /* +1 for ten's complement and during add */
+  uByte  *ub, *uh, *ul;           /* work */
+  uInt  uiwork;                   /* for macros */
 
   /* handle all the special values [any special operand leads to a */
   /* special result] */
@@ -1971,8 +2078,8 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
   GETCOEFF(dff, coe);                  /* extract the coefficient */
 
   /* now set hi and lo so that hi points to whichever of mul and fin */
-  /* has the higher exponent and lo point to the other [don't care if */
-  /* the same] */
+  /* has the higher exponent and lo points to the other [don't care, */
+  /* if the same].  One coefficient will be in acc, the other in coe. */
   if (mul.exponent>=fin.exponent) {
     hi=&mul;
     lo=&fin;
@@ -1983,22 +2090,23 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
     }
 
   /* remove leading zeros on both operands; this will save time later */
-  /* and make testing for zero trivial */
-  for (; UINTAT(hi->msd)==0 && hi->msd+3<hi->lsd;) hi->msd+=4;
+  /* and make testing for zero trivial (tests are safe because acc */
+  /* and coe are rounded up to uInts) */
+  for (; UBTOUI(hi->msd)==0 && hi->msd+3<hi->lsd;) hi->msd+=4;
   for (; *hi->msd==0 && hi->msd<hi->lsd;) hi->msd++;
-  for (; UINTAT(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4;
+  for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4;
   for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++;
 
   /* if hi is zero then result will be lo (which has the smaller */
   /* exponent), which also may need to be tested for zero for the */
   /* weird IEEE 754 sign rules */
-  if (*hi->msd==0 && hi->msd==hi->lsd) {     /* hi is zero */
+  if (*hi->msd==0) {                        /* hi is zero */
     /* "When the sum of two operands with opposite signs is */
     /* exactly zero, the sign of that sum shall be '+' in all */
     /* rounding modes except round toward -Infinity, in which */
     /* mode that sign shall be '-'." */
     if (diffsign) {
-      if (*lo->msd==0 && lo->msd==lo->lsd) { /* lo is zero */
+      if (*lo->msd==0) {                    /* lo is zero */
        lo->sign=0;
        if (set->round==DEC_ROUND_FLOOR) lo->sign=DECFLOAT_Sign;
        } /* diffsign && lo=0 */
@@ -2006,10 +2114,11 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
     return decFinalize(result, lo, set);     /* may need clamping */
     } /* numfl is zero */
   /* [here, both are minimal length and hi is non-zero] */
+  /* (if lo is zero then padding with zeros may be needed, below) */
 
   /* if signs differ, take the ten's complement of hi (zeros to the */
-  /* right do not matter because the complement of zero is zero); */
-  /* the +1 is done later, as part of the addition, inserted at the */
+  /* right do not matter because the complement of zero is zero); the */
+  /* +1 is done later, as part of the addition, inserted at the */
   /* correct digit */
   hipad=0;
   carry=0;
@@ -2017,7 +2126,7 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
     hipad=9;
     carry=1;
     /* exactly the correct number of digits must be inverted */
-    for (uh=hi->msd; uh<hi->lsd-3; uh+=4) UINTAT(uh)=0x09090909-UINTAT(uh);
+    for (uh=hi->msd; uh<hi->lsd-3; uh+=4) UBFROMUI(uh, 0x09090909-UBTOUI(uh));
     for (; uh<=hi->lsd; uh++) *uh=(uByte)(0x09-*uh);
     }
 
@@ -2032,7 +2141,8 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
   /* printf("FMA pad %ld\n", (LI)padding); */
 
   /* the result of the addition will be built into the accumulator, */
-  /* starting from the far right; this could be either hi or lo */
+  /* starting from the far right; this could be either hi or lo, and */
+  /* will be aligned */
   ub=acc+FMALEN-1;                /* where lsd of result will go */
   ul=lo->lsd;                     /* lsd of rhs */
 
@@ -2042,45 +2152,43 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
     /* digit at the right place, as it stays clear of hi digits */
     /* [it must be DECPMAX+2 because during a subtraction the msd */
     /* could become 0 after a borrow from 1.000 to 0.9999...] */
-    Int hilen=(Int)(hi->lsd-hi->msd+1); /* lengths */
-    Int lolen=(Int)(lo->lsd-lo->msd+1); /* .. */
-    Int newexp=MINI(hi->exponent, hi->exponent+hilen-DECPMAX)-3;
-    Int reduce=newexp-lo->exponent;
-    if (reduce>0) {                    /* [= case gives reduce=0 nop] */
+
+    Int hilen=(Int)(hi->lsd-hi->msd+1); /* length of hi */
+    Int lolen=(Int)(lo->lsd-lo->msd+1); /* and of lo */
+
+    if (hilen+padding-lolen > DECPMAX+2) {   /* can reduce lo to single */
+      /* make sure it is virtually at least DECPMAX from hi->msd, at */
+      /* least to right of hi->lsd (in case of destructive subtract), */
+      /* and separated by at least two digits from either of those */
+      /* (the tricky DOUBLE case is when hi is a 1 that will become a */
+      /* 0.9999... by subtraction: */
+      /*   hi:  1                                   E+16 */
+      /*   lo:   .................1000000000000000  E-16 */
+      /* which for the addition pads to: */
+      /*   hi:  1000000000000000000                 E-16 */
+      /*   lo:   .................1000000000000000  E-16 */
+      Int newexp=MINI(hi->exponent, hi->exponent+hilen-DECPMAX)-3;
+
       /* printf("FMA reduce: %ld\n", (LI)reduce); */
-      if (reduce>=lolen) {             /* eating all */
-       lo->lsd=lo->msd;                /* reduce to single digit */
-       lo->exponent=newexp;            /* [known to be non-zero] */
-       }
-       else { /* < */
-       uByte *up=lo->lsd;
-       lo->lsd=lo->lsd-reduce;
-       if (*lo->lsd==0)                /* could need sticky bit */
-        for (; up>lo->lsd; up--) {     /* search discarded digits */
-         if (*up!=0) {                 /* found one... */
-           *lo->lsd=1;                 /* set sticky bit */
-           break;
-           }
-         }
-       lo->exponent+=reduce;
-       }
-      padding=hi->exponent-lo->exponent; /* recalculate */
-      ul=lo->lsd;                       /* .. */
-      } /* maybe reduce */
-    /* padding is now <= DECPMAX+2 but still > 0; tricky DOUBLE case */
-    /* is when hi is a 1 that will become a 0.9999... by subtraction: */
-    /*  hi:   1                                   E+16 */
-    /*  lo:    .................1000000000000000  E-16 */
-    /* which for the addition pads and reduces to: */
-    /*  hi:   1000000000000000000                 E-2 */
-    /*  lo:    .................1                 E-2 */
+      lo->lsd=lo->msd;                      /* to single digit [maybe 0] */
+      lo->exponent=newexp;                  /* new lowest exponent */
+      padding=hi->exponent-lo->exponent;     /* recalculate */
+      ul=lo->lsd;                           /* .. and repoint */
+      }
+
+    /* padding is still > 0, but will fit in acc (less leading carry slot) */
     #if DECCHECK
-      if (padding>DECPMAX+2) printf("FMA excess padding: %ld\n", (LI)padding);
       if (padding<=0) printf("FMA low padding: %ld\n", (LI)padding);
+      if (hilen+padding+1>FMALEN)
+       printf("FMA excess hilen+padding: %ld+%ld \n", (LI)hilen, (LI)padding);
       /* printf("FMA padding: %ld\n", (LI)padding); */
     #endif
+
     /* padding digits can now be set in the result; one or more of */
     /* these will come from lo; others will be zeros in the gap */
+    for (; ul-3>=lo->msd && padding>3; padding-=4, ul-=4, ub-=4) {
+      UBFROMUI(ub-3, UBTOUI(ul-3));         /* [cannot overlap] */
+      }
     for (; ul>=lo->msd && padding>0; padding--, ul--, ub--) *ub=*ul;
     for (;padding>0; padding--, ub--) *ub=0; /* mind the gap */
     }
@@ -2088,23 +2196,39 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
   /* addition now complete to the right of the rightmost digit of hi */
   uh=hi->lsd;
 
-  /* carry was set up depending on ten's complement above; do the add... */
+  /* dow do the add from hi->lsd to the left */
+  /* [bytewise, because either operand can run out at any time] */
+  /* carry was set up depending on ten's complement above */
+  /* first assume both operands have some digits */
   for (;; ub--) {
-    uInt hid, lod;
-    if (uh<hi->msd) {
+    if (uh<hi->msd || ul<lo->msd) break;
+    *ub=(uByte)(carry+(*uh--)+(*ul--));
+    carry=0;
+    if (*ub<10) continue;
+    *ub-=10;
+    carry=1;
+    } /* both loop */
+
+  if (ul<lo->msd) {          /* to left of lo */
+    for (;; ub--) {
+      if (uh<hi->msd) break;
+      *ub=(uByte)(carry+(*uh--));  /* [+0] */
+      carry=0;
+      if (*ub<10) continue;
+      *ub-=10;
+      carry=1;
+      } /* hi loop */
+    }
+   else {                    /* to left of hi */
+    for (;; ub--) {
       if (ul<lo->msd) break;
-      hid=hipad;
-      }
-     else hid=*uh--;
-    if (ul<lo->msd) lod=0;
-     else lod=*ul--;
-    *ub=(uByte)(carry+hid+lod);
-    if (*ub<10) carry=0;
-     else {
+      *ub=(uByte)(carry+hipad+(*ul--));
+      carry=0;
+      if (*ub<10) continue;
       *ub-=10;
       carry=1;
-      }
-    } /* addition loop */
+      } /* lo loop */
+    }
 
   /* addition complete -- now handle carry, borrow, etc. */
   /* use lo to set up the num (its exponent is already correct, and */
@@ -2122,7 +2246,7 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
     if (!carry) {                 /* no carry out means hi<lo */
       /* borrowed -- take ten's complement of the right digits */
       lo->sign=hi->sign;          /* sign is lhs sign */
-      for (ul=lo->msd; ul<lo->lsd-3; ul+=4) UINTAT(ul)=0x09090909-UINTAT(ul);
+      for (ul=lo->msd; ul<lo->lsd-3; ul+=4) UBFROMUI(ul, 0x09090909-UBTOUI(ul));
       for (; ul<=lo->lsd; ul++) *ul=(uByte)(0x09-*ul); /* [leaves ul at lsd+1] */
       /* complete the ten's complement by adding 1 [cannot overrun] */
       for (ul--; *ul==9; ul--) *ul=0;
@@ -2133,7 +2257,7 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
       /* all done except for the special IEEE 754 exact-zero-result */
       /* rule (see above); while testing for zero, strip leading */
       /* zeros (which will save decFinalize doing it) */
-      for (; UINTAT(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4;
+      for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4;
       for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++;
       if (*lo->msd==0) {          /* must be true zero (and diffsign) */
        lo->sign=0;                /* assume + */
@@ -2143,11 +2267,18 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
       } /* subtraction gave positive result */
     } /* diffsign */
 
+  #if DECCHECK
+  /* assert no left underrun */
+  if (lo->msd<acc) {
+    printf("FMA underrun by %ld \n", (LI)(acc-lo->msd));
+    }
+  #endif
+
   return decFinalize(result, lo, set); /* round, check, and lay out */
   } /* decFloatFMA */
 
 /* ------------------------------------------------------------------ */
-/* decFloatFromInt -- initialise a decFloat from an Int                      */
+/* decFloatFromInt -- initialise a decFloat from an Int              */
 /*                                                                   */
 /*   result gets the converted Int                                   */
 /*   n     is the Int to convert                                     */
@@ -2213,7 +2344,7 @@ decFloat * decFloatFromUInt32(decFloat *result, uInt u) {
 /* decFloatInvert -- logical digitwise INVERT of a decFloat          */
 /*                                                                   */
 /*   result gets the result of INVERTing df                          */
-/*   df            is the decFloat to invert                                 */
+/*   df     is the decFloat to invert                                */
 /*   set    is the context                                           */
 /*   returns result, which will be canonical with sign=0             */
 /*                                                                   */
@@ -2241,12 +2372,12 @@ decFloat * decFloatInvert(decFloat *result, const decFloat *df,
 /* ------------------------------------------------------------------ */
 /* decFloatIs -- decFloat tests (IsSigned, etc.)                     */
 /*                                                                   */
-/*   df is the decFloat to test                                              */
-/*   returns 0 or 1 in an int32_t                                    */
+/*   df is the decFloat to test                                      */
+/*   returns 0 or 1 in a uInt                                        */
 /*                                                                   */
 /* Many of these could be macros, but having them as real functions   */
-/* is a bit cleaner (and they can be referred to here by the generic  */
-/* names)                                                            */
+/* is a little cleaner (and they can be referred to here by the       */
+/* generic names)                                                    */
 /* ------------------------------------------------------------------ */
 uInt decFloatIsCanonical(const decFloat *df) {
   if (DFISSPECIAL(df)) {
@@ -2333,10 +2464,10 @@ uInt decFloatIsZero(const decFloat *df) {
   } /* decFloatIs... */
 
 /* ------------------------------------------------------------------ */
-/* decFloatLogB -- return adjusted exponent, by 754r rules           */
+/* decFloatLogB -- return adjusted exponent, by 754 rules            */
 /*                                                                   */
 /*   result gets the adjusted exponent as an integer, or a NaN etc.   */
-/*   df            is the decFloat to be examined                            */
+/*   df     is the decFloat to be examined                           */
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
@@ -2353,12 +2484,12 @@ decFloat * decFloatLogB(decFloat *result, const decFloat *df,
   if (DFISNAN(df)) return decNaNs(result, df, NULL, set);
   if (DFISINF(df)) {
     DFWORD(result, 0)=0;                    /* need +ve */
-    return decInfinity(result, result);             /* canonical +Infinity */
+    return decInfinity(result, result);      /* canonical +Infinity */
     }
   if (DFISZERO(df)) {
-    set->status|=DEC_Division_by_zero;      /* as per 754r */
+    set->status|=DEC_Division_by_zero;      /* as per 754 */
     DFWORD(result, 0)=DECFLOAT_Sign;        /* make negative */
-    return decInfinity(result, result);             /* canonical -Infinity */
+    return decInfinity(result, result);      /* canonical -Infinity */
     }
   ae=GETEXPUN(df)                      /* get unbiased exponent .. */
     +decFloatDigits(df)-1;             /* .. and make adjusted exponent */
@@ -2381,10 +2512,10 @@ decFloat * decFloatLogB(decFloat *result, const decFloat *df,
   } /* decFloatLogB */
 
 /* ------------------------------------------------------------------ */
-/* decFloatMax -- return maxnum of two operands                              */
+/* decFloatMax -- return maxnum of two operands                      */
 /*                                                                   */
 /*   result gets the chosen decFloat                                 */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -2416,7 +2547,7 @@ decFloat * decFloatMax(decFloat *result,
 /* decFloatMaxMag -- return maxnummag of two operands                */
 /*                                                                   */
 /*   result gets the chosen decFloat                                 */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -2440,10 +2571,10 @@ decFloat * decFloatMaxMag(decFloat *result,
   } /* decFloatMaxMag */
 
 /* ------------------------------------------------------------------ */
-/* decFloatMin -- return minnum of two operands                              */
+/* decFloatMin -- return minnum of two operands                      */
 /*                                                                   */
 /*   result gets the chosen decFloat                                 */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -2475,7 +2606,7 @@ decFloat * decFloatMin(decFloat *result,
 /* decFloatMinMag -- return minnummag of two operands                */
 /*                                                                   */
 /*   result gets the chosen decFloat                                 */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -2501,8 +2632,8 @@ decFloat * decFloatMinMag(decFloat *result,
 /* ------------------------------------------------------------------ */
 /* decFloatMinus -- negate value, heeding NaNs, etc.                 */
 /*                                                                   */
-/*   result gets the canonicalized 0-df                                      */
-/*   df            is the decFloat to minus                                  */
+/*   result gets the canonicalized 0-df                              */
+/*   df     is the decFloat to minus                                 */
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
@@ -2524,8 +2655,8 @@ decFloat * decFloatMinus(decFloat *result, const decFloat *df,
 /* ------------------------------------------------------------------ */
 /* decFloatMultiply -- multiply two decFloats                        */
 /*                                                                   */
-/*   result gets the result of multiplying dfl and dfr:                      */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   result gets the result of multiplying dfl and dfr:              */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -2535,7 +2666,7 @@ decFloat * decFloatMultiply(decFloat *result,
                            const decFloat *dfl, const decFloat *dfr,
                            decContext *set) {
   bcdnum num;                     /* for final conversion */
-  uByte         bcdacc[DECPMAX9*18+1];    /* for coefficent in BCD */
+  uByte  bcdacc[DECPMAX9*18+1];    /* for coefficent in BCD */
 
   if (DFISSPECIAL(dfl) || DFISSPECIAL(dfr)) { /* either is special? */
     /* NaNs are handled as usual */
@@ -2561,7 +2692,7 @@ decFloat * decFloatMultiply(decFloat *result,
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
-/* This is 754r nextdown; Invalid is the only status possible (from   */
+/* This is 754 nextdown; Invalid is the only status possible (from    */
 /* an sNaN).                                                         */
 /* ------------------------------------------------------------------ */
 decFloat * decFloatNextMinus(decFloat *result, const decFloat *dfl,
@@ -2580,19 +2711,19 @@ decFloat * decFloatNextMinus(decFloat *result, const decFloat *dfl,
   /* here (but can be done with normal add if the sign of zero is */
   /* treated carefully, because no Inexactitude is interesting); */
   /* rounding to -Infinity then pushes the result to next below */
-  decFloatZero(&delta);                        /* set up tiny delta */
-  DFWORD(&delta, DECWORDS-1)=1;                /* coefficient=1 */
+  decFloatZero(&delta);                /* set up tiny delta */
+  DFWORD(&delta, DECWORDS-1)=1;        /* coefficient=1 */
   DFWORD(&delta, 0)=DECFLOAT_Sign;     /* Sign=1 + biased exponent=0 */
   /* set up for the directional round */
-  saveround=set->round;                        /* save mode */
+  saveround=set->round;                /* save mode */
   set->round=DEC_ROUND_FLOOR;          /* .. round towards -Infinity */
-  savestat=set->status;                        /* save status */
+  savestat=set->status;                /* save status */
   decFloatAdd(result, dfl, &delta, set);
   /* Add rules mess up the sign when going from +Ntiny to 0 */
   if (DFISZERO(result)) DFWORD(result, 0)^=DECFLOAT_Sign; /* correct */
   set->status&=DEC_Invalid_operation;  /* preserve only sNaN status */
   set->status|=savestat;               /* restore pending flags */
-  set->round=saveround;                        /* .. and mode */
+  set->round=saveround;                /* .. and mode */
   return result;
   } /* decFloatNextMinus */
 
@@ -2604,7 +2735,7 @@ decFloat * decFloatNextMinus(decFloat *result, const decFloat *dfl,
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
-/* This is 754r nextup; Invalid is the only status possible (from     */
+/* This is 754 nextup; Invalid is the only status possible (from      */
 /* an sNaN).                                                         */
 /* ------------------------------------------------------------------ */
 decFloat * decFloatNextPlus(decFloat *result, const decFloat *dfl,
@@ -2624,19 +2755,19 @@ decFloat * decFloatNextPlus(decFloat *result, const decFloat *dfl,
   /* here (but can be done with normal add if the sign of zero is */
   /* treated carefully, because no Inexactitude is interesting); */
   /* rounding to +Infinity then pushes the result to next above */
-  decFloatZero(&delta);                        /* set up tiny delta */
-  DFWORD(&delta, DECWORDS-1)=1;                /* coefficient=1 */
+  decFloatZero(&delta);                /* set up tiny delta */
+  DFWORD(&delta, DECWORDS-1)=1;        /* coefficient=1 */
   DFWORD(&delta, 0)=0;                 /* Sign=0 + biased exponent=0 */
   /* set up for the directional round */
-  saveround=set->round;                        /* save mode */
-  set->round=DEC_ROUND_CEILING;                /* .. round towards +Infinity */
-  savestat=set->status;                        /* save status */
+  saveround=set->round;                /* save mode */
+  set->round=DEC_ROUND_CEILING;        /* .. round towards +Infinity */
+  savestat=set->status;                /* save status */
   decFloatAdd(result, dfl, &delta, set);
   /* Add rules mess up the sign when going from -Ntiny to -0 */
   if (DFISZERO(result)) DFWORD(result, 0)^=DECFLOAT_Sign; /* correct */
   set->status&=DEC_Invalid_operation;  /* preserve only sNaN status */
   set->status|=savestat;               /* restore pending flags */
-  set->round=saveround;                        /* .. and mode */
+  set->round=saveround;                /* .. and mode */
   return result;
   } /* decFloatNextPlus */
 
@@ -2649,8 +2780,9 @@ decFloat * decFloatNextPlus(decFloat *result, const decFloat *dfl,
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
-/* This is 754r nextafter; status may be set unless the result is a   */
-/* normal number.                                                    */
+/* This is 754-1985 nextafter, as modified during revision (dropped   */
+/* from 754-2008); status may be set unless the result is a normal    */
+/* number.                                                           */
 /* ------------------------------------------------------------------ */
 decFloat * decFloatNextToward(decFloat *result,
                              const decFloat *dfl, const decFloat *dfr,
@@ -2676,7 +2808,7 @@ decFloat * decFloatNextToward(decFloat *result,
       }
     saveround=set->round;                   /* save mode */
     set->round=DEC_ROUND_CEILING;           /* .. round towards +Infinity */
-    deltatop=0;                                     /* positive delta */
+    deltatop=0;                             /* positive delta */
     }
    else { /* lhs>rhs, do NextMinus, see above for commentary */
     if (DFISINF(dfl) && !DFISSIGNED(dfl)) {  /* +Infinity special case */
@@ -2684,23 +2816,23 @@ decFloat * decFloatNextToward(decFloat *result,
       return result;
       }
     saveround=set->round;                   /* save mode */
-    set->round=DEC_ROUND_FLOOR;                     /* .. round towards -Infinity */
+    set->round=DEC_ROUND_FLOOR;             /* .. round towards -Infinity */
     deltatop=DECFLOAT_Sign;                 /* negative delta */
     }
-  savestat=set->status;                             /* save status */
+  savestat=set->status;                     /* save status */
   /* Here, Inexact is needed where appropriate (and hence Underflow, */
   /* etc.).  Therefore the tiny delta which is otherwise */
   /* unrepresentable (see NextPlus and NextMinus) is constructed */
   /* using the multiplication of FMA. */
-  decFloatZero(&delta);                        /* set up tiny delta */
-  DFWORD(&delta, DECWORDS-1)=1;                /* coefficient=1 */
+  decFloatZero(&delta);                /* set up tiny delta */
+  DFWORD(&delta, DECWORDS-1)=1;        /* coefficient=1 */
   DFWORD(&delta, 0)=deltatop;          /* Sign + biased exponent=0 */
   decFloatFromString(&pointone, "1E-1", set); /* set up multiplier */
   decFloatFMA(result, &delta, &pointone, dfl, set);
   /* [Delta is truly tiny, so no need to correct sign of zero] */
   /* use new status unless the result is normal */
   if (decFloatIsNormal(result)) set->status=savestat; /* else goes forward */
-  set->round=saveround;                        /* restore mode */
+  set->round=saveround;                /* restore mode */
   return result;
   } /* decFloatNextToward */
 
@@ -2708,12 +2840,12 @@ decFloat * decFloatNextToward(decFloat *result,
 /* decFloatOr -- logical digitwise OR of two decFloats               */
 /*                                                                   */
 /*   result gets the result of ORing dfl and dfr                     */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result, which will be canonical with sign=0             */
 /*                                                                   */
-/* The operands must be positive, finite with exponent q=0, and              */
+/* The operands must be positive, finite with exponent q=0, and       */
 /* comprise just zeros and ones; if not, Invalid operation results.   */
 /* ------------------------------------------------------------------ */
 decFloat * decFloatOr(decFloat *result,
@@ -2739,14 +2871,14 @@ decFloat * decFloatOr(decFloat *result,
 /* ------------------------------------------------------------------ */
 /* decFloatPlus -- add value to 0, heeding NaNs, etc.                */
 /*                                                                   */
-/*   result gets the canonicalized 0+df                                      */
-/*   df            is the decFloat to plus                                   */
+/*   result gets the canonicalized 0+df                              */
+/*   df     is the decFloat to plus                                  */
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
 /* This has the same effect as 0+df where the exponent of the zero is */
 /* the same as that of df (if df is finite).                         */
-/* The effect is also the same as decFloatCopy except that NaNs              */
+/* The effect is also the same as decFloatCopy except that NaNs       */
 /* are handled normally (the sign of a NaN is not affected, and an    */
 /* sNaN will signal), the result is canonical, and zero gets sign 0.  */
 /* ------------------------------------------------------------------ */
@@ -2762,7 +2894,7 @@ decFloat * decFloatPlus(decFloat *result, const decFloat *df,
 /* decFloatQuantize -- quantize a decFloat                           */
 /*                                                                   */
 /*   result gets the result of quantizing dfl to match dfr           */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs), which sets the exponent     */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -2775,16 +2907,19 @@ decFloat * decFloatQuantize(decFloat *result,
                            decContext *set) {
   Int  explb, exprb;         /* left and right biased exponents */
   uByte *ulsd;               /* local LSD pointer */
-  uInt *ui;                  /* work */
-  uByte *ub;                 /* .. */
+  uByte *ub, *uc;            /* work */
   Int  drop;                 /* .. */
   uInt dpd;                  /* .. */
-  uInt encode;               /* encoding accumulator */
+  uInt encode;               /* encoding accumulator */
   uInt sourhil, sourhir;     /* top words from source decFloats */
+  uInt uiwork;               /* for macros */
+  #if QUAD
+  uShort uswork;             /* .. */
+  #endif
   /* the following buffer holds the coefficient for manipulation */
-  uByte buf[4+DECPMAX*3];     /* + space for zeros to left or right */
+  uByte buf[4+DECPMAX*3+2*QUAD];   /* + space for zeros to left or right */
   #if DECTRACE
-  bcdnum num;                /* for trace displays */
+  bcdnum num;                     /* for trace displays */
   #endif
 
   /* Start decoding the arguments */
@@ -2827,7 +2962,7 @@ decFloat * decFloatQuantize(decFloat *result,
   decShowNum(&num, "dfl");
   #endif
 
-  if (drop>0) {                                /* [most common case] */
+  if (drop>0) {                        /* [most common case] */
     /* (this code is very similar to that in decFloatFinalize, but */
     /* has many differences so is duplicated here -- so any changes */
     /* may need to be made there, too) */
@@ -2838,7 +2973,7 @@ decFloat * decFloatQuantize(decFloat *result,
     /* there is at least one zero needed to the left, in all but one */
     /* exceptional (all-nines) case, so place four zeros now; this is */
     /* needed almost always and makes rounding all-nines by fours safe */
-    UINTAT(BUFOFF-4)=0;
+    UBFROMUI(BUFOFF-4, 0);
 
     /* Three cases here: */
     /*  1. new LSD is in coefficient (almost always) */
@@ -2849,7 +2984,7 @@ decFloat * decFloatQuantize(decFloat *result,
 
     /* [duplicate check-stickies code to save a test] */
     /* [by-digit check for stickies as runs of zeros are rare] */
-    if (drop<DECPMAX) {                             /* NB lengths not addresses */
+    if (drop<DECPMAX) {                     /* NB lengths not addresses */
       roundat=BUFOFF+DECPMAX-drop;
       reround=*roundat;
       for (ub=roundat+1; ub<BUFOFF+DECPMAX; ub++) {
@@ -2932,7 +3067,7 @@ decFloat * decFloatQuantize(decFloat *result,
        /* increment the coefficient; this could give 1000... (after */
        /* the all nines case) */
        ub=ulsd;
-       for (; UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0;
+       for (; UBTOUI(ub-3)==0x09090909; ub-=4) UBFROMUI(ub-3, 0);
        /* now at most 3 digits left to non-9 (usually just the one) */
        for (; *ub==9; ub--) *ub=0;
        *ub+=1;
@@ -2945,8 +3080,8 @@ decFloat * decFloatQuantize(decFloat *result,
     /* available in the coefficent -- the first word to the left was */
     /* cleared earlier for safe carry; now add any more needed */
     if (drop>4) {
-      UINTAT(BUFOFF-8)=0;                   /* must be at least 5 */
-      for (ui=&UINTAT(BUFOFF-12); ui>&UINTAT(ulsd-DECPMAX-3); ui--) *ui=0;
+      UBFROMUI(BUFOFF-8, 0);                /* must be at least 5 */
+      for (uc=BUFOFF-12; uc>ulsd-DECPMAX-3; uc-=4) UBFROMUI(uc, 0);
       }
     } /* need round (drop>0) */
 
@@ -2967,18 +3102,21 @@ decFloat * decFloatQuantize(decFloat *result,
       #else
       static const uInt dmask[]={0, 0xff000000, 0xffff0000, 0xffffff00};
       #endif
-      for (ui=&UINTAT(BUFOFF+DECPMAX);; ui++) {
-       *ui=0;
-       if (UINTAT(&UBYTEAT(ui)-DECPMAX)!=0) { /* could be bad */
+      /* note that here zeros to the right are added by fours, so in */
+      /* the Quad case this could write 36 zeros if the coefficient has */
+      /* fewer than three significant digits (hence the +2*QUAD for buf) */
+      for (uc=BUFOFF+DECPMAX;; uc+=4) {
+       UBFROMUI(uc, 0);
+       if (UBTOUI(uc-DECPMAX)!=0) {              /* could be bad */
          /* if all four digits should be zero, definitely bad */
-         if (ui<=&UINTAT(BUFOFF+DECPMAX+(-drop)-4))
+         if (uc<=BUFOFF+DECPMAX+(-drop)-4)
            return decInvalid(result, set);
          /* must be a 1- to 3-digit sequence; check more carefully */
-         if ((UINTAT(&UBYTEAT(ui)-DECPMAX)&dmask[(-drop)%4])!=0)
+         if ((UBTOUI(uc-DECPMAX)&dmask[(-drop)%4])!=0)
            return decInvalid(result, set);
          break;    /* no need for loop end test */
          }
-       if (ui>=&UINTAT(BUFOFF+DECPMAX+(-drop)-4)) break; /* done */
+       if (uc>=BUFOFF+DECPMAX+(-drop)-4) break;  /* done */
        }
       ulsd=BUFOFF+DECPMAX+(-drop)-1;
       } /* pad and check leading zeros */
@@ -3045,7 +3183,7 @@ decFloat * decFloatQuantize(decFloat *result,
 /* decFloatReduce -- reduce finite coefficient to minimum length      */
 /*                                                                   */
 /*   result gets the reduced decFloat                                */
-/*   df            is the source decFloat                                    */
+/*   df     is the source decFloat                                   */
 /*   set    is the context                                           */
 /*   returns result, which will be canonical                         */
 /*                                                                   */
@@ -3085,7 +3223,7 @@ decFloat * decFloatReduce(decFloat *result, const decFloat *df,
 /* decFloatRemainder -- integer divide and return remainder          */
 /*                                                                   */
 /*   result gets the remainder of dividing dfl by dfr:               */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -3101,7 +3239,7 @@ decFloat * decFloatRemainder(decFloat *result,
 /* decFloatRemainderNear -- integer divide to nearest and remainder   */
 /*                                                                   */
 /*   result gets the remainder of dividing dfl by dfr:               */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -3145,7 +3283,7 @@ decFloat * decFloatRotate(decFloat *result,
   if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set);
   if (!DFISINT(dfr)) return decInvalid(result, set);
   digits=decFloatDigits(dfr);                   /* calculate digits */
-  if (digits>2) return decInvalid(result, set);         /* definitely out of range */
+  if (digits>2) return decInvalid(result, set);  /* definitely out of range */
   rotate=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff]; /* is in bottom declet */
   if (rotate>DECPMAX) return decInvalid(result, set); /* too big */
   /* [from here on no error or status change is possible] */
@@ -3178,16 +3316,16 @@ decFloat * decFloatRotate(decFloat *result,
   num.lsd=num.msd+DECPMAX-1;
   num.sign=DFWORD(dfl, 0)&DECFLOAT_Sign;
   num.exponent=GETEXPUN(dfl);
-  savestat=set->status;                        /* record */
+  savestat=set->status;                /* record */
   decFinalize(result, &num, set);
-  set->status=savestat;                        /* restore */
+  set->status=savestat;                /* restore */
   return result;
   } /* decFloatRotate */
 
 /* ------------------------------------------------------------------ */
 /* decFloatSameQuantum -- test decFloats for same quantum            */
 /*                                                                   */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   returns 1 if the operands have the same quantum, 0 otherwise     */
 /*                                                                   */
@@ -3204,11 +3342,11 @@ uInt decFloatSameQuantum(const decFloat *dfl, const decFloat *dfr) {
   } /* decFloatSameQuantum */
 
 /* ------------------------------------------------------------------ */
-/* decFloatScaleB -- multiply by a power of 10, as per 754r          */
+/* decFloatScaleB -- multiply by a power of 10, as per 754           */
 /*                                                                   */
 /*   result gets the result of the operation                         */
-/*   dfl    is the first decFloat (lhs)                                      */
-/*   dfr    is the second decFloat (rhs), am integer (with q=0)              */
+/*   dfl    is the first decFloat (lhs)                              */
+/*   dfr    is the second decFloat (rhs), am integer (with q=0)       */
 /*   set    is the context                                           */
 /*   returns result                                                  */
 /*                                                                   */
@@ -3229,10 +3367,10 @@ decFloat * decFloatScaleB(decFloat *result,
   digits=decFloatDigits(dfr);               /* calculate digits */
 
   #if DOUBLE
-  if (digits>3) return decInvalid(result, set);          /* definitely out of range */
+  if (digits>3) return decInvalid(result, set);   /* definitely out of range */
   expr=DPD2BIN[DFWORD(dfr, 1)&0x3ff];            /* must be in bottom declet */
   #elif QUAD
-  if (digits>5) return decInvalid(result, set);          /* definitely out of range */
+  if (digits>5) return decInvalid(result, set);   /* definitely out of range */
   expr=DPD2BIN[DFWORD(dfr, 3)&0x3ff]             /* in bottom 2 declets .. */
       +DPD2BIN[(DFWORD(dfr, 3)>>10)&0x3ff]*1000;  /* .. */
   #endif
@@ -3241,7 +3379,7 @@ decFloat * decFloatScaleB(decFloat *result,
   if (DFISINF(dfl)) return decInfinity(result, dfl);   /* canonical */
   if (DFISSIGNED(dfr)) expr=-expr;
   /* dfl is finite and expr is valid */
-  *result=*dfl;                                     /* copy to target */
+  *result=*dfl;                             /* copy to target */
   return decFloatSetExponent(result, set, GETEXPUN(result)+expr);
   } /* decFloatScaleB */
 
@@ -3266,23 +3404,24 @@ decFloat * decFloatScaleB(decFloat *result,
 decFloat * decFloatShift(decFloat *result,
                         const decFloat *dfl, const decFloat *dfr,
                         decContext *set) {
-  Int shift;                           /* dfr as an Int */
-  uByte buf[DECPMAX*2];                        /* coefficient + padding */
-  uInt digits, savestat;               /* work */
+  Int   shift;                         /* dfr as an Int */
+  uByte  buf[DECPMAX*2];               /* coefficient + padding */
+  uInt  digits, savestat;              /* work */
   bcdnum num;                          /* .. */
+  uInt  uiwork;                        /* for macros */
 
   if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set);
   if (!DFISINT(dfr)) return decInvalid(result, set);
   digits=decFloatDigits(dfr);                    /* calculate digits */
-  if (digits>2) return decInvalid(result, set);          /* definitely out of range */
-  shift=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff];          /* is in bottom declet */
+  if (digits>2) return decInvalid(result, set);   /* definitely out of range */
+  shift=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff];   /* is in bottom declet */
   if (shift>DECPMAX) return decInvalid(result, set);   /* too big */
   /* [from here on no error or status change is possible] */
 
   if (DFISINF(dfl)) return decInfinity(result, dfl); /* canonical */
   /* handle no-shift and all-shift (clear to zero) cases */
   if (shift==0) return decCanonical(result, dfl);
-  if (shift==DECPMAX) {                             /* zero with sign */
+  if (shift==DECPMAX) {                     /* zero with sign */
     uByte sign=(uByte)(DFBYTE(dfl, 0)&0x80); /* save sign bit */
     decFloatZero(result);                   /* make +0 */
     DFBYTE(result, 0)=(uByte)(DFBYTE(result, 0)|sign); /* and set sign */
@@ -3299,23 +3438,23 @@ decFloat * decFloatShift(decFloat *result,
     num.lsd=buf+DECPMAX-shift-1;
     }
    else { /* shift left -- zero padding needed to right */
-    UINTAT(buf+DECPMAX)=0;             /* 8 will handle most cases */
-    UINTAT(buf+DECPMAX+4)=0;           /* .. */
+    UBFROMUI(buf+DECPMAX, 0);          /* 8 will handle most cases */
+    UBFROMUI(buf+DECPMAX+4, 0);        /* .. */
     if (shift>8) memset(buf+DECPMAX+8, 0, 8+QUAD*18); /* all other cases */
     num.msd+=shift;
     num.lsd=num.msd+DECPMAX-1;
     }
-  savestat=set->status;                        /* record */
+  savestat=set->status;                /* record */
   decFinalize(result, &num, set);
-  set->status=savestat;                        /* restore */
+  set->status=savestat;                /* restore */
   return result;
   } /* decFloatShift */
 
 /* ------------------------------------------------------------------ */
-/* decFloatSubtract -- subtract a decFloat from another                      */
+/* decFloatSubtract -- subtract a decFloat from another              */
 /*                                                                   */
 /*   result gets the result of subtracting dfr from dfl:             */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result                                                  */
@@ -3333,9 +3472,9 @@ decFloat * decFloatSubtract(decFloat *result,
   } /* decFloatSubtract */
 
 /* ------------------------------------------------------------------ */
-/* decFloatToInt -- round to 32-bit binary integer (4 flavours)              */
+/* decFloatToInt -- round to 32-bit binary integer (4 flavours)       */
 /*                                                                   */
-/*   df           is the decFloat to round                                   */
+/*   df    is the decFloat to round                                  */
 /*   set   is the context                                            */
 /*   round is the rounding mode to use                               */
 /*   returns a uInt or an Int, rounded according to the name         */
@@ -3361,12 +3500,12 @@ Int decFloatToInt32Exact(const decFloat *df, decContext *set,
   return (Int)decToInt32(df, set, round, 1, 0);}
 
 /* ------------------------------------------------------------------ */
-/* decFloatToIntegral -- round to integral value (two flavours)              */
+/* decFloatToIntegral -- round to integral value (two flavours)       */
 /*                                                                   */
 /*   result gets the result                                          */
-/*   df            is the decFloat to round                                  */
+/*   df     is the decFloat to round                                 */
 /*   set    is the context                                           */
-/*   round  is the rounding mode to use                                      */
+/*   round  is the rounding mode to use                              */
 /*   returns result                                                  */
 /*                                                                   */
 /* No exceptions, even Inexact, are raised except for sNaN input, or  */
@@ -3384,12 +3523,12 @@ decFloat * decFloatToIntegralExact(decFloat *result, const decFloat *df,
 /* decFloatXor -- logical digitwise XOR of two decFloats             */
 /*                                                                   */
 /*   result gets the result of XORing dfl and dfr                    */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs)                             */
 /*   set    is the context                                           */
 /*   returns result, which will be canonical with sign=0             */
 /*                                                                   */
-/* The operands must be positive, finite with exponent q=0, and              */
+/* The operands must be positive, finite with exponent q=0, and       */
 /* comprise just zeros and ones; if not, Invalid operation results.   */
 /* ------------------------------------------------------------------ */
 decFloat * decFloatXor(decFloat *result,
@@ -3432,14 +3571,14 @@ static decFloat *decInvalid(decFloat *result, decContext *set) {
 /* decInfinity -- set canonical Infinity with sign from a decFloat    */
 /*                                                                   */
 /*   result gets a canonical Infinity                                */
-/*   df            is source decFloat (only the sign is used)                */
+/*   df     is source decFloat (only the sign is used)               */
 /*   returns result                                                  */
 /*                                                                   */
-/* df may be the same as result                                              */
+/* df may be the same as result                                      */
 /* ------------------------------------------------------------------ */
 static decFloat *decInfinity(decFloat *result, const decFloat *df) {
   uInt sign=DFWORD(df, 0);        /* save source signword */
-  decFloatZero(result);                   /* clear everything */
+  decFloatZero(result);           /* clear everything */
   DFWORD(result, 0)=DECFLOAT_Inf | (sign & DECFLOAT_Sign);
   return result;
   } /* decInfinity */
@@ -3449,7 +3588,7 @@ static decFloat *decInfinity(decFloat *result, const decFloat *df) {
 /*                                                                   */
 /*   result gets the result of handling dfl and dfr, one or both of   */
 /*         which is a NaN                                            */
-/*   dfl    is the first decFloat (lhs)                                      */
+/*   dfl    is the first decFloat (lhs)                              */
 /*   dfr    is the second decFloat (rhs) -- may be NULL for a single- */
 /*         operand operation                                         */
 /*   set    is the context                                           */
@@ -3476,19 +3615,20 @@ static decFloat *decNaNs(decFloat *result,
   } /* decNaNs */
 
 /* ------------------------------------------------------------------ */
-/* decNumCompare -- numeric comparison of two decFloats                      */
+/* decNumCompare -- numeric comparison of two decFloats              */
 /*                                                                   */
 /*   dfl    is the left-hand decFloat, which is not a NaN            */
 /*   dfr    is the right-hand decFloat, which is not a NaN           */
 /*   tot    is 1 for total order compare, 0 for simple numeric       */
-/*   returns -1, 0, or +1 for dfl<dfr, dfl=dfr, dfl>dfr                      */
+/*   returns -1, 0, or +1 for dfl<dfr, dfl=dfr, dfl>dfr              */
 /*                                                                   */
-/* No error is possible; status and mode are unchanged.                      */
+/* No error is possible; status and mode are unchanged.              */
 /* ------------------------------------------------------------------ */
 static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
   Int  sigl, sigr;                     /* LHS and RHS non-0 signums */
   Int  shift;                          /* shift needed to align operands */
   uByte *ub, *uc;                      /* work */
+  uInt uiwork;                         /* for macros */
   /* buffers +2 if Quad (36 digits), need double plus 4 for safe padding */
   uByte bufl[DECPMAX*2+QUAD*2+4];      /* for LHS coefficient + padding */
   uByte bufr[DECPMAX*2+QUAD*2+4];      /* for RHS coefficient + padding */
@@ -3512,7 +3652,7 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
   sigr=-sigl;                          /* sign to return if abs(RHS) wins */
 
   if (DFISINF(dfl)) {
-    if (DFISINF(dfr)) return 0;                /* both infinite & same sign */
+    if (DFISINF(dfr)) return 0;        /* both infinite & same sign */
     return sigl;                       /* inf > n */
     }
   if (DFISINF(dfr)) return sigr;       /* n < inf [dfl is finite] */
@@ -3544,17 +3684,16 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
   /* decode the coefficients */
   /* (shift both right two if Quad to make a multiple of four) */
   #if QUAD
-    ub=bufl;                            /* avoid type-pun violation */
-    UINTAT(ub)=0;
-    uc=bufr;                            /* avoid type-pun violation */
-    UINTAT(uc)=0;
+    UBFROMUI(bufl, 0);
+    UBFROMUI(bufr, 0);
   #endif
   GETCOEFF(dfl, bufl+QUAD*2);          /* decode from decFloat */
   GETCOEFF(dfr, bufr+QUAD*2);          /* .. */
   if (shift==0) {                      /* aligned; common and easy */
     /* all multiples of four, here */
     for (ub=bufl, uc=bufr; ub<bufl+DECPMAX+QUAD*2; ub+=4, uc+=4) {
-      if (UINTAT(ub)==UINTAT(uc)) continue; /* so far so same */
+      uInt ui=UBTOUI(ub);
+      if (ui==UBTOUI(uc)) continue;    /* so far so same */
       /* about to find a winner; go by bytes in case little-endian */
       for (;; ub++, uc++) {
        if (*ub>*uc) return sigl;       /* difference found */
@@ -3565,17 +3704,17 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
    else if (shift>0) {                 /* lhs to left */
     ub=bufl;                           /* RHS pointer */
     /* pad bufl so right-aligned; most shifts will fit in 8 */
-    UINTAT(bufl+DECPMAX+QUAD*2)=0;     /* add eight zeros */
-    UINTAT(bufl+DECPMAX+QUAD*2+4)=0;   /* .. */
+    UBFROMUI(bufl+DECPMAX+QUAD*2, 0);  /* add eight zeros */
+    UBFROMUI(bufl+DECPMAX+QUAD*2+4, 0); /* .. */
     if (shift>8) {
       /* more than eight; fill the rest, and also worth doing the */
       /* lead-in by fours */
-      uByte *up;                        /* work */
+      uByte *up;                       /* work */
       uByte *upend=bufl+DECPMAX+QUAD*2+shift;
-      for (up=bufl+DECPMAX+QUAD*2+8; up<upend; up+=4) UINTAT(up)=0;
+      for (up=bufl+DECPMAX+QUAD*2+8; up<upend; up+=4) UBFROMUI(up, 0);
       /* [pads up to 36 in all for Quad] */
       for (;; ub+=4) {
-       if (UINTAT(ub)!=0) return sigl;
+       if (UBTOUI(ub)!=0) return sigl;
        if (ub+4>bufl+shift-4) break;
        }
       }
@@ -3585,7 +3724,8 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
     /* comparison can go for the full length of bufr, which is a */
     /* multiple of 4 bytes */
     for (uc=bufr; ; uc+=4, ub+=4) {
-      if (UINTAT(uc)!=UINTAT(ub)) {    /* mismatch found */
+      uInt ui=UBTOUI(ub);
+      if (ui!=UBTOUI(uc)) {            /* mismatch found */
        for (;; uc++, ub++) {           /* check from left [little-endian?] */
          if (*ub>*uc) return sigl;     /* difference found */
          if (*ub<*uc) return sigr;     /* .. */
@@ -3598,17 +3738,17 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
    else { /* shift<0) .. RHS is to left of LHS; mirror shift>0 */
     uc=bufr;                           /* RHS pointer */
     /* pad bufr so right-aligned; most shifts will fit in 8 */
-    UINTAT(bufr+DECPMAX+QUAD*2)=0;     /* add eight zeros */
-    UINTAT(bufr+DECPMAX+QUAD*2+4)=0;   /* .. */
+    UBFROMUI(bufr+DECPMAX+QUAD*2, 0);  /* add eight zeros */
+    UBFROMUI(bufr+DECPMAX+QUAD*2+4, 0); /* .. */
     if (shift<-8) {
       /* more than eight; fill the rest, and also worth doing the */
       /* lead-in by fours */
-      uByte *up;                        /* work */
+      uByte *up;                       /* work */
       uByte *upend=bufr+DECPMAX+QUAD*2-shift;
-      for (up=bufr+DECPMAX+QUAD*2+8; up<upend; up+=4) UINTAT(up)=0;
+      for (up=bufr+DECPMAX+QUAD*2+8; up<upend; up+=4) UBFROMUI(up, 0);
       /* [pads up to 36 in all for Quad] */
       for (;; uc+=4) {
-       if (UINTAT(uc)!=0) return sigr;
+       if (UBTOUI(uc)!=0) return sigr;
        if (uc+4>bufr-shift-4) break;
        }
       }
@@ -3618,7 +3758,8 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
     /* comparison can go for the full length of bufl, which is a */
     /* multiple of 4 bytes */
     for (ub=bufl; ; ub+=4, uc+=4) {
-      if (UINTAT(ub)!=UINTAT(uc)) {    /* mismatch found */
+      uInt ui=UBTOUI(ub);
+      if (ui!=UBTOUI(uc)) {            /* mismatch found */
        for (;; ub++, uc++) {           /* check from left [little-endian?] */
          if (*ub>*uc) return sigl;     /* difference found */
          if (*ub<*uc) return sigr;     /* .. */
@@ -3639,10 +3780,10 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
 /* ------------------------------------------------------------------ */
 /* decToInt32 -- local routine to effect ToInteger conversions       */
 /*                                                                   */
-/*   df            is the decFloat to convert                                */
+/*   df     is the decFloat to convert                               */
 /*   set    is the context                                           */
-/*   rmode  is the rounding mode to use                                      */
-/*   exact  is 1 if Inexact should be signalled                              */
+/*   rmode  is the rounding mode to use                              */
+/*   exact  is 1 if Inexact should be signalled                      */
 /*   unsign is 1 if the result a uInt, 0 if an Int (cast to uInt)     */
 /*   returns 32-bit result as a uInt                                 */
 /*                                                                   */
@@ -3652,13 +3793,13 @@ static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) {
 static uInt decToInt32(const decFloat *df, decContext *set,
                       enum rounding rmode, Flag exact, Flag unsign) {
   Int  exp;                       /* exponent */
-  uInt sourhi, sourpen, sourlo;           /* top word from source decFloat .. */
+  uInt sourhi, sourpen, sourlo;    /* top word from source decFloat .. */
   uInt hi, lo;                    /* .. penultimate, least, etc. */
   decFloat zero, result;          /* work */
   Int  i;                         /* .. */
 
   /* Start decoding the argument */
-  sourhi=DFWORD(df, 0);                        /* top word */
+  sourhi=DFWORD(df, 0);                /* top word */
   exp=DECCOMBEXP[sourhi>>26];          /* get exponent high bits (in place) */
   if (EXPISSPECIAL(exp)) {             /* is special? */
     set->status|=DEC_Invalid_operation; /* signal */
@@ -3730,10 +3871,10 @@ static uInt decToInt32(const decFloat *df, decContext *set,
 /* decToIntegral -- local routine to effect ToIntegral value         */
 /*                                                                   */
 /*   result gets the result                                          */
-/*   df            is the decFloat to round                                  */
+/*   df     is the decFloat to round                                 */
 /*   set    is the context                                           */
-/*   rmode  is the rounding mode to use                                      */
-/*   exact  is 1 if Inexact should be signalled                              */
+/*   rmode  is the rounding mode to use                              */
+/*   exact  is 1 if Inexact should be signalled                      */
 /*   returns result                                                  */
 /* ------------------------------------------------------------------ */
 static decFloat * decToIntegral(decFloat *result, const decFloat *df,
@@ -3746,7 +3887,7 @@ static decFloat * decToIntegral(decFloat *result, const decFloat *df,
   decFloat zero;                  /* work */
 
   /* Start decoding the argument */
-  sourhi=DFWORD(df, 0);                   /* top word */
+  sourhi=DFWORD(df, 0);           /* top word */
   exp=DECCOMBEXP[sourhi>>26];     /* get exponent high bits (in place) */
 
   if (EXPISSPECIAL(exp)) {        /* is special? */
@@ -3762,12 +3903,12 @@ static decFloat * decToIntegral(decFloat *result, const decFloat *df,
 
   if (exp>=0) return decCanonical(result, df); /* already integral */
 
-  saveround=set->round;                        /* save rounding mode .. */
+  saveround=set->round;                /* save rounding mode .. */
   savestatus=set->status;              /* .. and status */
   set->round=rmode;                    /* set mode */
   decFloatZero(&zero);                 /* make 0E+0 */
   decFloatQuantize(result, df, &zero, set); /* 'integrate'; cannot fail */
-  set->round=saveround;                        /* restore rounding mode .. */
+  set->round=saveround;                /* restore rounding mode .. */
   if (!exact) set->status=savestatus;  /* .. and status, unless exact */
   return result;
   } /* decToIntegral */
index fa16e79..845b914 100644 (file)
@@ -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 */
index d2e3bed..b1d1cc4 100644 (file)
 #include <string.h>          /* for strcmp */
 #include <stdio.h>           /* for printf if DECCHECK */
 #include "dconfig.h"         /* for GCC definitions */
-#include "decContext.h"              /* context and base types */
+#include "decContext.h"       /* context and base types */
 #include "decNumberLocal.h"   /* decNumber local types, etc. */
 
-#if DECCHECK
 /* compile-time endian tester [assumes sizeof(Int)>1] */
 static const  Int mfcone=1;                 /* constant 1 */
-static const  Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
+static const  Flag *mfctop=(const Flag *)&mfcone; /* -> top byte */
 #define LITEND *mfctop            /* named flag; 1=little-endian */
-#endif
 
 /* ------------------------------------------------------------------ */
 /* round-for-reround digits                                          */
@@ -64,7 +62,7 @@ const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
 /*                                                                   */
 /*  context is the context structure to be queried                   */
 /*  mask indicates the bits to be cleared (the status bit that       */
-/*    corresponds to each 1 bit in the mask is cleared)                      */
+/*    corresponds to each 1 bit in the mask is cleared)              */
 /*  returns context                                                  */
 /*                                                                   */
 /* No error is possible.                                             */
@@ -80,9 +78,9 @@ decContext *decContextClearStatus(decContext *context, uInt mask) {
 /*  context is the structure to be initialized                       */
 /*  kind selects the required set of default values, one of:         */
 /*     DEC_INIT_BASE       -- select ANSI X3-274 defaults            */
-/*     DEC_INIT_DECIMAL32  -- select IEEE 754r defaults, 32-bit      */
-/*     DEC_INIT_DECIMAL64  -- select IEEE 754r defaults, 64-bit      */
-/*     DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit     */
+/*     DEC_INIT_DECIMAL32  -- select IEEE 754 defaults, 32-bit       */
+/*     DEC_INIT_DECIMAL64  -- select IEEE 754 defaults, 64-bit       */
+/*     DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit      */
 /*     For any other value a valid context is returned, but with     */
 /*     Invalid_operation set in the status field.                    */
 /*  returns a context structure with the appropriate initial values.  */
@@ -105,11 +103,11 @@ decContext * decContextDefault(decContext *context, Int kind) {
       break;
     case DEC_INIT_DECIMAL32:
       context->digits=7;                    /* digits */
-      context->emax=96;                             /* Emax */
+      context->emax=96;                     /* Emax */
       context->emin=-95;                    /* Emin */
       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
-      context->traps=0;                             /* no traps set */
-      context->clamp=1;                             /* clamp exponents */
+      context->traps=0;                     /* no traps set */
+      context->clamp=1;                     /* clamp exponents */
       #if DECSUBSET
       context->extended=1;                  /* set */
       #endif
@@ -119,8 +117,8 @@ decContext * decContextDefault(decContext *context, Int kind) {
       context->emax=384;                    /* Emax */
       context->emin=-383;                   /* Emin */
       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
-      context->traps=0;                             /* no traps set */
-      context->clamp=1;                             /* clamp exponents */
+      context->traps=0;                     /* no traps set */
+      context->clamp=1;                     /* clamp exponents */
       #if DECSUBSET
       context->extended=1;                  /* set */
       #endif
@@ -130,8 +128,8 @@ decContext * decContextDefault(decContext *context, Int kind) {
       context->emax=6144;                   /* Emax */
       context->emin=-6143;                  /* Emin */
       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
-      context->traps=0;                             /* no traps set */
-      context->clamp=1;                             /* clamp exponents */
+      context->traps=0;                     /* no traps set */
+      context->clamp=1;                     /* clamp exponents */
       #if DECSUBSET
       context->extended=1;                  /* set */
       #endif
@@ -142,15 +140,6 @@ decContext * decContextDefault(decContext *context, Int kind) {
       decContextSetStatus(context, DEC_Invalid_operation); /* trap */
     }
 
-  #if DECCHECK
-  if (LITEND!=DECLITEND) {
-    const char *adj;
-    if (LITEND) adj="little";
-          else adj="big";
-    printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
-          DECLITEND, adj);
-    }
-  #endif
   return context;} /* decContextDefault */
 
 /* ------------------------------------------------------------------ */
@@ -166,7 +155,7 @@ enum rounding decContextGetRounding(decContext *context) {
   } /* decContextGetRounding */
 
 /* ------------------------------------------------------------------ */
-/* decContextGetStatus -- return current status                              */
+/* decContextGetStatus -- return current status                      */
 /*                                                                   */
 /*  context is the context structure to be queried                   */
 /*  returns status                                                   */
@@ -181,8 +170,8 @@ uInt decContextGetStatus(decContext *context) {
 /* decContextRestoreStatus -- restore bits in current status         */
 /*                                                                   */
 /*  context is the context structure to be updated                   */
-/*  newstatus is the source for the bits to be restored                      */
-/*  mask indicates the bits to be restored (the status bit that              */
+/*  newstatus is the source for the bits to be restored              */
+/*  mask indicates the bits to be restored (the status bit that       */
 /*    corresponds to each 1 bit in the mask is set to the value of    */
 /*    the correspnding bit in newstatus)                             */
 /*  returns context                                                  */
@@ -252,7 +241,7 @@ decContext * decContextSetStatus(decContext *context, uInt status) {
 /*                                                                   */
 /*  returns the context structure, unless the string is equal to      */
 /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
-/*    returned.                                                              */
+/*    returned.                                                      */
 /* ------------------------------------------------------------------ */
 decContext * decContextSetStatusFromString(decContext *context,
                                           const char *string) {
@@ -303,7 +292,7 @@ decContext * decContextSetStatusFromString(decContext *context,
 /*                                                                   */
 /*  returns the context structure, unless the string is equal to      */
 /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
-/*    returned.                                                              */
+/*    returned.                                                      */
 /* ------------------------------------------------------------------ */
 decContext * decContextSetStatusFromStringQuiet(decContext *context,
                                                const char *string) {
@@ -356,11 +345,11 @@ decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
   return context;} /* decContextSetStatusQuiet */
 
 /* ------------------------------------------------------------------ */
-/* decContextStatusToString -- convert status flags to a string              */
+/* decContextStatusToString -- convert status flags to a string       */
 /*                                                                   */
 /*  context is a context with valid status field                     */
 /*                                                                   */
-/*  returns a constant string describing the condition.         If multiple  */
+/*  returns a constant string describing the condition.  If multiple  */
 /*    (or no) flags are set, a generic constant message is returned.  */
 /* ------------------------------------------------------------------ */
 const char *decContextStatusToString(const decContext *context) {
@@ -385,11 +374,41 @@ const char *decContextStatusToString(const decContext *context) {
   #if DECSUBSET
   if (status==DEC_Lost_digits         ) return DEC_Condition_LD;
   #endif
-  if (status==0                               ) return DEC_Condition_ZE;
+  if (status==0                       ) return DEC_Condition_ZE;
   return DEC_Condition_MU;  /* Multiple errors */
   } /* decContextStatusToString */
 
 /* ------------------------------------------------------------------ */
+/* decContextTestEndian -- test whether DECLITEND is set correctly    */
+/*                                                                   */
+/*  quiet is 1 to suppress message; 0 otherwise                      */
+/*  returns 0 if DECLITEND is correct                                */
+/*         1 if DECLITEND is incorrect and should be 1               */
+/*        -1 if DECLITEND is incorrect and should be 0               */
+/*                                                                   */
+/* A message is displayed if the return value is not 0 and quiet==0.  */
+/*                                                                   */
+/* No error is possible.                                             */
+/* ------------------------------------------------------------------ */
+Int decContextTestEndian(Flag quiet) {
+  Int res=0;                 /* optimist */
+  uInt dle=(uInt)DECLITEND;   /* unsign */
+  if (dle>1) dle=1;          /* ensure 0 or 1 */
+
+  if (LITEND!=DECLITEND) {
+    const char *adj;
+    if (!quiet) {
+      if (LITEND) adj="little";
+            else adj="big";
+      printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
+            DECLITEND, adj);
+      }
+    res=(Int)LITEND-dle;
+    }
+  return res;
+  } /* decContextTestEndian */
+
+/* ------------------------------------------------------------------ */
 /* decContextTestSavedStatus -- test bits in saved status            */
 /*                                                                   */
 /*  oldstatus is the status word to be tested                        */
index f80d03c..70effd8 100644 (file)
@@ -34,7 +34,7 @@
 /*                                                                   */
 /* Context variables must always have valid values:                  */
 /*                                                                   */
-/*  status   -- [any bits may be cleared, but not set, by user]              */
+/*  status   -- [any bits may be cleared, but not set, by user]       */
 /*  round    -- must be one of the enumerated rounding modes         */
 /*                                                                   */
 /* The following variables are implied for fixed size formats (i.e.,  */
   #define DECCONTEXT
   #define DECCNAME     "decContext"                    /* Short name */
   #define DECCFULLNAME "Decimal Context Descriptor"   /* Verbose name */
-  #define DECCAUTHOR   "Mike Cowlishaw"                      /* Who to blame */
+  #define DECCAUTHOR   "Mike Cowlishaw"              /* Who to blame */
 
-  #include "gstdint.h"            /* C99 standard integers           */
+  #if !defined(int32_t)
+    #include <stdint.h>           /* C99 standard integers           */
+  #endif
   #include <stdio.h>              /* for printf, etc.                */
-  #include <signal.h>             /* for traps                       */
+  #include <signal.h>             /* for traps                       */
 
   /* Extended flags setting -- set this to 0 to use only IEEE flags   */
+  #if !defined(DECEXTFLAG)
   #define DECEXTFLAG 1            /* 1=enable extended flags         */
+  #endif
 
   /* Conditional code flag -- set this to 0 for best performance      */
+  #if !defined(DECSUBSET)
   #define DECSUBSET  0            /* 1=enable subset arithmetic      */
+  #endif
 
   /* Context for operations, with associated constants               */
   enum rounding {
     DEC_ROUND_CEILING,            /* round towards +infinity         */
-    DEC_ROUND_UP,                 /* round away from 0               */
+    DEC_ROUND_UP,                 /* round away from 0               */
     DEC_ROUND_HALF_UP,            /* 0.5 rounds up                   */
     DEC_ROUND_HALF_EVEN,          /* 0.5 rounds to nearest even      */
     DEC_ROUND_HALF_DOWN,          /* 0.5 rounds down                 */
     DEC_ROUND_DOWN,               /* round towards 0 (truncate)      */
     DEC_ROUND_FLOOR,              /* round towards -infinity         */
-    DEC_ROUND_05UP,               /* round for reround               */
+    DEC_ROUND_05UP,               /* round for reround               */
     DEC_ROUND_MAX                 /* enum must be less than this     */
     };
   #define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
 
   typedef struct {
-    int32_t  digits;              /* working precision               */
-    int32_t  emax;                /* maximum positive exponent       */
-    int32_t  emin;                /* minimum negative exponent       */
+    int32_t  digits;              /* working precision               */
+    int32_t  emax;                /* maximum positive exponent       */
+    int32_t  emin;                /* minimum negative exponent       */
     enum     rounding round;      /* rounding mode                   */
     uint32_t traps;               /* trap-enabler flags              */
     uint32_t status;              /* status flags                    */
   #define DEC_MIN_EMIN -999999999
   #define DEC_MAX_MATH     999999 /* max emax, etc., for math funcs. */
 
-  /* Classifications for decimal numbers, aligned with 754r (note     */
-  /* that 'normal' and 'subnormal' are meaningful only with a        */
-  /* decContext or a fixed size format).                             */
+  /* Classifications for decimal numbers, aligned with 754 (note that */
+  /* 'normal' and 'subnormal' are meaningful only with a decContext   */
+  /* or a fixed size format).                                        */
   enum decClass {
     DEC_CLASS_SNAN,
     DEC_CLASS_QNAN,
     #define DEC_Division_impossible  0x00000004
     #define DEC_Division_undefined   0x00000008
     #define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
-    #define DEC_Inexact                     0x00000020
-    #define DEC_Invalid_context             0x00000040
+    #define DEC_Inexact             0x00000020
+    #define DEC_Invalid_context      0x00000040
     #define DEC_Invalid_operation    0x00000080
     #if DECSUBSET
     #define DEC_Lost_digits         0x00000100
     #endif
     #define DEC_Overflow            0x00000200
-    #define DEC_Clamped                     0x00000400
-    #define DEC_Rounded                     0x00000800
+    #define DEC_Clamped             0x00000400
+    #define DEC_Rounded             0x00000800
     #define DEC_Subnormal           0x00001000
     #define DEC_Underflow           0x00002000
   #else
     #define DEC_Division_impossible  0x00000010
     #define DEC_Division_undefined   0x00000010
     #define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
-    #define DEC_Inexact                     0x00000001
-    #define DEC_Invalid_context             0x00000010
+    #define DEC_Inexact             0x00000001
+    #define DEC_Invalid_context      0x00000010
     #define DEC_Invalid_operation    0x00000010
     #if DECSUBSET
     #define DEC_Lost_digits         0x00000000
     #endif
     #define DEC_Overflow            0x00000008
-    #define DEC_Clamped                     0x00000000
-    #define DEC_Rounded                     0x00000000
+    #define DEC_Clamped             0x00000000
+    #define DEC_Rounded             0x00000000
     #define DEC_Subnormal           0x00000000
     #define DEC_Underflow           0x00000004
   #endif
 
-  /* IEEE 854 groupings for the flags                                */
+  /* IEEE 754 groupings for the flags                                */
   /* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal    */
-  /* are not in IEEE 854]                                            */
-  #define DEC_IEEE_854_Division_by_zero         (DEC_Division_by_zero)
+  /* are not in IEEE 754]                                            */
+  #define DEC_IEEE_754_Division_by_zero  (DEC_Division_by_zero)
   #if DECSUBSET
-  #define DEC_IEEE_854_Inexact          (DEC_Inexact | DEC_Lost_digits)
+  #define DEC_IEEE_754_Inexact          (DEC_Inexact | DEC_Lost_digits)
   #else
-  #define DEC_IEEE_854_Inexact          (DEC_Inexact)
+  #define DEC_IEEE_754_Inexact          (DEC_Inexact)
   #endif
-  #define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax |     \
+  #define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax |     \
                                          DEC_Division_impossible |   \
                                          DEC_Division_undefined |    \
                                          DEC_Insufficient_storage |  \
-                                         DEC_Invalid_context |       \
+                                         DEC_Invalid_context |       \
                                          DEC_Invalid_operation)
-  #define DEC_IEEE_854_Overflow                 (DEC_Overflow)
-  #define DEC_IEEE_854_Underflow        (DEC_Underflow)
+  #define DEC_IEEE_754_Overflow         (DEC_Overflow)
+  #define DEC_IEEE_754_Underflow        (DEC_Underflow)
 
   /* flags which are normally errors (result is qNaN, infinite, or 0) */
-  #define DEC_Errors (DEC_IEEE_854_Division_by_zero |                \
-                     DEC_IEEE_854_Invalid_operation |                \
-                     DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow)
+  #define DEC_Errors (DEC_IEEE_754_Division_by_zero |                \
+                     DEC_IEEE_754_Invalid_operation |                \
+                     DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)
   /* flags which cause a result to become qNaN                       */
-  #define DEC_NaNs    DEC_IEEE_854_Invalid_operation
+  #define DEC_NaNs    DEC_IEEE_754_Invalid_operation
 
   /* flags which are normally for information only (finite results)   */
   #if DECSUBSET
   #define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
   #endif
 
+  /* IEEE 854 names (for compatibility with older decNumber versions) */
+  #define DEC_IEEE_854_Division_by_zero  DEC_IEEE_754_Division_by_zero
+  #define DEC_IEEE_854_Inexact          DEC_IEEE_754_Inexact
+  #define DEC_IEEE_854_Invalid_operation DEC_IEEE_754_Invalid_operation
+  #define DEC_IEEE_854_Overflow         DEC_IEEE_754_Overflow
+  #define DEC_IEEE_854_Underflow        DEC_IEEE_754_Underflow
+
   /* Name strings for the exceptional conditions                     */
   #define DEC_Condition_CS "Conversion syntax"
   #define DEC_Condition_DZ "Division by zero"
                                   /* including terminator            */
 
   /* Initialization descriptors, used by decContextDefault           */
-  #define DEC_INIT_BASE                0
+  #define DEC_INIT_BASE        0
   #define DEC_INIT_DECIMAL32   32
   #define DEC_INIT_DECIMAL64   64
   #define DEC_INIT_DECIMAL128 128
   extern decContext  * decContextSetStatusFromStringQuiet(decContext *, const char *);
   extern decContext  * decContextSetStatusQuiet(decContext *, uint32_t);
   extern const char  * decContextStatusToString(const decContext *);
+  extern int32_t       decContextTestEndian(uint8_t);
   extern uint32_t      decContextTestSavedStatus(uint32_t, uint32_t);
   extern uint32_t      decContextTestStatus(decContext *, uint32_t);
   extern decContext  * decContextZeroStatus(decContext *);
index a4710d6..87b35d0 100644 (file)
 
 /* ------------------------------------------------------------------------ */
 /* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
-/* [Automatically generated -- do not edit.  2007.05.05]                   */
+/* [Automatically generated -- do not edit.  2008.06.21]                   */
 /* ------------------------------------------------------------------------ */
-/* ------------------------------------------------------------------------ */
-/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html            */
+/* For details, see DPDecimal.html on the General Decimal Arithmetic page.  */
 
 #include "decDPDSymbols.h"
 
@@ -43,9 +42,9 @@
 /*   uint16_t BIN2DPD[1000];    -- Bin -> DPD (999 => 2457)                */
 /*   uint8_t  BIN2CHAR[4001];   -- Bin -> CHAR (999 => '\3' '9' '9' '9')   */
 /*   uint8_t  BIN2BCD8[4000];   -- Bin -> bytes (999 => 9 9 9 3)           */
-/*   uint16_t DPD2BCD[1024];    -- DPD -> BCD (0x3FF => 0x999)             */
+/*   uint16_t DPD2BCD[1024];    -- DPD -> BCD (0x3FF => 0x999)             */
 /*   uint16_t DPD2BIN[1024];    -- DPD -> BIN (0x3FF => 999)               */
-/*   uint32_t DPD2BINK[1024];   -- DPD -> BIN * 1000 (0x3FF => 999000)     */
+/*   uint32_t DPD2BINK[1024];   -- DPD -> BIN * 1000 (0x3FF => 999000)     */
 /*   uint32_t DPD2BINM[1024];   -- DPD -> BIN * 1E+6 (0x3FF => 999000000)  */
 /*   uint8_t  DPD2BCD8[4096];   -- DPD -> bytes (x3FF => 9 9 9 3)          */
 /*                                                                         */
 /* in the table entry. BIN2CHAR entries are a single byte length (0 for    */
 /* value 0) followed by three digit characters; a trailing terminator is    */
 /* included to allow 4-char moves always.  BIN2BCD8 and DPD2BCD8 entries    */
-/* are similar with the three BCD8 digits followed by a one-byte length            */
+/* are similar with the three BCD8 digits followed by a one-byte length     */
 /* (again, length=0 for value 0).                                          */
 /*                                                                         */
-/* To use a table, its name, prefixed with DEC_, must be defined with a            */
+/* To use a table, its name, prefixed with DEC_, must be defined with a     */
 /* value of 1 before this header file is included.  For example:           */
 /*    #define DEC_BCD2DPD 1                                                */
 /* This mechanism allows software to only include tables that are needed.   */
@@ -513,7 +512,7 @@ const uint16_t DPD2BIN[1024]={        0,    1,    2,    3,    4,    5,    6,    7,
 #if defined(DEC_DPD2BINK) && DEC_DPD2BINK==1 && !defined(DECDPD2BINK)
 #define DECDPD2BINK
 
-const uint32_t DPD2BINK[1024]={              0,   1000,   2000,   3000,   4000,   5000,
+const uint32_t DPD2BINK[1024]={       0,   1000,   2000,   3000,   4000,   5000,
    6000,   7000,   8000,   9000,  80000,  81000, 800000, 801000, 880000, 881000,
   10000,  11000,  12000,  13000,  14000,  15000,  16000,  17000,  18000,  19000,
   90000,  91000, 810000, 811000, 890000, 891000,  20000,  21000,  22000,  23000,
@@ -621,24 +620,24 @@ const uint32_t DPD2BINK[1024]={         0,   1000,   2000,   3000,   4000,   5000,
 #if defined(DEC_DPD2BINM) && DEC_DPD2BINM==1 && !defined(DECDPD2BINM)
 #define DECDPD2BINM
 
-const uint32_t DPD2BINM[1024]={0,   1000000,   2000000,          3000000,   4000000,
-   5000000,   6000000,  7000000,   8000000,   9000000,  80000000,  81000000,
- 800000000, 801000000, 880000000, 881000000,  10000000,         11000000,  12000000,
-  13000000,  14000000, 15000000,  16000000,  17000000,  18000000,  19000000,
+const uint32_t DPD2BINM[1024]={0,   1000000,   2000000,   3000000,   4000000,
+   5000000,   6000000,  7000000,   8000000,   9000000,  80000000,  81000000,
+ 800000000, 801000000, 880000000, 881000000,  10000000,  11000000,  12000000,
+  13000000,  14000000, 15000000,  16000000,  17000000,  18000000,  19000000,
   90000000,  91000000, 810000000, 811000000, 890000000, 891000000,  20000000,
-  21000000,  22000000, 23000000,  24000000,  25000000,  26000000,  27000000,
+  21000000,  22000000, 23000000,  24000000,  25000000,  26000000,  27000000,
   28000000,  29000000, 82000000,  83000000, 820000000, 821000000, 808000000,
- 809000000,  30000000, 31000000,  32000000,  33000000,  34000000,  35000000,
-  36000000,  37000000, 38000000,  39000000,  92000000,  93000000, 830000000,
- 831000000, 818000000, 819000000,  40000000,  41000000,         42000000,  43000000,
-  44000000,  45000000, 46000000,  47000000,  48000000,  49000000,  84000000,
-  85000000, 840000000, 841000000,  88000000,  89000000,         50000000,  51000000,
-  52000000,  53000000, 54000000,  55000000,  56000000,  57000000,  58000000,
-  59000000,  94000000, 95000000, 850000000, 851000000,  98000000,  99000000,
-  60000000,  61000000, 62000000,  63000000,  64000000,  65000000,  66000000,
+ 809000000,  30000000, 31000000,  32000000,  33000000,  34000000,  35000000,
+  36000000,  37000000, 38000000,  39000000,  92000000,  93000000, 830000000,
+ 831000000, 818000000, 819000000,  40000000,  41000000,  42000000,  43000000,
+  44000000,  45000000, 46000000,  47000000,  48000000,  49000000,  84000000,
+  85000000, 840000000, 841000000,  88000000,  89000000,  50000000,  51000000,
+  52000000,  53000000, 54000000,  55000000,  56000000,  57000000,  58000000,
+  59000000,  94000000, 95000000, 850000000, 851000000,  98000000,  99000000,
+  60000000,  61000000, 62000000,  63000000,  64000000,  65000000,  66000000,
   67000000,  68000000, 69000000,  86000000,  87000000, 860000000, 861000000,
- 888000000, 889000000, 70000000,  71000000,  72000000,  73000000,  74000000,
-  75000000,  76000000, 77000000,  78000000,  79000000,  96000000,  97000000,
+ 888000000, 889000000, 70000000,  71000000,  72000000,  73000000,  74000000,
+  75000000,  76000000, 77000000,  78000000,  79000000,  96000000,  97000000,
  870000000, 871000000, 898000000, 899000000, 100000000, 101000000, 102000000,
  103000000, 104000000, 105000000, 106000000, 107000000, 108000000, 109000000,
  180000000, 181000000, 900000000, 901000000, 980000000, 981000000, 110000000,
index ba6a0af..030cc2b 100644 (file)
 /* This module comprises decDouble operations (including conversions) */
 /* ------------------------------------------------------------------ */
 
-#include "decContext.h"              /* public includes */
+#include "decContext.h"       /* public includes */
 #include "decDouble.h"       /* .. */
 
 /* Constant mappings for shared code */
-#define DECPMAX            DECDOUBLE_Pmax
-#define DECEMIN            DECDOUBLE_Emin
-#define DECEMAX            DECDOUBLE_Emax
+#define DECPMAX     DECDOUBLE_Pmax
+#define DECEMIN     DECDOUBLE_Emin
+#define DECEMAX     DECDOUBLE_Emax
 #define DECEMAXD    DECDOUBLE_EmaxD
 #define DECBYTES    DECDOUBLE_Bytes
 #define DECSTRING   DECDOUBLE_String
 #define DECECONL    DECDOUBLE_EconL
-#define DECBIAS            DECDOUBLE_Bias
-#define DECLETS            DECDOUBLE_Declets
+#define DECBIAS     DECDOUBLE_Bias
+#define DECLETS     DECDOUBLE_Declets
 #define DECQTINY    (-DECDOUBLE_Bias)
 /* parameters of next-wider format */
 #define DECWBYTES   DECQUAD_Bytes
 #define DECWBIAS    DECQUAD_Bias
 
 /* Type and function mappings for shared code */
-#define decFloat              decDouble          /* Type name */
-#define decFloatWider         decQuad            /* Type name */
+#define decFloat                  decDouble      /* Type name */
+#define decFloatWider             decQuad        /* Type name */
 
 /* Utilities and conversions (binary results, extractors, etc.) */
-#define decFloatFromBCD                decDoubleFromBCD
-#define decFloatFromInt32      decDoubleFromInt32
-#define decFloatFromPacked     decDoubleFromPacked
-#define decFloatFromString     decDoubleFromString
-#define decFloatFromUInt32     decDoubleFromUInt32
-#define decFloatFromWider      decDoubleFromWider
-#define decFloatGetCoefficient decDoubleGetCoefficient
-#define decFloatGetExponent    decDoubleGetExponent
-#define decFloatSetCoefficient decDoubleSetCoefficient
-#define decFloatSetExponent    decDoubleSetExponent
-#define decFloatShow           decDoubleShow
-#define decFloatToBCD          decDoubleToBCD
-#define decFloatToEngString    decDoubleToEngString
-#define decFloatToInt32                decDoubleToInt32
-#define decFloatToInt32Exact   decDoubleToInt32Exact
-#define decFloatToPacked       decDoubleToPacked
-#define decFloatToString       decDoubleToString
-#define decFloatToUInt32       decDoubleToUInt32
-#define decFloatToUInt32Exact  decDoubleToUInt32Exact
-#define decFloatToWider                decDoubleToWider
-#define decFloatZero           decDoubleZero
+#define decFloatFromBCD           decDoubleFromBCD
+#define decFloatFromInt32         decDoubleFromInt32
+#define decFloatFromPacked        decDoubleFromPacked
+#define decFloatFromPackedChecked  decDoubleFromPackedChecked
+#define decFloatFromString        decDoubleFromString
+#define decFloatFromUInt32        decDoubleFromUInt32
+#define decFloatFromWider         decDoubleFromWider
+#define decFloatGetCoefficient    decDoubleGetCoefficient
+#define decFloatGetExponent       decDoubleGetExponent
+#define decFloatSetCoefficient    decDoubleSetCoefficient
+#define decFloatSetExponent       decDoubleSetExponent
+#define decFloatShow              decDoubleShow
+#define decFloatToBCD             decDoubleToBCD
+#define decFloatToEngString       decDoubleToEngString
+#define decFloatToInt32           decDoubleToInt32
+#define decFloatToInt32Exact      decDoubleToInt32Exact
+#define decFloatToPacked          decDoubleToPacked
+#define decFloatToString          decDoubleToString
+#define decFloatToUInt32          decDoubleToUInt32
+#define decFloatToUInt32Exact     decDoubleToUInt32Exact
+#define decFloatToWider           decDoubleToWider
+#define decFloatZero              decDoubleZero
 
 /* Computational (result is a decFloat) */
-#define decFloatAbs            decDoubleAbs
-#define decFloatAdd            decDoubleAdd
-#define decFloatAnd            decDoubleAnd
-#define decFloatDivide         decDoubleDivide
-#define decFloatDivideInteger  decDoubleDivideInteger
-#define decFloatFMA            decDoubleFMA
-#define decFloatInvert         decDoubleInvert
-#define decFloatLogB           decDoubleLogB
-#define decFloatMax            decDoubleMax
-#define decFloatMaxMag         decDoubleMaxMag
-#define decFloatMin            decDoubleMin
-#define decFloatMinMag         decDoubleMinMag
-#define decFloatMinus          decDoubleMinus
-#define decFloatMultiply       decDoubleMultiply
-#define decFloatNextMinus      decDoubleNextMinus
-#define decFloatNextPlus       decDoubleNextPlus
-#define decFloatNextToward     decDoubleNextToward
-#define decFloatOr             decDoubleOr
-#define decFloatPlus           decDoublePlus
-#define decFloatQuantize       decDoubleQuantize
-#define decFloatReduce         decDoubleReduce
-#define decFloatRemainder      decDoubleRemainder
-#define decFloatRemainderNear  decDoubleRemainderNear
-#define decFloatRotate         decDoubleRotate
-#define decFloatScaleB         decDoubleScaleB
-#define decFloatShift          decDoubleShift
-#define decFloatSubtract       decDoubleSubtract
-#define decFloatToIntegralValue decDoubleToIntegralValue
-#define decFloatToIntegralExact decDoubleToIntegralExact
-#define decFloatXor            decDoubleXor
+#define decFloatAbs               decDoubleAbs
+#define decFloatAdd               decDoubleAdd
+#define decFloatAnd               decDoubleAnd
+#define decFloatDivide            decDoubleDivide
+#define decFloatDivideInteger     decDoubleDivideInteger
+#define decFloatFMA               decDoubleFMA
+#define decFloatInvert            decDoubleInvert
+#define decFloatLogB              decDoubleLogB
+#define decFloatMax               decDoubleMax
+#define decFloatMaxMag            decDoubleMaxMag
+#define decFloatMin               decDoubleMin
+#define decFloatMinMag            decDoubleMinMag
+#define decFloatMinus             decDoubleMinus
+#define decFloatMultiply          decDoubleMultiply
+#define decFloatNextMinus         decDoubleNextMinus
+#define decFloatNextPlus          decDoubleNextPlus
+#define decFloatNextToward        decDoubleNextToward
+#define decFloatOr                decDoubleOr
+#define decFloatPlus              decDoublePlus
+#define decFloatQuantize          decDoubleQuantize
+#define decFloatReduce            decDoubleReduce
+#define decFloatRemainder         decDoubleRemainder
+#define decFloatRemainderNear     decDoubleRemainderNear
+#define decFloatRotate            decDoubleRotate
+#define decFloatScaleB            decDoubleScaleB
+#define decFloatShift             decDoubleShift
+#define decFloatSubtract          decDoubleSubtract
+#define decFloatToIntegralValue    decDoubleToIntegralValue
+#define decFloatToIntegralExact    decDoubleToIntegralExact
+#define decFloatXor               decDoubleXor
 
 /* Comparisons */
-#define decFloatCompare                decDoubleCompare
-#define decFloatCompareSignal  decDoubleCompareSignal
-#define decFloatCompareTotal   decDoubleCompareTotal
-#define decFloatCompareTotalMag decDoubleCompareTotalMag
+#define decFloatCompare           decDoubleCompare
+#define decFloatCompareSignal     decDoubleCompareSignal
+#define decFloatCompareTotal      decDoubleCompareTotal
+#define decFloatCompareTotalMag    decDoubleCompareTotalMag
 
 /* Copies */
-#define decFloatCanonical      decDoubleCanonical
-#define decFloatCopy           decDoubleCopy
-#define decFloatCopyAbs                decDoubleCopyAbs
-#define decFloatCopyNegate     decDoubleCopyNegate
-#define decFloatCopySign       decDoubleCopySign
+#define decFloatCanonical         decDoubleCanonical
+#define decFloatCopy              decDoubleCopy
+#define decFloatCopyAbs           decDoubleCopyAbs
+#define decFloatCopyNegate        decDoubleCopyNegate
+#define decFloatCopySign          decDoubleCopySign
 
 /* Non-computational */
-#define decFloatClass          decDoubleClass
-#define decFloatClassString    decDoubleClassString
-#define decFloatDigits         decDoubleDigits
-#define decFloatIsCanonical    decDoubleIsCanonical
-#define decFloatIsFinite       decDoubleIsFinite
-#define decFloatIsInfinite     decDoubleIsInfinite
-#define decFloatIsInteger      decDoubleIsInteger
-#define decFloatIsNaN          decDoubleIsNaN
-#define decFloatIsNormal       decDoubleIsNormal
-#define decFloatIsSignaling    decDoubleIsSignaling
-#define decFloatIsSignalling   decDoubleIsSignalling
-#define decFloatIsSigned       decDoubleIsSigned
-#define decFloatIsSubnormal    decDoubleIsSubnormal
-#define decFloatIsZero         decDoubleIsZero
-#define decFloatRadix          decDoubleRadix
-#define decFloatSameQuantum    decDoubleSameQuantum
-#define decFloatVersion                decDoubleVersion
-
+#define decFloatClass             decDoubleClass
+#define decFloatClassString       decDoubleClassString
+#define decFloatDigits            decDoubleDigits
+#define decFloatIsCanonical       decDoubleIsCanonical
+#define decFloatIsFinite          decDoubleIsFinite
+#define decFloatIsInfinite        decDoubleIsInfinite
+#define decFloatIsInteger         decDoubleIsInteger
+#define decFloatIsNaN             decDoubleIsNaN
+#define decFloatIsNormal          decDoubleIsNormal
+#define decFloatIsSignaling       decDoubleIsSignaling
+#define decFloatIsSignalling      decDoubleIsSignalling
+#define decFloatIsSigned          decDoubleIsSigned
+#define decFloatIsSubnormal       decDoubleIsSubnormal
+#define decFloatIsZero            decDoubleIsZero
+#define decFloatRadix             decDoubleRadix
+#define decFloatSameQuantum       decDoubleSameQuantum
+#define decFloatVersion           decDoubleVersion
 
 #include "decNumberLocal.h"   /* local includes (need DECPMAX) */
 #include "decCommon.c"       /* non-arithmetic decFloat routines */
 #include "decBasic.c"        /* basic formats routines */
 
-/* Below here will move to shared file as completed */
-
index 53fcf40..aa8d77d 100644 (file)
 /* ------------------------------------------------------------------ */
 /* decDouble.h -- Decimal 64-bit format module header                */
 /* ------------------------------------------------------------------ */
-/* Please see decFloats.h for an overview and documentation details.  */
-/* ------------------------------------------------------------------ */
 
 #if !defined(DECDOUBLE)
   #define DECDOUBLE
 
-  #define DECDOUBLENAME              "decimalDouble"         /* Short name   */
+  #define DECDOUBLENAME       "decimalDouble"        /* Short name   */
   #define DECDOUBLETITLE      "Decimal 64-bit datum"  /* Verbose name */
   #define DECDOUBLEAUTHOR     "Mike Cowlishaw"       /* Who to blame */
 
   /* parameters for decDoubles */
   #define DECDOUBLE_Bytes   8     /* length                          */
   #define DECDOUBLE_Pmax    16    /* maximum precision (digits)      */
-  #define DECDOUBLE_Emin   -383           /* minimum adjusted exponent       */
-  #define DECDOUBLE_Emax    384           /* maximum adjusted exponent       */
+  #define DECDOUBLE_Emin   -383    /* minimum adjusted exponent       */
+  #define DECDOUBLE_Emax    384    /* maximum adjusted exponent       */
   #define DECDOUBLE_EmaxD   3     /* maximum exponent digits         */
-  #define DECDOUBLE_Bias    398           /* bias for the exponent           */
-  #define DECDOUBLE_String  25    /* maximum string length, +1       */
+  #define DECDOUBLE_Bias    398    /* bias for the exponent          */
+  #define DECDOUBLE_String  25    /* maximum string length, +1       */
   #define DECDOUBLE_EconL   8     /* exponent continuation length    */
   #define DECDOUBLE_Declets 5     /* count of declets                */
   /* highest biased exponent (Elimit-1) */
   #include "decContext.h"
   #include "decQuad.h"
 
-  /* The decDouble decimal 64-bit type, accessible by various types */
+  /* The decDouble decimal 64-bit type, accessible by all sizes */
   typedef union {
-    uint8_t bytes[DECDOUBLE_Bytes]; /* fields: 1, 5, 8, 50 bits          */
+    uint8_t   bytes[DECDOUBLE_Bytes];  /* fields: 1, 5, 8, 50 bits */
     uint16_t shorts[DECDOUBLE_Bytes/2];
-    uint32_t words[DECDOUBLE_Bytes/4];
+    uint32_t  words[DECDOUBLE_Bytes/4];
+    #if DECUSE64
+    uint64_t  longs[DECDOUBLE_Bytes/8];
+    #endif
     } decDouble;
 
   /* ---------------------------------------------------------------- */
@@ -75,6 +76,7 @@
   extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t);
   extern decDouble * decDoubleFromInt32(decDouble *, int32_t);
   extern decDouble * decDoubleFromPacked(decDouble *, int32_t, const uint8_t *);
+  extern decDouble * decDoubleFromPackedChecked(decDouble *, int32_t, const uint8_t *);
   extern decDouble * decDoubleFromString(decDouble *, const char *, decContext *);
   extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t);
   extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *);
 
   /* decNumber conversions; these are implemented as macros so as not  */
   /* to force a dependency on decimal64 and decNumber in decDouble.    */
+  /* decDoubleFromNumber returns a decimal64 * to avoid warnings.      */
   #define decDoubleToNumber(dq, dn) decimal64ToNumber((decimal64 *)(dq), dn)
-  #define decDoubleFromNumber(dq, dn, set) (decDouble *)decimal64FromNumber((decimal64 *)(dq), dn, set)
+  #define decDoubleFromNumber(dq, dn, set) decimal64FromNumber((decimal64 *)(dq), dn, set)
 
 #endif
index f9a624a..ebc7cf0 100644 (file)
 /* ------------------------------------------------------------------ */
 /* Decimal Number arithmetic module                                  */
 /* ------------------------------------------------------------------ */
-/* This module comprises the routines for General Decimal Arithmetic  */
-/* as defined in the specification which may be found on the         */
-/* http://www2.hursley.ibm.com/decimal web pages.  It implements both */
+/* This module comprises the routines for arbitrary-precision General */
+/* Decimal Arithmetic as defined in the specification which may be    */
+/* found on the General Decimal Arithmetic pages.  It implements both */
 /* the full ('extended') arithmetic and the simpler ('subset')       */
 /* arithmetic.                                                       */
 /*                                                                   */
-/* Usage notes:                                                              */
+/* Usage notes:                                                      */
 /*                                                                   */
 /* 1. This code is ANSI C89 except:                                  */
 /*                                                                   */
-/*       If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and              */
+/*    a) C99 line comments (double forward slash) are used.  (Most C  */
+/*      compilers accept these.  If yours does not, a simple script  */
+/*      can be used to convert them to ANSI C comments.)             */
+/*                                                                   */
+/*    b) Types from C99 stdint.h are used.  If you do not have this   */
+/*      header file, see the User's Guide section of the decNumber   */
+/*      documentation; this lists the necessary definitions.         */
+/*                                                                   */
+/*    c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and       */
 /*      uint64_t types may be used.  To avoid these, set DECUSE64=0  */
 /*      and DECDPUN<=4 (see documentation).                          */
 /*                                                                   */
+/*    The code also conforms to C99 restrictions; in particular,      */
+/*    strict aliasing rules are observed.                            */
+/*                                                                   */
 /* 2. The decNumber format which this library uses is optimized for   */
 /*    efficient processing of relatively short numbers; in particular */
 /*    it allows the use of fixed sized structures and minimizes copy  */
-/*    and move operations.  It does, however, support arbitrary              */
+/*    and move operations.  It does, however, support arbitrary       */
 /*    precision (up to 999,999,999 digits) and arbitrary exponent     */
 /*    range (Emax in the range 0 through 999,999,999 and Emin in the  */
 /*    range -999,999,999 through 0).  Mathematical functions (for     */
@@ -67,7 +78,7 @@
 /*    permitted).  Other than that case, operands must not overlap.   */
 /*                                                                   */
 /* 5. Error handling: the type of the error is ORed into the status   */
-/*    flags in the current context (decContext structure).  The              */
+/*    flags in the current context (decContext structure).  The       */
 /*    SIGFPE signal is then raised if the corresponding trap-enabler  */
 /*    flag in the decContext is set (is 1).                          */
 /*                                                                   */
@@ -76,7 +87,7 @@
 /*                                                                   */
 /*    The result of any routine which returns a number will always    */
 /*    be a valid number (which may be a special value, such as an     */
-/*    Infinity or NaN).                                                      */
+/*    Infinity or NaN).                                              */
 /*                                                                   */
 /* 6. The decNumber format is not an exchangeable concrete           */
 /*    representation as it comprises fields which may be machine-     */
 /*    Canonical conversions to and from strings are provided; other   */
 /*    conversions are available in separate modules.                 */
 /*                                                                   */
-/* 7. Normally, input operands are assumed to be valid.         Set DECCHECK */
+/* 7. Normally, input operands are assumed to be valid.  Set DECCHECK */
 /*    to 1 for extended operand checking (including NULL operands).   */
 /*    Results are undefined if a badly-formed structure (or a NULL    */
-/*    pointer to a structure) is provided, though with DECCHECK              */
+/*    pointer to a structure) is provided, though with DECCHECK       */
 /*    enabled the operator routines are protected against exceptions. */
 /*    (Except if the result pointer is NULL, which is unrecoverable.) */
 /*                                                                   */
 /*                                                                   */
 /* 8. Subset arithmetic is available only if DECSUBSET is set to 1.   */
 /* ------------------------------------------------------------------ */
-/* Implementation notes for maintenance of this module:                      */
+/* Implementation notes for maintenance of this module:              */
 /*                                                                   */
 /* 1. Storage leak protection: Routines which use malloc are not     */
 /*    permitted to use return for fastpath or error exits (i.e.,      */
 /* 3. Setting status in the context must always be the very last      */
 /*    action in a routine, as non-0 status may raise a trap and hence */
 /*    the call to set status may not return (if the handler uses long */
-/*    jump).  Therefore all cleanup must be done first.         In general,  */
+/*    jump).  Therefore all cleanup must be done first.  In general,  */
 /*    to achieve this status is accumulated and is only applied just  */
 /*    before return by calling decContextSetStatus (via decStatus).   */
 /*                                                                   */
 /*                                                                   */
 /* 4. Exponent checking is minimized by allowing the exponent to      */
 /*    grow outside its limits during calculations, provided that      */
-/*    the decFinalize function is called later.         Multiplication and   */
+/*    the decFinalize function is called later.  Multiplication and   */
 /*    division, and intermediate calculations in exponentiation,      */
-/*    require more careful checks because of the risk of 31-bit              */
+/*    require more careful checks because of the risk of 31-bit       */
 /*    overflow (the most negative valid exponent is -1999999997, for  */
 /*    a 999999999-digit number with adjusted exponent of -999999999). */
 /*                                                                   */
 /*    is not useful for longer numbers because overflow of 32 bits    */
 /*    would lead to 4 multiplies, which is almost as expensive as     */
 /*    a divide (unless a floating-point or 64-bit multiply is        */
-/*    assumed to be available).                                              */
+/*    assumed to be available).                                      */
 /*                                                                   */
-/* 8. Unusual abbreviations that may be used in the commentary:              */
+/* 8. Unusual abbreviations that may be used in the commentary:       */
 /*     lhs -- left hand side (operand, of an operation)              */
-/*     lsd -- least significant digit (of coefficient)               */
+/*     lsd -- least significant digit (of coefficient)               */
 /*     lsu -- least significant Unit (of coefficient)                */
 /*     msd -- most significant digit (of coefficient)                */
 /*     msi -- most significant item (in an array)                    */
 /*     msu -- most significant Unit (of coefficient)                 */
 /*     rhs -- right hand side (operand, of an operation)             */
-/*     +ve -- positive                                               */
-/*     -ve -- negative                                               */
+/*     +ve -- positive                                               */
+/*     -ve -- negative                                               */
 /*     **  -- raise to the power                                     */
 /* ------------------------------------------------------------------ */
 
 /* Public lookup table used by the D2U macro */
 const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
 
-#define DECVERB            1              /* set to 1 for verbose DECCHECK */
+#define DECVERB     1             /* set to 1 for verbose DECCHECK */
 #define powers     DECPOWERS      /* old internal name */
 
 /* Local constants */
 #define DIVIDE     0x80           /* Divide operators */
 #define REMAINDER   0x40          /* .. */
 #define DIVIDEINT   0x20          /* .. */
-#define REMNEAR            0x10           /* .. */
-#define COMPARE            0x01           /* Compare operators */
-#define COMPMAX            0x02           /* .. */
-#define COMPMIN            0x03           /* .. */
+#define REMNEAR     0x10          /* .. */
+#define COMPARE     0x01          /* Compare operators */
+#define COMPMAX     0x02          /* .. */
+#define COMPMIN     0x03          /* .. */
 #define COMPTOTAL   0x04          /* .. */
-#define COMPNAN            0x05           /* .. [NaN processing] */
-#define COMPSIG            0x06           /* .. [signaling COMPARE] */
+#define COMPNAN     0x05          /* .. [NaN processing] */
+#define COMPSIG     0x06          /* .. [signaling COMPARE] */
 #define COMPMAXMAG  0x07          /* .. */
 #define COMPMINMAG  0x08          /* .. */
 
-#define DEC_sNaN     0x40000000           /* local status: sNaN signal */
-#define BADINT (Int)0x80000000    /* most-negative Int; error indicator */
+#define DEC_sNaN     0x40000000    /* local status: sNaN signal */
+#define BADINT (Int)0x80000000    /* most-negative Int; error indicator */
 /* Next two indicate an integer >= 10**6, and its parity (bottom bit) */
 #define BIGEVEN (Int)0x80000002
 #define BIGODD (Int)0x80000003
@@ -262,7 +273,7 @@ static Int     decShiftToLeast(Unit *, Int, Int);
 static Int        decShiftToMost(Unit *, Int, Int);
 static void       decStatus(decNumber *, uInt, decContext *);
 static void       decToString(const decNumber *, char[], Flag);
-static decNumber * decTrim(decNumber *, decContext *, Flag, Int *);
+static decNumber * decTrim(decNumber *, decContext *, Flag, Flag, Int *);
 static Int        decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
                              Unit *, Int);
 static Int        decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
@@ -302,7 +313,7 @@ uInt decAllocBytes=0;                  /* count of bytes allocated */
 #if DECCHECK
 /* Optional checking routines. Enabling these means that decNumber */
 /* and decContext operands to operator routines are checked for */
-/* correctness.         This roughly doubles the execution time of the */
+/* correctness.  This roughly doubles the execution time of the */
 /* fastest routines (and adds 600+ bytes), so should not normally be */
 /* used in 'production'. */
 /* decCheckInexact is used to check that inexact results have a full */
@@ -382,7 +393,7 @@ Int decNumberToInt32(const decNumber *dn, decContext *set) {
     Int d;                        /* work */
     const Unit *up;               /* .. */
     uInt hi=0, lo;                /* .. */
-    up=dn->lsu;                           /* -> lsu */
+    up=dn->lsu;                   /* -> lsu */
     lo=*up;                       /* get 1 to 9 digits */
     #if DECDPUN>1                 /* split to higher */
       hi=lo/10;
@@ -418,7 +429,7 @@ uInt decNumberToUInt32(const decNumber *dn, decContext *set) {
     Int d;                        /* work */
     const Unit *up;               /* .. */
     uInt hi=0, lo;                /* .. */
-    up=dn->lsu;                           /* -> lsu */
+    up=dn->lsu;                   /* -> lsu */
     lo=*up;                       /* get 1 to 9 digits */
     #if DECDPUN>1                 /* split to higher */
       hi=lo/10;
@@ -437,7 +448,7 @@ uInt decNumberToUInt32(const decNumber *dn, decContext *set) {
   } /* decNumberToUInt32 */
 
 /* ------------------------------------------------------------------ */
-/* to-scientific-string -- conversion to numeric string                      */
+/* to-scientific-string -- conversion to numeric string              */
 /* to-engineering-string -- conversion to numeric string             */
 /*                                                                   */
 /*   decNumberToString(dn, string);                                  */
@@ -464,30 +475,30 @@ char * decNumberToEngString(const decNumber *dn, char *string){
 /* to-number -- conversion from numeric string                       */
 /*                                                                   */
 /* decNumberFromString -- convert string to decNumber                */
-/*   dn               -- the number structure to fill                        */
+/*   dn        -- the number structure to fill                       */
 /*   chars[]   -- the string to convert ('\0' terminated)            */
 /*   set       -- the context used for processing any error,         */
 /*               determining the maximum precision available         */
 /*               (set.digits), determining the maximum and minimum   */
 /*               exponent (set.emax and set.emin), determining if    */
-/*               extended values are allowed, and checking the       */
+/*               extended values are allowed, and checking the       */
 /*               rounding mode if overflow occurs or rounding is     */
 /*               needed.                                             */
 /*                                                                   */
 /* The length of the coefficient and the size of the exponent are     */
 /* checked by this routine, so the correct error (Underflow or       */
-/* Overflow) can be reported or rounding applied, as necessary.              */
+/* Overflow) can be reported or rounding applied, as necessary.       */
 /*                                                                   */
 /* If bad syntax is detected, the result will be a quiet NaN.        */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberFromString(decNumber *dn, const char chars[],
                                decContext *set) {
   Int  exponent=0;                /* working exponent [assume 0] */
-  uByte bits=0;                           /* working flags [assume +ve] */
+  uByte bits=0;                   /* working flags [assume +ve] */
   Unit *res;                      /* where result will be built */
   Unit resbuff[SD2U(DECBUFFER+9)];/* local buffer in case need temporary */
                                   /* [+9 allows for ln() constants] */
-  Unit *allocres=NULL;            /* -> allocated result, iff allocated */
+  Unit *allocres=NULL;            /* -> allocated result, iff allocated */
   Int  d=0;                       /* count of digits found in decimal part */
   const char *dotchar=NULL;       /* where dot was found */
   const char *cfirst=chars;       /* -> first character of decimal part */
@@ -507,7 +518,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
 
   do {                            /* status & malloc protection */
     for (c=chars;; c++) {         /* -> input character */
-      if (*c>='0' && *c<='9') {           /* test for Arabic digit */
+      if (*c>='0' && *c<='9') {    /* test for Arabic digit */
        last=c;
        d++;                       /* count of real digits */
        continue;                  /* still in decimal part */
@@ -537,7 +548,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
       if (!set->extended) break;   /* hopeless */
       #endif
       /* Infinities and NaNs are possible, here */
-      if (dotchar!=NULL) break;           /* .. unless had a dot */
+      if (dotchar!=NULL) break;    /* .. unless had a dot */
       decNumberZero(dn);          /* be optimistic */
       if (decBiStr(c, "infinity", "INFINITY")
        || decBiStr(c, "inf", "INF")) {
@@ -548,7 +559,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
       /* a NaN expected */
       /* 2003.09.10 NaNs are now permitted to have a sign */
       dn->bits=bits | DECNAN;     /* assume simple NaN */
-      if (*c=='s' || *c=='S') {           /* looks like an sNaN */
+      if (*c=='s' || *c=='S') {    /* looks like an sNaN */
        c++;
        dn->bits=bits | DECSNAN;
        }
@@ -578,7 +589,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
        if (d>set->digits) break;
        } /* too many digits? */
       /* good; drop through to convert the integer to coefficient */
-      status=0;                           /* syntax is OK */
+      status=0;                   /* syntax is OK */
       bits=dn->bits;              /* for copy-back */
       } /* last==NULL */
 
@@ -613,14 +624,14 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
        /* [up to 1999999999 is OK, for example 1E-1000000998] */
        }
       if (nege) exponent=-exponent;    /* was negative */
-      status=0;                                /* is OK */
+      status=0;                        /* is OK */
       } /* stuff after digits */
 
     /* Here when whole string has been inspected; syntax is good */
     /* cfirst->first digit (never dot), last->last digit (ditto) */
 
     /* strip leading zeros/dot [leave final 0 if all 0's] */
-    if (*cfirst=='0') {                        /* [cfirst has stepped over .] */
+    if (*cfirst=='0') {                /* [cfirst has stepped over .] */
       for (c=cfirst; c<last; c++, cfirst++) {
        if (*c=='.') continue;          /* ignore dots */
        if (*c!='0') break;             /* non-zero found */
@@ -637,7 +648,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
 
     /* Handle decimal point... */
     if (dotchar!=NULL && dotchar<last) /* non-trailing '.' found? */
-      exponent-=(last-dotchar);                /* adjust exponent */
+      exponent-=(last-dotchar);        /* adjust exponent */
     /* [we can now ignore the .] */
 
     /* OK, the digits string is good.  Assemble in the decNumber, or in */
@@ -703,7 +714,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
        }
       }
     /* decNumberShow(dn); */
-    } while(0);                                /* [for break] */
+    } while(0);                        /* [for break] */
 
   if (allocres!=NULL) free(allocres);  /* drop any storage used */
   if (status!=0) decStatus(dn, status, set);
@@ -721,7 +732,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
 /*                                                                   */
 /*   res is C, the result.  C may be A                               */
 /*   rhs is A                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* See also decNumberCopyAbs for a quiet bitwise version of this.     */
 /* C must have space for set->digits digits.                         */
@@ -739,7 +750,7 @@ decNumber * decNumberAbs(decNumber *res, const decNumber *rhs,
   #endif
 
   decNumberZero(&dzero);               /* set 0 */
-  dzero.exponent=rhs->exponent;                /* [no coefficient expansion] */
+  dzero.exponent=rhs->exponent;        /* [no coefficient expansion] */
   decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
   if (status!=0) decStatus(res, status, set);
   #if DECCHECK
@@ -756,7 +767,7 @@ decNumber * decNumberAbs(decNumber *res, const decNumber *rhs,
 /*   res is C, the result.  C may be A and/or B (e.g., X=X+X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /* ------------------------------------------------------------------ */
@@ -851,7 +862,7 @@ decNumber * decNumberAnd(decNumber *res, const decNumber *lhs,
 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for one digit (or NaN).                         */
 /* ------------------------------------------------------------------ */
@@ -871,7 +882,7 @@ decNumber * decNumberCompare(decNumber *res, const decNumber *lhs,
 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for one digit (or NaN).                         */
 /* ------------------------------------------------------------------ */
@@ -891,10 +902,10 @@ decNumber * decNumberCompareSignal(decNumber *res, const decNumber *lhs,
 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for one digit; the result will always be one of  */
-/* -1, 0, or 1.                                                              */
+/* -1, 0, or 1.                                                      */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberCompareTotal(decNumber *res, const decNumber *lhs,
                                  const decNumber *rhs, decContext *set) {
@@ -912,10 +923,10 @@ decNumber * decNumberCompareTotal(decNumber *res, const decNumber *lhs,
 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for one digit; the result will always be one of  */
-/* -1, 0, or 1.                                                              */
+/* -1, 0, or 1.                                                      */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
                                     const decNumber *rhs, decContext *set) {
@@ -944,7 +955,7 @@ decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
        a=allocbufa;                    /* use the allocated space */
        }
       decNumberCopy(a, lhs);           /* copy content */
-      a->bits&=~DECNEG;                        /* .. and clear the sign */
+      a->bits&=~DECNEG;                /* .. and clear the sign */
       lhs=a;                           /* use copy from here on */
       }
     if (decNumberIsNegative(rhs)) {    /* rhs<0 */
@@ -958,11 +969,11 @@ decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
        b=allocbufb;                    /* use the allocated space */
        }
       decNumberCopy(b, rhs);           /* copy content */
-      b->bits&=~DECNEG;                        /* .. and clear the sign */
+      b->bits&=~DECNEG;                /* .. and clear the sign */
       rhs=b;                           /* use copy from here on */
       }
     decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
-    } while(0);                                /* end protected */
+    } while(0);                        /* end protected */
 
   if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
   if (allocbufb!=NULL) free(allocbufb); /* .. */
@@ -978,7 +989,7 @@ decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
 /*   res is C, the result.  C may be A and/or B (e.g., X=X/X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /* ------------------------------------------------------------------ */
@@ -994,14 +1005,14 @@ decNumber * decNumberDivide(decNumber *res, const decNumber *lhs,
   } /* decNumberDivide */
 
 /* ------------------------------------------------------------------ */
-/* decNumberDivideInteger -- divide and return integer quotient              */
+/* decNumberDivideInteger -- divide and return integer quotient       */
 /*                                                                   */
 /*   This computes C = A # B, where # is the integer divide operator  */
 /*                                                                   */
 /*   res is C, the result.  C may be A and/or B (e.g., X=X#X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /* ------------------------------------------------------------------ */
@@ -1032,7 +1043,7 @@ decNumber * decNumberDivideInteger(decNumber *res, const decNumber *lhs,
 /*                                                                   */
 /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
 /* almost always be correctly rounded, but may be up to 1 ulp in      */
-/* error in rare cases.                                                      */
+/* error in rare cases.                                              */
 /* ------------------------------------------------------------------ */
 /* This is a wrapper for decExpOp which can handle the slightly wider */
 /* (double) range needed by Ln (which has to be able to calculate     */
@@ -1065,7 +1076,7 @@ decNumber * decNumberExp(decNumber *res, const decNumber *rhs,
       }
     #endif
     decExpOp(res, rhs, set, &status);
-    } while(0);                                /* end protected */
+    } while(0);                        /* end protected */
 
   #if DECSUBSET
   if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */
@@ -1087,7 +1098,7 @@ decNumber * decNumberExp(decNumber *res, const decNumber *rhs,
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
 /*   fhs is C [far hand side]                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* Mathematical function restrictions apply (see above); a NaN is     */
 /* returned with Invalid_operation if a restriction is violated.      */
@@ -1146,7 +1157,7 @@ decNumber * decNumberFMA(decNumber *res, const decNumber *lhs,
     /* Note sNaN has to go through addOp to shorten payload if */
     /* necessary */
     if ((status&DEC_Invalid_operation)!=0) {
-      if (!(status&DEC_sNaN)) {                /* but be true invalid */
+      if (!(status&DEC_sNaN)) {        /* but be true invalid */
        decNumberZero(res);             /* acc not yet set */
        res->bits=DECNAN;
        break;
@@ -1156,12 +1167,12 @@ decNumber * decNumberFMA(decNumber *res, const decNumber *lhs,
       }
     #if DECCHECK
      else { /* multiply was OK */
-      if (status!=0) printf("Status=%08lx after FMA multiply\n", status);
+      if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
       }
     #endif
     /* add the third operand and result -> res, and all is done */
     decAddOp(res, acc, fhs, set, 0, &status);
-    } while(0);                                /* end protected */
+    } while(0);                        /* end protected */
 
   if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
   if (status!=0) decStatus(res, status, set);
@@ -1206,7 +1217,7 @@ decNumber * decNumberInvert(decNumber *res, const decNumber *rhs,
   msudigs=MSUDIGITS(set->digits);      /* [faster than remainder] */
   for (; uc<=msuc; ua++, uc++) {       /* Unit loop */
     Unit a;                            /* extract unit */
-    Int         i, j;                          /* work */
+    Int  i, j;                         /* work */
     if (ua>msua) a=0;
      else a=*ua;
     *uc=0;                             /* can now write back */
@@ -1252,7 +1263,7 @@ decNumber * decNumberInvert(decNumber *res, const decNumber *rhs,
 /*                                                                   */
 /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
 /* almost always be correctly rounded, but may be up to 1 ulp in      */
-/* error in rare cases.                                                      */
+/* error in rare cases.                                              */
 /* ------------------------------------------------------------------ */
 /* This is a wrapper for decLnOp which can handle the slightly wider  */
 /* (+11) range needed by Ln, Log10, etc. (which may have to be able   */
@@ -1287,7 +1298,7 @@ decNumber * decNumberLn(decNumber *res, const decNumber *rhs,
       } /* extended=0 */
     #endif
     decLnOp(res, rhs, set, &status);
-    } while(0);                                /* end protected */
+    } while(0);                        /* end protected */
 
   #if DECSUBSET
   if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */
@@ -1301,7 +1312,7 @@ decNumber * decNumberLn(decNumber *res, const decNumber *rhs,
   } /* decNumberLn */
 
 /* ------------------------------------------------------------------ */
-/* decNumberLogB - get adjusted exponent, by 754r rules                      */
+/* decNumberLogB - get adjusted exponent, by 754 rules               */
 /*                                                                   */
 /*   This computes C = adjustedexponent(A)                           */
 /*                                                                   */
@@ -1336,9 +1347,9 @@ decNumber * decNumberLogB(decNumber *res, const decNumber *rhs,
   if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);
    else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs);
    else if (decNumberIsZero(rhs)) {
-    decNumberZero(res);                        /* prepare for Infinity */
+    decNumberZero(res);                /* prepare for Infinity */
     res->bits=DECNEG|DECINF;           /* -Infinity */
-    status|=DEC_Division_by_zero;      /* as per 754r */
+    status|=DEC_Division_by_zero;      /* as per 754 */
     }
    else { /* finite non-zero */
     Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
@@ -1352,7 +1363,7 @@ decNumber * decNumberLogB(decNumber *res, const decNumber *rhs,
 /* ------------------------------------------------------------------ */
 /* decNumberLog10 -- logarithm in base 10                            */
 /*                                                                   */
-/*   This computes C = log10(A)                                              */
+/*   This computes C = log10(A)                                      */
 /*                                                                   */
 /*   res is C, the result.  C may be A                               */
 /*   rhs is A                                                        */
@@ -1371,13 +1382,13 @@ decNumber * decNumberLogB(decNumber *res, const decNumber *rhs,
 /*                                                                   */
 /* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
 /* almost always be correctly rounded, but may be up to 1 ulp in      */
-/* error in rare cases.                                                      */
+/* error in rare cases.                                              */
 /* ------------------------------------------------------------------ */
 /* This calculates ln(A)/ln(10) using appropriate precision.  For     */
 /* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the      */
 /* requested digits and t is the number of digits in the exponent     */
-/* (maximum 6).         For ln(10) it is p + 3; this is often handled by the */
-/* fastpath in decLnOp.         The final division is done to the requested  */
+/* (maximum 6).  For ln(10) it is p + 3; this is often handled by the */
+/* fastpath in decLnOp.  The final division is done to the requested  */
 /* precision.                                                        */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
@@ -1444,7 +1455,7 @@ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
        decNumberFromInt32(w, w->exponent);
        residue=0;
        decCopyFit(res, w, set, &residue, &status); /* copy & round */
-       decFinish(res, set, &residue, &status);     /* cleanup/set flags */
+       decFinish(res, set, &residue, &status);     /* cleanup/set flags */
        break;
        } /* not a power of 10 */
       } /* not a candidate for exact */
@@ -1501,7 +1512,7 @@ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
 
     aset.digits=set->digits;           /* for final divide */
     decDivideOp(res, a, b, &aset, DIVIDE, &status); /* into result */
-    } while(0);                                /* [for break] */
+    } while(0);                        /* [for break] */
 
   if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
   if (allocbufb!=NULL) free(allocbufb); /* .. */
@@ -1519,12 +1530,12 @@ decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
 /* ------------------------------------------------------------------ */
 /* decNumberMax -- compare two Numbers and return the maximum        */
 /*                                                                   */
-/*   This computes C = A ? B, returning the maximum by 754R rules     */
+/*   This computes C = A ? B, returning the maximum by 754 rules      */
 /*                                                                   */
 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /* ------------------------------------------------------------------ */
@@ -1542,12 +1553,12 @@ decNumber * decNumberMax(decNumber *res, const decNumber *lhs,
 /* ------------------------------------------------------------------ */
 /* decNumberMaxMag -- compare and return the maximum by magnitude     */
 /*                                                                   */
-/*   This computes C = A ? B, returning the maximum by 754R rules     */
+/*   This computes C = A ? B, returning the maximum by 754 rules      */
 /*                                                                   */
 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /* ------------------------------------------------------------------ */
@@ -1565,12 +1576,12 @@ decNumber * decNumberMaxMag(decNumber *res, const decNumber *lhs,
 /* ------------------------------------------------------------------ */
 /* decNumberMin -- compare two Numbers and return the minimum        */
 /*                                                                   */
-/*   This computes C = A ? B, returning the minimum by 754R rules     */
+/*   This computes C = A ? B, returning the minimum by 754 rules      */
 /*                                                                   */
 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /* ------------------------------------------------------------------ */
@@ -1588,12 +1599,12 @@ decNumber * decNumberMin(decNumber *res, const decNumber *lhs,
 /* ------------------------------------------------------------------ */
 /* decNumberMinMag -- compare and return the minimum by magnitude     */
 /*                                                                   */
-/*   This computes C = A ? B, returning the minimum by 754R rules     */
+/*   This computes C = A ? B, returning the minimum by 754 rules      */
 /*                                                                   */
 /*   res is C, the result.  C may be A and/or B (e.g., X=X?X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /* ------------------------------------------------------------------ */
@@ -1615,7 +1626,7 @@ decNumber * decNumberMinMag(decNumber *res, const decNumber *lhs,
 /*                                                                   */
 /*   res is C, the result.  C may be A                               */
 /*   rhs is A                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* See also decNumberCopyNegate for a quiet bitwise version of this.  */
 /* C must have space for set->digits digits.                         */
@@ -1632,7 +1643,7 @@ decNumber * decNumberMinus(decNumber *res, const decNumber *rhs,
   #endif
 
   decNumberZero(&dzero);               /* make 0 */
-  dzero.exponent=rhs->exponent;                /* [no coefficient expansion] */
+  dzero.exponent=rhs->exponent;        /* [no coefficient expansion] */
   decAddOp(res, &dzero, rhs, set, DECNEG, &status);
   if (status!=0) decStatus(res, status, set);
   #if DECCHECK
@@ -1642,15 +1653,15 @@ decNumber * decNumberMinus(decNumber *res, const decNumber *rhs,
   } /* decNumberMinus */
 
 /* ------------------------------------------------------------------ */
-/* decNumberNextMinus -- next towards -Infinity                              */
+/* decNumberNextMinus -- next towards -Infinity                      */
 /*                                                                   */
 /*   This computes C = A - infinitesimal, rounded towards -Infinity   */
 /*                                                                   */
 /*   res is C, the result.  C may be A                               */
 /*   rhs is A                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
-/* This is a generalization of 754r NextDown.                        */
+/* This is a generalization of 754 NextDown.                         */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
                               decContext *set) {
@@ -1684,9 +1695,9 @@ decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
 /*                                                                   */
 /*   res is C, the result.  C may be A                               */
 /*   rhs is A                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
-/* This is a generalization of 754r NextUp.                          */
+/* This is a generalization of 754 NextUp.                           */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
                              decContext *set) {
@@ -1718,14 +1729,15 @@ decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
 /* decNumberNextToward -- next towards rhs                           */
 /*                                                                   */
 /*   This computes C = A +/- infinitesimal, rounded towards          */
-/*   +/-Infinity in the direction of B, as per 754r nextafter rules   */
+/*   +/-Infinity in the direction of B, as per 754-1985 nextafter     */
+/*   modified during revision but dropped from 754-2008.             */
 /*                                                                   */
 /*   res is C, the result.  C may be A or B.                         */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
-/* This is a generalization of 754r NextAfter.                       */
+/* This is a generalization of 754-1985 NextAfter.                   */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs,
                                const decNumber *rhs, decContext *set) {
@@ -1747,27 +1759,27 @@ decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs,
       if (result==0) decNumberCopySign(res, lhs, rhs); /* easy */
        else { /* differ: need NextPlus or NextMinus */
        uByte sub;                      /* add or subtract */
-       if (result<0) {                 /* lhs<rhs, do nextplus */
+       if (result<0) {                 /* lhs<rhs, do nextplus */
          /* -Infinity is the special case */
          if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
            decSetMaxValue(res, set);
            res->bits=DECNEG;           /* negative */
-           return res;                 /* there is no status to set */
+           return res;                 /* there is no status to set */
            }
          workset.round=DEC_ROUND_CEILING;
          sub=0;                        /* add, please */
          } /* plus */
-        else {                         /* lhs>rhs, do nextminus */
+        else {                         /* lhs>rhs, do nextminus */
          /* +Infinity is the special case */
          if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
            decSetMaxValue(res, set);
-           return res;                 /* there is no status to set */
+           return res;                 /* there is no status to set */
            }
          workset.round=DEC_ROUND_FLOOR;
          sub=DECNEG;                   /* subtract, please */
          } /* minus */
        decNumberZero(&dtiny);          /* start with 0 */
-       dtiny.lsu[0]=1;                 /* make number that is .. */
+       dtiny.lsu[0]=1;                 /* make number that is .. */
        dtiny.exponent=DEC_MIN_EMIN-1;  /* .. smaller than tiniest */
        decAddOp(res, lhs, &dtiny, &workset, sub, &status); /* + or - */
        /* turn off exceptions if the result is a normal number */
@@ -1856,7 +1868,7 @@ decNumber * decNumberOr(decNumber *res, const decNumber *lhs,
 /*                                                                   */
 /*   res is C, the result.  C may be A                               */
 /*   rhs is A                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* See also decNumberCopy for a quiet bitwise version of this.       */
 /* C must have space for set->digits digits.                         */
@@ -1874,7 +1886,7 @@ decNumber * decNumberPlus(decNumber *res, const decNumber *rhs,
   #endif
 
   decNumberZero(&dzero);               /* make 0 */
-  dzero.exponent=rhs->exponent;                /* [no coefficient expansion] */
+  dzero.exponent=rhs->exponent;        /* [no coefficient expansion] */
   decAddOp(res, &dzero, rhs, set, 0, &status);
   if (status!=0) decStatus(res, status, set);
   #if DECCHECK
@@ -1891,7 +1903,7 @@ decNumber * decNumberPlus(decNumber *res, const decNumber *rhs,
 /*   res is C, the result.  C may be A and/or B (e.g., X=X+X)        */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /* ------------------------------------------------------------------ */
@@ -1914,7 +1926,7 @@ decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs,
 /*   res is C, the result.  C may be A and/or B (e.g., X=X**X)       */
 /*   lhs is A                                                        */
 /*   rhs is B                                                        */
-/*   set is the context                                                      */
+/*   set is the context                                              */
 /*                                                                   */
 /* C must have space for set->digits digits.                         */
 /*                                                                   */
@@ -1930,7 +1942,7 @@ decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs,
 /*                                                                   */
 /* The final result is rounded according to the context; it will      */
 /* almost always be correctly rounded, but may be up to 1 ulp in      */
-/* error in rare cases.                                                      */
+/* error in rare cases.                                              */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberPower(decNumber *res, const decNumber *lhs,
                           const decNumber *rhs, decContext *set) {
@@ -1953,7 +1965,7 @@ decNumber * decNumberPower(decNumber *res, const decNumber *lhs,
   Flag seenbit;                   /* seen a bit while powering */
   Int  residue=0;                 /* rounding residue */
   uInt status=0;                  /* accumulators */
-&n