xref: /netbsd-src/external/gpl3/gcc.old/dist/libdecnumber/decCommon.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg /* Common code for fixed-size types in the decNumber C Library.
2*8feb0f0bSmrg    Copyright (C) 2007-2020 Free Software Foundation, Inc.
336ac495dSmrg    Contributed by IBM Corporation.  Author Mike Cowlishaw.
436ac495dSmrg 
536ac495dSmrg    This file is part of GCC.
636ac495dSmrg 
736ac495dSmrg    GCC is free software; you can redistribute it and/or modify it under
836ac495dSmrg    the terms of the GNU General Public License as published by the Free
936ac495dSmrg    Software Foundation; either version 3, or (at your option) any later
1036ac495dSmrg    version.
1136ac495dSmrg 
1236ac495dSmrg    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1336ac495dSmrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or
1436ac495dSmrg    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1536ac495dSmrg    for more details.
1636ac495dSmrg 
1736ac495dSmrg Under Section 7 of GPL version 3, you are granted additional
1836ac495dSmrg permissions described in the GCC Runtime Library Exception, version
1936ac495dSmrg 3.1, as published by the Free Software Foundation.
2036ac495dSmrg 
2136ac495dSmrg You should have received a copy of the GNU General Public License and
2236ac495dSmrg a copy of the GCC Runtime Library Exception along with this program;
2336ac495dSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2436ac495dSmrg <http://www.gnu.org/licenses/>.  */
2536ac495dSmrg 
2636ac495dSmrg /* ------------------------------------------------------------------ */
2736ac495dSmrg /* decCommon.c -- common code for all three fixed-size types	      */
2836ac495dSmrg /* ------------------------------------------------------------------ */
2936ac495dSmrg /* This module comprises code that is shared between all the formats  */
3036ac495dSmrg /* (decSingle, decDouble, and decQuad); it includes set and extract   */
3136ac495dSmrg /* of format components, widening, narrowing, and string conversions. */
3236ac495dSmrg /*								      */
3336ac495dSmrg /* Unlike decNumber, parameterization takes place at compile time     */
3436ac495dSmrg /* rather than at runtime.  The parameters are set in the decDouble.c */
3536ac495dSmrg /* (etc.) files, which then include this one to produce the compiled  */
3636ac495dSmrg /* code.  The functions here, therefore, are code shared between      */
3736ac495dSmrg /* multiple formats.						      */
3836ac495dSmrg /* ------------------------------------------------------------------ */
3936ac495dSmrg /* Names here refer to decFloat rather than to decDouble, etc., and */
4036ac495dSmrg /* the functions are in strict alphabetical order. */
4136ac495dSmrg /* Constants, tables, and debug function(s) are included only for QUAD */
4236ac495dSmrg /* (which will always be compiled if DOUBLE or SINGLE are used). */
4336ac495dSmrg /* */
4436ac495dSmrg /* Whenever a decContext is used, only the status may be set (using */
4536ac495dSmrg /* OR) or the rounding mode read; all other fields are ignored and */
4636ac495dSmrg /* untouched. */
4736ac495dSmrg 
4836ac495dSmrg #include "decCommonSymbols.h"
4936ac495dSmrg 
5036ac495dSmrg /* names for simpler testing and default context */
5136ac495dSmrg #if DECPMAX==7
5236ac495dSmrg   #define SINGLE     1
5336ac495dSmrg   #define DOUBLE     0
5436ac495dSmrg   #define QUAD	     0
5536ac495dSmrg   #define DEFCONTEXT DEC_INIT_DECIMAL32
5636ac495dSmrg #elif DECPMAX==16
5736ac495dSmrg   #define SINGLE     0
5836ac495dSmrg   #define DOUBLE     1
5936ac495dSmrg   #define QUAD	     0
6036ac495dSmrg   #define DEFCONTEXT DEC_INIT_DECIMAL64
6136ac495dSmrg #elif DECPMAX==34
6236ac495dSmrg   #define SINGLE     0
6336ac495dSmrg   #define DOUBLE     0
6436ac495dSmrg   #define QUAD	     1
6536ac495dSmrg   #define DEFCONTEXT DEC_INIT_DECIMAL128
6636ac495dSmrg #else
6736ac495dSmrg   #error Unexpected DECPMAX value
6836ac495dSmrg #endif
6936ac495dSmrg 
7036ac495dSmrg /* Assertions */
7136ac495dSmrg 
7236ac495dSmrg #if DECPMAX!=7 && DECPMAX!=16 && DECPMAX!=34
7336ac495dSmrg   #error Unexpected Pmax (DECPMAX) value for this module
7436ac495dSmrg #endif
7536ac495dSmrg 
7636ac495dSmrg /* Assert facts about digit characters, etc. */
7736ac495dSmrg #if ('9'&0x0f)!=9
7836ac495dSmrg   #error This module assumes characters are of the form 0b....nnnn
7936ac495dSmrg   /* where .... are don't care 4 bits and nnnn is 0000 through 1001 */
8036ac495dSmrg #endif
8136ac495dSmrg #if ('9'&0xf0)==('.'&0xf0)
8236ac495dSmrg   #error This module assumes '.' has a different mask than a digit
8336ac495dSmrg #endif
8436ac495dSmrg 
8536ac495dSmrg /* Assert ToString lay-out conditions */
8636ac495dSmrg #if DECSTRING<DECPMAX+9
8736ac495dSmrg   #error ToString needs at least 8 characters for lead-in and dot
8836ac495dSmrg #endif
8936ac495dSmrg #if DECPMAX+DECEMAXD+5 > DECSTRING
9036ac495dSmrg   #error Exponent form can be too long for ToString to lay out safely
9136ac495dSmrg #endif
9236ac495dSmrg #if DECEMAXD > 4
9336ac495dSmrg   #error Exponent form is too long for ToString to lay out
9436ac495dSmrg   /* Note: code for up to 9 digits exists in archives [decOct] */
9536ac495dSmrg #endif
9636ac495dSmrg 
9736ac495dSmrg /* Private functions used here and possibly in decBasic.c, etc. */
9836ac495dSmrg static decFloat * decFinalize(decFloat *, bcdnum *, decContext *);
9936ac495dSmrg static Flag decBiStr(const char *, const char *, const char *);
10036ac495dSmrg 
10136ac495dSmrg /* Macros and private tables; those which are not format-dependent    */
10236ac495dSmrg /* are only included if decQuad is being built. 		      */
10336ac495dSmrg 
10436ac495dSmrg /* ------------------------------------------------------------------ */
10536ac495dSmrg /* Combination field lookup tables (uInts to save measurable work)    */
10636ac495dSmrg /*								      */
10736ac495dSmrg /*   DECCOMBEXP  - 2 most-significant-bits of exponent (00, 01, or    */
10836ac495dSmrg /*		   10), shifted left for format, or DECFLOAT_Inf/NaN  */
10936ac495dSmrg /*   DECCOMBWEXP - The same, for the next-wider format (unless QUAD)  */
11036ac495dSmrg /*   DECCOMBMSD  - 4-bit most-significant-digit 		      */
11136ac495dSmrg /*		   [0 if the index is a special (Infinity or NaN)]    */
11236ac495dSmrg /*   DECCOMBFROM - 5-bit combination field from EXP top bits and MSD  */
11336ac495dSmrg /*		   (placed in uInt so no shift is needed)	      */
11436ac495dSmrg /*								      */
11536ac495dSmrg /* DECCOMBEXP, DECCOMBWEXP, and DECCOMBMSD are indexed by the sign    */
11636ac495dSmrg /*   and 5-bit combination field (0-63, the second half of the table  */
11736ac495dSmrg /*   identical to the first half)				      */
11836ac495dSmrg /* DECCOMBFROM is indexed by expTopTwoBits*16 + msd		      */
11936ac495dSmrg /*								      */
12036ac495dSmrg /* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are     */
12136ac495dSmrg /* only included once, when QUAD is being built 		      */
12236ac495dSmrg /* ------------------------------------------------------------------ */
12336ac495dSmrg static const uInt DECCOMBEXP[64]={
12436ac495dSmrg   0, 0, 0, 0, 0, 0, 0, 0,
12536ac495dSmrg   1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
12636ac495dSmrg   1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
12736ac495dSmrg   2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
12836ac495dSmrg   2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
12936ac495dSmrg   0,	       0,	    1<<DECECONL, 1<<DECECONL,
13036ac495dSmrg   2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN,
13136ac495dSmrg   0, 0, 0, 0, 0, 0, 0, 0,
13236ac495dSmrg   1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
13336ac495dSmrg   1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
13436ac495dSmrg   2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
13536ac495dSmrg   2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
13636ac495dSmrg   0,	       0,	    1<<DECECONL, 1<<DECECONL,
13736ac495dSmrg   2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN};
13836ac495dSmrg #if !QUAD
13936ac495dSmrg static const uInt DECCOMBWEXP[64]={
14036ac495dSmrg   0, 0, 0, 0, 0, 0, 0, 0,
14136ac495dSmrg   1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
14236ac495dSmrg   1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
14336ac495dSmrg   2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
14436ac495dSmrg   2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
14536ac495dSmrg   0,		0,	      1<<DECWECONL, 1<<DECWECONL,
14636ac495dSmrg   2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN,
14736ac495dSmrg   0, 0, 0, 0, 0, 0, 0, 0,
14836ac495dSmrg   1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
14936ac495dSmrg   1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
15036ac495dSmrg   2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
15136ac495dSmrg   2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
15236ac495dSmrg   0,		0,	      1<<DECWECONL, 1<<DECWECONL,
15336ac495dSmrg   2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN};
15436ac495dSmrg #endif
15536ac495dSmrg 
15636ac495dSmrg #if QUAD
15736ac495dSmrg const uInt DECCOMBMSD[64]={
15836ac495dSmrg   0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
15936ac495dSmrg   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0,
16036ac495dSmrg   0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
16136ac495dSmrg   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0};
16236ac495dSmrg 
16336ac495dSmrg const uInt DECCOMBFROM[48]={
16436ac495dSmrg   0x00000000, 0x04000000, 0x08000000, 0x0C000000, 0x10000000, 0x14000000,
16536ac495dSmrg   0x18000000, 0x1C000000, 0x60000000, 0x64000000, 0x00000000, 0x00000000,
16636ac495dSmrg   0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20000000, 0x24000000,
16736ac495dSmrg   0x28000000, 0x2C000000, 0x30000000, 0x34000000, 0x38000000, 0x3C000000,
16836ac495dSmrg   0x68000000, 0x6C000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
16936ac495dSmrg   0x00000000, 0x00000000, 0x40000000, 0x44000000, 0x48000000, 0x4C000000,
17036ac495dSmrg   0x50000000, 0x54000000, 0x58000000, 0x5C000000, 0x70000000, 0x74000000,
17136ac495dSmrg   0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
17236ac495dSmrg 
17336ac495dSmrg /* ------------------------------------------------------------------ */
17436ac495dSmrg /* Request and include the tables to use for conversions	      */
17536ac495dSmrg /* ------------------------------------------------------------------ */
17636ac495dSmrg #define DEC_BCD2DPD  1	      /* 0-0x999 -> DPD */
17736ac495dSmrg #define DEC_BIN2DPD  1	      /* 0-999 -> DPD */
17836ac495dSmrg #define DEC_BIN2BCD8 1	      /* 0-999 -> ddd, len */
17936ac495dSmrg #define DEC_DPD2BCD8 1	      /* DPD -> ddd, len */
18036ac495dSmrg #define DEC_DPD2BIN  1	      /* DPD -> 0-999 */
18136ac495dSmrg #define DEC_DPD2BINK 1	      /* DPD -> 0-999000 */
18236ac495dSmrg #define DEC_DPD2BINM 1	      /* DPD -> 0-999000000 */
18336ac495dSmrg #include "decDPD.h"	      /* source of the lookup tables */
18436ac495dSmrg 
18536ac495dSmrg #endif
18636ac495dSmrg 
18736ac495dSmrg /* ----------------------------------------------------------------- */
18836ac495dSmrg /* decBiStr -- compare string with pairwise options		     */
18936ac495dSmrg /*								     */
19036ac495dSmrg /*   targ is the string to compare				     */
19136ac495dSmrg /*   str1 is one of the strings to compare against (length may be 0) */
19236ac495dSmrg /*   str2 is the other; it must be the same length as str1	     */
19336ac495dSmrg /*								     */
19436ac495dSmrg /*   returns 1 if strings compare equal, (that is, targ is the same  */
19536ac495dSmrg /*   length as str1 and str2, and each character of targ is in one   */
19636ac495dSmrg /*   of str1 or str2 in the corresponding position), or 0 otherwise  */
19736ac495dSmrg /*								     */
19836ac495dSmrg /* This is used for generic caseless compare, including the awkward  */
19936ac495dSmrg /* case of the Turkish dotted and dotless Is.  Use as (for example): */
20036ac495dSmrg /*   if (decBiStr(test, "mike", "MIKE")) ...			     */
20136ac495dSmrg /* ----------------------------------------------------------------- */
decBiStr(const char * targ,const char * str1,const char * str2)20236ac495dSmrg static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
20336ac495dSmrg   for (;;targ++, str1++, str2++) {
20436ac495dSmrg     if (*targ!=*str1 && *targ!=*str2) return 0;
20536ac495dSmrg     /* *targ has a match in one (or both, if terminator) */
20636ac495dSmrg     if (*targ=='\0') break;
20736ac495dSmrg     } /* forever */
20836ac495dSmrg   return 1;
20936ac495dSmrg   } /* decBiStr */
21036ac495dSmrg 
21136ac495dSmrg /* ------------------------------------------------------------------ */
21236ac495dSmrg /* decFinalize -- adjust and store a final result		      */
21336ac495dSmrg /*								      */
21436ac495dSmrg /*  df	is the decFloat format number which gets the final result     */
21536ac495dSmrg /*  num is the descriptor of the number to be checked and encoded     */
21636ac495dSmrg /*	   [its values, including the coefficient, may be modified]   */
21736ac495dSmrg /*  set is the context to use					      */
21836ac495dSmrg /*  returns df							      */
21936ac495dSmrg /*								      */
22036ac495dSmrg /* The num descriptor may point to a bcd8 string of any length; this  */
22136ac495dSmrg /* string may have leading insignificant zeros.  If it has more than  */
22236ac495dSmrg /* DECPMAX digits then the final digit can be a round-for-reround     */
22336ac495dSmrg /* digit (i.e., it may include a sticky bit residue).		      */
22436ac495dSmrg /*								      */
22536ac495dSmrg /* The exponent (q) may be one of the codes for a special value and   */
22636ac495dSmrg /* can be up to 999999999 for conversion from string.		      */
22736ac495dSmrg /*								      */
22836ac495dSmrg /* No error is possible, but Inexact, Underflow, and/or Overflow may  */
22936ac495dSmrg /* be set.							      */
23036ac495dSmrg /* ------------------------------------------------------------------ */
23136ac495dSmrg /* Constant whose size varies with format; also the check for surprises */
23236ac495dSmrg static uByte allnines[DECPMAX]=
23336ac495dSmrg #if SINGLE
23436ac495dSmrg   {9, 9, 9, 9, 9, 9, 9};
23536ac495dSmrg #elif DOUBLE
23636ac495dSmrg   {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
23736ac495dSmrg #elif QUAD
23836ac495dSmrg   {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
23936ac495dSmrg    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
24036ac495dSmrg #endif
24136ac495dSmrg 
decFinalize(decFloat * df,bcdnum * num,decContext * set)24236ac495dSmrg static decFloat * decFinalize(decFloat *df, bcdnum *num,
24336ac495dSmrg 			      decContext *set) {
24436ac495dSmrg   uByte *ub;		      /* work */
24536ac495dSmrg   uInt	 dpd;		      /* .. */
24636ac495dSmrg   uInt	 uiwork;	      /* for macros */
24736ac495dSmrg   uByte *umsd=num->msd;       /* local copy */
24836ac495dSmrg   uByte *ulsd=num->lsd;       /* .. */
24936ac495dSmrg   uInt	 encode;	      /* encoding accumulator */
25036ac495dSmrg   Int	 length;	      /* coefficient length */
25136ac495dSmrg 
25236ac495dSmrg   #if DECCHECK
25336ac495dSmrg   Int clen=ulsd-umsd+1;
25436ac495dSmrg   #if QUAD
25536ac495dSmrg     #define COEXTRA 2			     /* extra-long coefficent */
25636ac495dSmrg   #else
25736ac495dSmrg     #define COEXTRA 0
25836ac495dSmrg   #endif
25936ac495dSmrg   if (clen<1 || clen>DECPMAX*3+2+COEXTRA)
26036ac495dSmrg     printf("decFinalize: suspect coefficient [length=%ld]\n", (LI)clen);
26136ac495dSmrg   if (num->sign!=0 && num->sign!=DECFLOAT_Sign)
26236ac495dSmrg     printf("decFinalize: bad sign [%08lx]\n", (LI)num->sign);
26336ac495dSmrg   if (!EXPISSPECIAL(num->exponent)
26436ac495dSmrg       && (num->exponent>1999999999 || num->exponent<-1999999999))
26536ac495dSmrg     printf("decFinalize: improbable exponent [%ld]\n", (LI)num->exponent);
26636ac495dSmrg   /* decShowNum(num, "final"); */
26736ac495dSmrg   #endif
26836ac495dSmrg 
26936ac495dSmrg   /* A special will have an 'exponent' which is very positive and a */
27036ac495dSmrg   /* coefficient < DECPMAX */
27136ac495dSmrg   length=(uInt)(ulsd-umsd+1);		     /* coefficient length */
27236ac495dSmrg 
27336ac495dSmrg   if (!NUMISSPECIAL(num)) {
27436ac495dSmrg     Int   drop; 			     /* digits to be dropped */
27536ac495dSmrg     /* skip leading insignificant zeros to calculate an exact length */
27636ac495dSmrg     /* [this is quite expensive] */
27736ac495dSmrg     if (*umsd==0) {
27836ac495dSmrg       for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4;
27936ac495dSmrg       for (; *umsd==0 && umsd<ulsd;) umsd++;
28036ac495dSmrg       length=ulsd-umsd+1;		     /* recalculate */
28136ac495dSmrg       }
28236ac495dSmrg     drop=MAXI(length-DECPMAX, DECQTINY-num->exponent);
28336ac495dSmrg     /* drop can now be > digits for bottom-clamp (subnormal) cases */
28436ac495dSmrg     if (drop>0) {			     /* rounding needed */
28536ac495dSmrg       /* (decFloatQuantize has very similar code to this, so any */
28636ac495dSmrg       /* changes may need to be made there, too) */
28736ac495dSmrg       uByte *roundat;			     /* -> re-round digit */
28836ac495dSmrg       uByte reround;			     /* reround value */
28936ac495dSmrg       /* printf("Rounding; drop=%ld\n", (LI)drop); */
29036ac495dSmrg 
29136ac495dSmrg       num->exponent+=drop;		     /* always update exponent */
29236ac495dSmrg 
29336ac495dSmrg       /* Three cases here: */
29436ac495dSmrg       /*   1. new LSD is in coefficient (almost always) */
29536ac495dSmrg       /*   2. new LSD is digit to left of coefficient (so MSD is */
29636ac495dSmrg       /*      round-for-reround digit) */
29736ac495dSmrg       /*   3. new LSD is to left of case 2 (whole coefficient is sticky) */
29836ac495dSmrg       /* [duplicate check-stickies code to save a test] */
29936ac495dSmrg       /* [by-digit check for stickies as runs of zeros are rare] */
30036ac495dSmrg       if (drop<length) {		     /* NB lengths not addresses */
30136ac495dSmrg 	roundat=umsd+length-drop;
30236ac495dSmrg 	reround=*roundat;
30336ac495dSmrg 	for (ub=roundat+1; ub<=ulsd; ub++) {
30436ac495dSmrg 	  if (*ub!=0) { 		     /* non-zero to be discarded */
30536ac495dSmrg 	    reround=DECSTICKYTAB[reround];   /* apply sticky bit */
30636ac495dSmrg 	    break;			     /* [remainder don't-care] */
30736ac495dSmrg 	    }
30836ac495dSmrg 	  } /* check stickies */
30936ac495dSmrg 	ulsd=roundat-1; 		     /* new LSD */
31036ac495dSmrg 	}
31136ac495dSmrg        else {				     /* edge case */
31236ac495dSmrg 	if (drop==length) {
31336ac495dSmrg 	  roundat=umsd;
31436ac495dSmrg 	  reround=*roundat;
31536ac495dSmrg 	  }
31636ac495dSmrg 	 else {
31736ac495dSmrg 	  roundat=umsd-1;
31836ac495dSmrg 	  reround=0;
31936ac495dSmrg 	  }
32036ac495dSmrg 	for (ub=roundat+1; ub<=ulsd; ub++) {
32136ac495dSmrg 	  if (*ub!=0) { 		     /* non-zero to be discarded */
32236ac495dSmrg 	    reround=DECSTICKYTAB[reround];   /* apply sticky bit */
32336ac495dSmrg 	    break;			     /* [remainder don't-care] */
32436ac495dSmrg 	    }
32536ac495dSmrg 	  } /* check stickies */
32636ac495dSmrg 	*umsd=0;			     /* coefficient is a 0 */
32736ac495dSmrg 	ulsd=umsd;			     /* .. */
32836ac495dSmrg 	}
32936ac495dSmrg 
33036ac495dSmrg       if (reround!=0) { 		     /* discarding non-zero */
33136ac495dSmrg 	uInt bump=0;
33236ac495dSmrg 	set->status|=DEC_Inexact;
33336ac495dSmrg 	/* if adjusted exponent [exp+digits-1] is < EMIN then num is */
33436ac495dSmrg 	/* subnormal -- so raise Underflow */
33536ac495dSmrg 	if (num->exponent<DECEMIN && (num->exponent+(ulsd-umsd+1)-1)<DECEMIN)
33636ac495dSmrg 	  set->status|=DEC_Underflow;
33736ac495dSmrg 
33836ac495dSmrg 	/* next decide whether increment of the coefficient is needed */
33936ac495dSmrg 	if (set->round==DEC_ROUND_HALF_EVEN) {	  /* fastpath slowest case */
34036ac495dSmrg 	  if (reround>5) bump=1;		  /* >0.5 goes up */
34136ac495dSmrg 	   else if (reround==5) 		  /* exactly 0.5000 .. */
34236ac495dSmrg 	    bump=*ulsd & 0x01;			  /* .. up iff [new] lsd is odd */
34336ac495dSmrg 	  } /* r-h-e */
34436ac495dSmrg 	 else switch (set->round) {
34536ac495dSmrg 	  case DEC_ROUND_DOWN: {
34636ac495dSmrg 	    /* no change */
34736ac495dSmrg 	    break;} /* r-d */
34836ac495dSmrg 	  case DEC_ROUND_HALF_DOWN: {
34936ac495dSmrg 	    if (reround>5) bump=1;
35036ac495dSmrg 	    break;} /* r-h-d */
35136ac495dSmrg 	  case DEC_ROUND_HALF_UP: {
35236ac495dSmrg 	    if (reround>=5) bump=1;
35336ac495dSmrg 	    break;} /* r-h-u */
35436ac495dSmrg 	  case DEC_ROUND_UP: {
35536ac495dSmrg 	    if (reround>0) bump=1;
35636ac495dSmrg 	    break;} /* r-u */
35736ac495dSmrg 	  case DEC_ROUND_CEILING: {
35836ac495dSmrg 	    /* same as _UP for positive numbers, and as _DOWN for negatives */
35936ac495dSmrg 	    if (!num->sign && reround>0) bump=1;
36036ac495dSmrg 	    break;} /* r-c */
36136ac495dSmrg 	  case DEC_ROUND_FLOOR: {
36236ac495dSmrg 	    /* same as _UP for negative numbers, and as _DOWN for positive */
36336ac495dSmrg 	    /* [negative reround cannot occur on 0] */
36436ac495dSmrg 	    if (num->sign && reround>0) bump=1;
36536ac495dSmrg 	    break;} /* r-f */
36636ac495dSmrg 	  case DEC_ROUND_05UP: {
36736ac495dSmrg 	    if (reround>0) { /* anything out there is 'sticky' */
36836ac495dSmrg 	      /* bump iff lsd=0 or 5; this cannot carry so it could be */
36936ac495dSmrg 	      /* effected immediately with no bump -- but the code */
37036ac495dSmrg 	      /* is clearer if this is done the same way as the others */
37136ac495dSmrg 	      if (*ulsd==0 || *ulsd==5) bump=1;
37236ac495dSmrg 	      }
37336ac495dSmrg 	    break;} /* r-r */
37436ac495dSmrg 	  default: {	  /* e.g., DEC_ROUND_MAX */
37536ac495dSmrg 	    set->status|=DEC_Invalid_context;
37636ac495dSmrg 	    #if DECCHECK
37736ac495dSmrg 	    printf("Unknown rounding mode: %ld\n", (LI)set->round);
37836ac495dSmrg 	    #endif
37936ac495dSmrg 	    break;}
38036ac495dSmrg 	  } /* switch (not r-h-e) */
38136ac495dSmrg 	/* printf("ReRound: %ld  bump: %ld\n", (LI)reround, (LI)bump); */
38236ac495dSmrg 
38336ac495dSmrg 	if (bump!=0) {			     /* need increment */
38436ac495dSmrg 	  /* increment the coefficient; this might end up with 1000... */
38536ac495dSmrg 	  /* (after the all nines case) */
38636ac495dSmrg 	  ub=ulsd;
38736ac495dSmrg 	  for(; ub-3>=umsd && UBTOUI(ub-3)==0x09090909; ub-=4)	{
38836ac495dSmrg 	    UBFROMUI(ub-3, 0);		     /* to 00000000 */
38936ac495dSmrg 	    }
39036ac495dSmrg 	  /* [note ub could now be to left of msd, and it is not safe */
39136ac495dSmrg 	  /* to write to the the left of the msd] */
39236ac495dSmrg 	  /* now at most 3 digits left to non-9 (usually just the one) */
39336ac495dSmrg 	  for (; ub>=umsd; *ub=0, ub--) {
39436ac495dSmrg 	    if (*ub==9) continue;	     /* carry */
39536ac495dSmrg 	    *ub+=1;
39636ac495dSmrg 	    break;
39736ac495dSmrg 	    }
39836ac495dSmrg 	  if (ub<umsd) {		     /* had all-nines */
39936ac495dSmrg 	    *umsd=1;			     /* coefficient to 1000... */
40036ac495dSmrg 	    /* usually the 1000... coefficient can be used as-is */
40136ac495dSmrg 	    if ((ulsd-umsd+1)==DECPMAX) {
40236ac495dSmrg 	      num->exponent++;
40336ac495dSmrg 	      }
40436ac495dSmrg 	     else {
40536ac495dSmrg 	      /* if coefficient is shorter than Pmax then num is */
40636ac495dSmrg 	      /* subnormal, so extend it; this is safe as drop>0 */
40736ac495dSmrg 	      /* (or, if the coefficient was supplied above, it could */
40836ac495dSmrg 	      /* not be 9); this may make the result normal. */
40936ac495dSmrg 	      ulsd++;
41036ac495dSmrg 	      *ulsd=0;
41136ac495dSmrg 	      /* [exponent unchanged] */
41236ac495dSmrg 	      #if DECCHECK
41336ac495dSmrg 	      if (num->exponent!=DECQTINY) /* sanity check */
41436ac495dSmrg 		printf("decFinalize: bad all-nines extend [^%ld, %ld]\n",
41536ac495dSmrg 		       (LI)num->exponent, (LI)(ulsd-umsd+1));
41636ac495dSmrg 	      #endif
41736ac495dSmrg 	      } /* subnormal extend */
41836ac495dSmrg 	    } /* had all-nines */
41936ac495dSmrg 	  } /* bump needed */
42036ac495dSmrg 	} /* inexact rounding */
42136ac495dSmrg 
42236ac495dSmrg       length=ulsd-umsd+1;		/* recalculate (may be <DECPMAX) */
42336ac495dSmrg       } /* need round (drop>0) */
42436ac495dSmrg 
42536ac495dSmrg     /* The coefficient will now fit and has final length unless overflow */
42636ac495dSmrg     /* decShowNum(num, "rounded"); */
42736ac495dSmrg 
42836ac495dSmrg     /* if exponent is >=emax may have to clamp, overflow, or fold-down */
42936ac495dSmrg     if (num->exponent>DECEMAX-(DECPMAX-1)) { /* is edge case */
43036ac495dSmrg       /* printf("overflow checks...\n"); */
43136ac495dSmrg       if (*ulsd==0 && ulsd==umsd) {	/* have zero */
43236ac495dSmrg 	num->exponent=DECEMAX-(DECPMAX-1); /* clamp to max */
43336ac495dSmrg 	}
43436ac495dSmrg        else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */
43536ac495dSmrg 	/* Overflow -- these could go straight to encoding, here, but */
43636ac495dSmrg 	/* instead num is adjusted to keep the code cleaner */
43736ac495dSmrg 	Flag needmax=0; 		/* 1 for finite result */
43836ac495dSmrg 	set->status|=(DEC_Overflow | DEC_Inexact);
43936ac495dSmrg 	switch (set->round) {
44036ac495dSmrg 	  case DEC_ROUND_DOWN: {
44136ac495dSmrg 	    needmax=1;			/* never Infinity */
44236ac495dSmrg 	    break;} /* r-d */
44336ac495dSmrg 	  case DEC_ROUND_05UP: {
44436ac495dSmrg 	    needmax=1;			/* never Infinity */
44536ac495dSmrg 	    break;} /* r-05 */
44636ac495dSmrg 	  case DEC_ROUND_CEILING: {
44736ac495dSmrg 	    if (num->sign) needmax=1;	/* Infinity iff non-negative */
44836ac495dSmrg 	    break;} /* r-c */
44936ac495dSmrg 	  case DEC_ROUND_FLOOR: {
45036ac495dSmrg 	    if (!num->sign) needmax=1;	/* Infinity iff negative */
45136ac495dSmrg 	    break;} /* r-f */
45236ac495dSmrg 	  default: break;		/* Infinity in all other cases */
45336ac495dSmrg 	  }
45436ac495dSmrg 	if (!needmax) { 		/* easy .. set Infinity */
45536ac495dSmrg 	  num->exponent=DECFLOAT_Inf;
45636ac495dSmrg 	  *umsd=0;			/* be clean: coefficient to 0 */
45736ac495dSmrg 	  ulsd=umsd;			/* .. */
45836ac495dSmrg 	  }
45936ac495dSmrg 	 else { 			/* return Nmax */
46036ac495dSmrg 	  umsd=allnines;		/* use constant array */
46136ac495dSmrg 	  ulsd=allnines+DECPMAX-1;
46236ac495dSmrg 	  num->exponent=DECEMAX-(DECPMAX-1);
46336ac495dSmrg 	  }
46436ac495dSmrg 	}
46536ac495dSmrg        else { /* no overflow but non-zero and may have to fold-down */
46636ac495dSmrg 	Int shift=num->exponent-(DECEMAX-(DECPMAX-1));
46736ac495dSmrg 	if (shift>0) {			/* fold-down needed */
46836ac495dSmrg 	  /* fold down needed; must copy to buffer in order to pad */
46936ac495dSmrg 	  /* with zeros safely; fortunately this is not the worst case */
47036ac495dSmrg 	  /* path because cannot have had a round */
47136ac495dSmrg 	  uByte buffer[ROUNDUP(DECPMAX+3, 4)]; /* [+3 allows uInt padding] */
47236ac495dSmrg 	  uByte *s=umsd;		/* source */
47336ac495dSmrg 	  uByte *t=buffer;		/* safe target */
47436ac495dSmrg 	  uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
47536ac495dSmrg 	  /* printf("folddown shift=%ld\n", (LI)shift); */
47636ac495dSmrg 	  for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s));
47736ac495dSmrg 	  for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0);  /* pad 0s */
47836ac495dSmrg 	  num->exponent-=shift;
47936ac495dSmrg 	  umsd=buffer;
48036ac495dSmrg 	  ulsd=tlsd;
48136ac495dSmrg 	  }
48236ac495dSmrg 	} /* fold-down? */
48336ac495dSmrg       length=ulsd-umsd+1;		/* recalculate length */
48436ac495dSmrg       } /* high-end edge case */
48536ac495dSmrg     } /* finite number */
48636ac495dSmrg 
48736ac495dSmrg   /*------------------------------------------------------------------*/
48836ac495dSmrg   /* At this point the result will properly fit the decFloat	      */
48936ac495dSmrg   /* encoding, and it can be encoded with no possibility of error     */
49036ac495dSmrg   /*------------------------------------------------------------------*/
49136ac495dSmrg   /* Following code does not alter coefficient (could be allnines array) */
49236ac495dSmrg 
49336ac495dSmrg   /* fast path possible when DECPMAX digits */
49436ac495dSmrg   if (length==DECPMAX) {
49536ac495dSmrg     return decFloatFromBCD(df, num->exponent, umsd, num->sign);
49636ac495dSmrg     } /* full-length */
49736ac495dSmrg 
49836ac495dSmrg   /* slower path when not a full-length number; must care about length */
49936ac495dSmrg   /* [coefficient length here will be < DECPMAX] */
50036ac495dSmrg   if (!NUMISSPECIAL(num)) {		/* is still finite */
50136ac495dSmrg     /* encode the combination field and exponent continuation */
50236ac495dSmrg     uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */
50336ac495dSmrg     uInt code=(uexp>>DECECONL)<<4;	/* top two bits of exp */
50436ac495dSmrg     /* [msd==0] */
50536ac495dSmrg     /* look up the combination field and make high word */
50636ac495dSmrg     encode=DECCOMBFROM[code];		/* indexed by (0-2)*16+msd */
50736ac495dSmrg     encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
50836ac495dSmrg     }
50936ac495dSmrg    else encode=num->exponent;		/* special [already in word] */
51036ac495dSmrg   encode|=num->sign;			/* add sign */
51136ac495dSmrg 
51236ac495dSmrg   /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
51336ac495dSmrg   /* refers to the declet from the least significant three digits) */
51436ac495dSmrg   /* and put the corresponding DPD code into dpd.  Access to umsd and */
51536ac495dSmrg   /* ulsd (pointers to the most and least significant digit of the */
51636ac495dSmrg   /* variable-length coefficient) is assumed, along with use of a */
51736ac495dSmrg   /* working pointer, uInt *ub. */
51836ac495dSmrg   /* As not full-length then chances are there are many leading zeros */
51936ac495dSmrg   /* [and there may be a partial triad] */
52036ac495dSmrg   #define getDPDt(dpd, n) ub=ulsd-(3*(n))-2;			      \
52136ac495dSmrg     if (ub<umsd-2) dpd=0;					      \
52236ac495dSmrg      else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];  \
52336ac495dSmrg      else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];}
52436ac495dSmrg 
52536ac495dSmrg   /* place the declets in the encoding words and copy to result (df), */
52636ac495dSmrg   /* according to endianness; in all cases complete the sign word */
52736ac495dSmrg   /* first */
52836ac495dSmrg   #if DECPMAX==7
52936ac495dSmrg     getDPDt(dpd, 1);
53036ac495dSmrg     encode|=dpd<<10;
53136ac495dSmrg     getDPDt(dpd, 0);
53236ac495dSmrg     encode|=dpd;
53336ac495dSmrg     DFWORD(df, 0)=encode;     /* just the one word */
53436ac495dSmrg 
53536ac495dSmrg   #elif DECPMAX==16
53636ac495dSmrg     getDPDt(dpd, 4); encode|=dpd<<8;
53736ac495dSmrg     getDPDt(dpd, 3); encode|=dpd>>2;
53836ac495dSmrg     DFWORD(df, 0)=encode;
53936ac495dSmrg     encode=dpd<<30;
54036ac495dSmrg     getDPDt(dpd, 2); encode|=dpd<<20;
54136ac495dSmrg     getDPDt(dpd, 1); encode|=dpd<<10;
54236ac495dSmrg     getDPDt(dpd, 0); encode|=dpd;
54336ac495dSmrg     DFWORD(df, 1)=encode;
54436ac495dSmrg 
54536ac495dSmrg   #elif DECPMAX==34
54636ac495dSmrg     getDPDt(dpd,10); encode|=dpd<<4;
54736ac495dSmrg     getDPDt(dpd, 9); encode|=dpd>>6;
54836ac495dSmrg     DFWORD(df, 0)=encode;
54936ac495dSmrg 
55036ac495dSmrg     encode=dpd<<26;
55136ac495dSmrg     getDPDt(dpd, 8); encode|=dpd<<16;
55236ac495dSmrg     getDPDt(dpd, 7); encode|=dpd<<6;
55336ac495dSmrg     getDPDt(dpd, 6); encode|=dpd>>4;
55436ac495dSmrg     DFWORD(df, 1)=encode;
55536ac495dSmrg 
55636ac495dSmrg     encode=dpd<<28;
55736ac495dSmrg     getDPDt(dpd, 5); encode|=dpd<<18;
55836ac495dSmrg     getDPDt(dpd, 4); encode|=dpd<<8;
55936ac495dSmrg     getDPDt(dpd, 3); encode|=dpd>>2;
56036ac495dSmrg     DFWORD(df, 2)=encode;
56136ac495dSmrg 
56236ac495dSmrg     encode=dpd<<30;
56336ac495dSmrg     getDPDt(dpd, 2); encode|=dpd<<20;
56436ac495dSmrg     getDPDt(dpd, 1); encode|=dpd<<10;
56536ac495dSmrg     getDPDt(dpd, 0); encode|=dpd;
56636ac495dSmrg     DFWORD(df, 3)=encode;
56736ac495dSmrg   #endif
56836ac495dSmrg 
56936ac495dSmrg   /* printf("Status: %08lx\n", (LI)set->status); */
57036ac495dSmrg   /* decFloatShow(df, "final2"); */
57136ac495dSmrg   return df;
57236ac495dSmrg   } /* decFinalize */
57336ac495dSmrg 
57436ac495dSmrg /* ------------------------------------------------------------------ */
57536ac495dSmrg /* decFloatFromBCD -- set decFloat from exponent, BCD8, and sign      */
57636ac495dSmrg /*								      */
57736ac495dSmrg /*  df is the target decFloat					      */
57836ac495dSmrg /*  exp is the in-range unbiased exponent, q, or a special value in   */
57936ac495dSmrg /*    the form returned by decFloatGetExponent			      */
58036ac495dSmrg /*  bcdar holds DECPMAX digits to set the coefficient from, one       */
58136ac495dSmrg /*    digit in each byte (BCD8 encoding); the first (MSD) is ignored  */
58236ac495dSmrg /*    if df is a NaN; all are ignored if df is infinite.	      */
58336ac495dSmrg /*    All bytes must be in 0-9; results are undefined otherwise.      */
58436ac495dSmrg /*  sig is DECFLOAT_Sign to set the sign bit, 0 otherwise	      */
58536ac495dSmrg /*  returns df, which will be canonical 			      */
58636ac495dSmrg /*								      */
58736ac495dSmrg /* No error is possible, and no status will be set.		      */
58836ac495dSmrg /* ------------------------------------------------------------------ */
decFloatFromBCD(decFloat * df,Int exp,const uByte * bcdar,Int sig)58936ac495dSmrg decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
59036ac495dSmrg 			   Int sig) {
59136ac495dSmrg   uInt encode, dpd;			/* work */
59236ac495dSmrg   const uByte *ub;			/* .. */
59336ac495dSmrg 
59436ac495dSmrg   if (EXPISSPECIAL(exp)) encode=exp|sig;/* specials already encoded */
59536ac495dSmrg    else {				/* is finite */
59636ac495dSmrg     /* encode the combination field and exponent continuation */
59736ac495dSmrg     uInt uexp=(uInt)(exp+DECBIAS);	/* biased exponent */
59836ac495dSmrg     uInt code=(uexp>>DECECONL)<<4;	/* top two bits of exp */
59936ac495dSmrg     code+=bcdar[0];			/* add msd */
60036ac495dSmrg     /* look up the combination field and make high word */
60136ac495dSmrg     encode=DECCOMBFROM[code]|sig;	/* indexed by (0-2)*16+msd */
60236ac495dSmrg     encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
60336ac495dSmrg     }
60436ac495dSmrg 
60536ac495dSmrg   /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
60636ac495dSmrg   /* refers to the declet from the least significant three digits) */
60736ac495dSmrg   /* and put the corresponding DPD code into dpd. */
60836ac495dSmrg   /* Use of a working pointer, uInt *ub, is assumed. */
60936ac495dSmrg 
61036ac495dSmrg   #define getDPDb(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2;     \
61136ac495dSmrg     dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];
61236ac495dSmrg 
61336ac495dSmrg   /* place the declets in the encoding words and copy to result (df), */
61436ac495dSmrg   /* according to endianness; in all cases complete the sign word */
61536ac495dSmrg   /* first */
61636ac495dSmrg   #if DECPMAX==7
61736ac495dSmrg     getDPDb(dpd, 1);
61836ac495dSmrg     encode|=dpd<<10;
61936ac495dSmrg     getDPDb(dpd, 0);
62036ac495dSmrg     encode|=dpd;
62136ac495dSmrg     DFWORD(df, 0)=encode;     /* just the one word */
62236ac495dSmrg 
62336ac495dSmrg   #elif DECPMAX==16
62436ac495dSmrg     getDPDb(dpd, 4); encode|=dpd<<8;
62536ac495dSmrg     getDPDb(dpd, 3); encode|=dpd>>2;
62636ac495dSmrg     DFWORD(df, 0)=encode;
62736ac495dSmrg     encode=dpd<<30;
62836ac495dSmrg     getDPDb(dpd, 2); encode|=dpd<<20;
62936ac495dSmrg     getDPDb(dpd, 1); encode|=dpd<<10;
63036ac495dSmrg     getDPDb(dpd, 0); encode|=dpd;
63136ac495dSmrg     DFWORD(df, 1)=encode;
63236ac495dSmrg 
63336ac495dSmrg   #elif DECPMAX==34
63436ac495dSmrg     getDPDb(dpd,10); encode|=dpd<<4;
63536ac495dSmrg     getDPDb(dpd, 9); encode|=dpd>>6;
63636ac495dSmrg     DFWORD(df, 0)=encode;
63736ac495dSmrg 
63836ac495dSmrg     encode=dpd<<26;
63936ac495dSmrg     getDPDb(dpd, 8); encode|=dpd<<16;
64036ac495dSmrg     getDPDb(dpd, 7); encode|=dpd<<6;
64136ac495dSmrg     getDPDb(dpd, 6); encode|=dpd>>4;
64236ac495dSmrg     DFWORD(df, 1)=encode;
64336ac495dSmrg 
64436ac495dSmrg     encode=dpd<<28;
64536ac495dSmrg     getDPDb(dpd, 5); encode|=dpd<<18;
64636ac495dSmrg     getDPDb(dpd, 4); encode|=dpd<<8;
64736ac495dSmrg     getDPDb(dpd, 3); encode|=dpd>>2;
64836ac495dSmrg     DFWORD(df, 2)=encode;
64936ac495dSmrg 
65036ac495dSmrg     encode=dpd<<30;
65136ac495dSmrg     getDPDb(dpd, 2); encode|=dpd<<20;
65236ac495dSmrg     getDPDb(dpd, 1); encode|=dpd<<10;
65336ac495dSmrg     getDPDb(dpd, 0); encode|=dpd;
65436ac495dSmrg     DFWORD(df, 3)=encode;
65536ac495dSmrg   #endif
65636ac495dSmrg   /* decFloatShow(df, "fromB"); */
65736ac495dSmrg   return df;
65836ac495dSmrg   } /* decFloatFromBCD */
65936ac495dSmrg 
66036ac495dSmrg /* ------------------------------------------------------------------ */
66136ac495dSmrg /* decFloatFromPacked -- set decFloat from exponent and packed BCD    */
66236ac495dSmrg /*								      */
66336ac495dSmrg /*  df is the target decFloat					      */
66436ac495dSmrg /*  exp is the in-range unbiased exponent, q, or a special value in   */
66536ac495dSmrg /*    the form returned by decFloatGetExponent			      */
66636ac495dSmrg /*  packed holds DECPMAX packed decimal digits plus a sign nibble     */
66736ac495dSmrg /*    (all 6 codes are OK); the first (MSD) is ignored if df is a NaN */
66836ac495dSmrg /*    and all except sign are ignored if df is infinite.  For DOUBLE  */
66936ac495dSmrg /*    and QUAD the first (pad) nibble is also ignored in all cases.   */
67036ac495dSmrg /*    All coefficient nibbles must be in 0-9 and sign in A-F; results */
67136ac495dSmrg /*    are undefined otherwise.					      */
67236ac495dSmrg /*  returns df, which will be canonical 			      */
67336ac495dSmrg /*								      */
67436ac495dSmrg /* No error is possible, and no status will be set.		      */
67536ac495dSmrg /* ------------------------------------------------------------------ */
decFloatFromPacked(decFloat * df,Int exp,const uByte * packed)67636ac495dSmrg decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
67736ac495dSmrg   uByte bcdar[DECPMAX+2];		/* work [+1 for pad, +1 for sign] */
67836ac495dSmrg   const uByte *ip;			/* .. */
67936ac495dSmrg   uByte *op;				/* .. */
68036ac495dSmrg   Int	sig=0;				/* sign */
68136ac495dSmrg 
68236ac495dSmrg   /* expand coefficient and sign to BCDAR */
68336ac495dSmrg   #if SINGLE
68436ac495dSmrg   op=bcdar+1;				/* no pad digit */
68536ac495dSmrg   #else
68636ac495dSmrg   op=bcdar;				/* first (pad) digit ignored */
68736ac495dSmrg   #endif
68836ac495dSmrg   for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) {
68936ac495dSmrg     *op++=*ip>>4;
69036ac495dSmrg     *op++=(uByte)(*ip&0x0f);		/* [final nibble is sign] */
69136ac495dSmrg     }
69236ac495dSmrg   op--; 				/* -> sign byte */
69336ac495dSmrg   if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
69436ac495dSmrg 
69536ac495dSmrg   if (EXPISSPECIAL(exp)) {		/* Infinity or NaN */
69636ac495dSmrg     if (!EXPISINF(exp)) bcdar[1]=0;	/* a NaN: ignore MSD */
69736ac495dSmrg      else memset(bcdar+1, 0, DECPMAX);	/* Infinite: coefficient to 0 */
69836ac495dSmrg     }
69936ac495dSmrg   return decFloatFromBCD(df, exp, bcdar+1, sig);
70036ac495dSmrg   } /* decFloatFromPacked */
70136ac495dSmrg 
70236ac495dSmrg /* ------------------------------------------------------------------ */
70336ac495dSmrg /* decFloatFromPackedChecked -- set from exponent and packed; checked */
70436ac495dSmrg /*								      */
70536ac495dSmrg /*  df is the target decFloat					      */
70636ac495dSmrg /*  exp is the in-range unbiased exponent, q, or a special value in   */
70736ac495dSmrg /*    the form returned by decFloatGetExponent			      */
70836ac495dSmrg /*  packed holds DECPMAX packed decimal digits plus a sign nibble     */
70936ac495dSmrg /*    (all 6 codes are OK); the first (MSD) must be 0 if df is a NaN  */
71036ac495dSmrg /*    and all digits must be 0 if df is infinite.  For DOUBLE and     */
71136ac495dSmrg /*    QUAD the first (pad) nibble must be 0.			      */
71236ac495dSmrg /*    All coefficient nibbles must be in 0-9 and sign in A-F.	      */
71336ac495dSmrg /*  returns df, which will be canonical or NULL if any of the	      */
71436ac495dSmrg /*    requirements are not met (if this case df is unchanged); that   */
71536ac495dSmrg /*    is, the input data must be as returned by decFloatToPacked,     */
71636ac495dSmrg /*    except that all six sign codes are accepted.		      */
71736ac495dSmrg /*								      */
71836ac495dSmrg /* No status will be set.					      */
71936ac495dSmrg /* ------------------------------------------------------------------ */
decFloatFromPackedChecked(decFloat * df,Int exp,const uByte * packed)72036ac495dSmrg decFloat * decFloatFromPackedChecked(decFloat *df, Int exp,
72136ac495dSmrg 				     const uByte *packed) {
72236ac495dSmrg   uByte bcdar[DECPMAX+2];		/* work [+1 for pad, +1 for sign] */
72336ac495dSmrg   const uByte *ip;			/* .. */
72436ac495dSmrg   uByte *op;				/* .. */
72536ac495dSmrg   Int	sig=0;				/* sign */
72636ac495dSmrg 
72736ac495dSmrg   /* expand coefficient and sign to BCDAR */
72836ac495dSmrg   #if SINGLE
72936ac495dSmrg   op=bcdar+1;				/* no pad digit */
73036ac495dSmrg   #else
73136ac495dSmrg   op=bcdar;				/* first (pad) digit here */
73236ac495dSmrg   #endif
73336ac495dSmrg   for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) {
73436ac495dSmrg     *op=*ip>>4;
73536ac495dSmrg     if (*op>9) return NULL;
73636ac495dSmrg     op++;
73736ac495dSmrg     *op=(uByte)(*ip&0x0f);		/* [final nibble is sign] */
73836ac495dSmrg     if (*op>9 && ip<packed+((DECPMAX+2)/2)-1) return NULL;
73936ac495dSmrg     op++;
74036ac495dSmrg     }
74136ac495dSmrg   op--; 				/* -> sign byte */
74236ac495dSmrg   if (*op<=9) return NULL;		/* bad sign */
74336ac495dSmrg   if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
74436ac495dSmrg 
74536ac495dSmrg   #if !SINGLE
74636ac495dSmrg   if (bcdar[0]!=0) return NULL; 	/* bad pad nibble */
74736ac495dSmrg   #endif
74836ac495dSmrg 
74936ac495dSmrg   if (EXPISNAN(exp)) {			/* a NaN */
75036ac495dSmrg     if (bcdar[1]!=0) return NULL;	/* bad msd */
75136ac495dSmrg     } /* NaN */
75236ac495dSmrg    else if (EXPISINF(exp)) {		/* is infinite */
75336ac495dSmrg     Int i;
75436ac495dSmrg     for (i=0; i<DECPMAX; i++) {
75536ac495dSmrg       if (bcdar[i+1]!=0) return NULL;	/* should be all zeros */
75636ac495dSmrg       }
75736ac495dSmrg     } /* infinity */
75836ac495dSmrg    else {				/* finite */
75936ac495dSmrg     /* check the exponent is in range */
76036ac495dSmrg     if (exp>DECEMAX-DECPMAX+1) return NULL;
76136ac495dSmrg     if (exp<DECEMIN-DECPMAX+1) return NULL;
76236ac495dSmrg     }
76336ac495dSmrg   return decFloatFromBCD(df, exp, bcdar+1, sig);
76436ac495dSmrg   } /* decFloatFromPacked */
76536ac495dSmrg 
76636ac495dSmrg /* ------------------------------------------------------------------ */
76736ac495dSmrg /* decFloatFromString -- conversion from numeric string 	      */
76836ac495dSmrg /*								      */
76936ac495dSmrg /*  result  is the decFloat format number which gets the result of    */
77036ac495dSmrg /*	    the conversion					      */
77136ac495dSmrg /*  *string is the character string which should contain a valid      */
77236ac495dSmrg /*	    number (which may be a special value), \0-terminated      */
77336ac495dSmrg /*	    If there are too many significant digits in the	      */
77436ac495dSmrg /*	    coefficient it will be rounded.			      */
77536ac495dSmrg /*  set     is the context					      */
77636ac495dSmrg /*  returns result						      */
77736ac495dSmrg /*								      */
77836ac495dSmrg /* The length of the coefficient and the size of the exponent are     */
77936ac495dSmrg /* checked by this routine, so the correct error (Underflow or	      */
78036ac495dSmrg /* Overflow) can be reported or rounding applied, as necessary.       */
78136ac495dSmrg /*								      */
78236ac495dSmrg /* There is no limit to the coefficient length for finite inputs;     */
78336ac495dSmrg /* NaN payloads must be integers with no more than DECPMAX-1 digits.  */
78436ac495dSmrg /* Exponents may have up to nine significant digits.		      */
78536ac495dSmrg /*								      */
78636ac495dSmrg /* If bad syntax is detected, the result will be a quiet NaN.	      */
78736ac495dSmrg /* ------------------------------------------------------------------ */
decFloatFromString(decFloat * result,const char * string,decContext * set)78836ac495dSmrg decFloat * decFloatFromString(decFloat *result, const char *string,
78936ac495dSmrg 			      decContext *set) {
79036ac495dSmrg   Int	 digits;		   /* count of digits in coefficient */
79136ac495dSmrg   const  char *dotchar=NULL;	   /* where dot was found [NULL if none] */
79236ac495dSmrg   const  char *cfirst=string;	   /* -> first character of decimal part */
79336ac495dSmrg   const  char *c;		   /* work */
79436ac495dSmrg   uByte *ub;			   /* .. */
79536ac495dSmrg   uInt	 uiwork;		   /* for macros */
79636ac495dSmrg   bcdnum num;			   /* collects data for finishing */
79736ac495dSmrg   uInt	 error=DEC_Conversion_syntax;	/* assume the worst */
79836ac495dSmrg   uByte  buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */
79936ac495dSmrg 				   /* some common rounding, +3, & pad */
80036ac495dSmrg   #if DECTRACE
80136ac495dSmrg   /* printf("FromString %s ...\n", string); */
80236ac495dSmrg   #endif
80336ac495dSmrg 
80436ac495dSmrg   for(;;) {				/* once-only 'loop' */
80536ac495dSmrg     num.sign=0; 			/* assume non-negative */
80636ac495dSmrg     num.msd=buffer;			/* MSD is here always */
80736ac495dSmrg 
80836ac495dSmrg     /* detect and validate the coefficient, including any leading, */
80936ac495dSmrg     /* trailing, or embedded '.' */
81036ac495dSmrg     /* [could test four-at-a-time here (saving 10% for decQuads), */
81136ac495dSmrg     /* but that risks storage violation because the position of the */
81236ac495dSmrg     /* terminator is unknown] */
81336ac495dSmrg     for (c=string;; c++) {		/* -> input character */
81436ac495dSmrg       if (((unsigned)(*c-'0'))<=9) continue; /* '0' through '9' is good */
81536ac495dSmrg       if (*c=='\0') break;		/* most common non-digit */
81636ac495dSmrg       if (*c=='.') {
81736ac495dSmrg 	if (dotchar!=NULL) break;	/* not first '.' */
81836ac495dSmrg 	dotchar=c;			/* record offset into decimal part */
81936ac495dSmrg 	continue;}
82036ac495dSmrg       if (c==string) {			/* first in string... */
82136ac495dSmrg 	if (*c=='-') {			/* valid - sign */
82236ac495dSmrg 	  cfirst++;
82336ac495dSmrg 	  num.sign=DECFLOAT_Sign;
82436ac495dSmrg 	  continue;}
82536ac495dSmrg 	if (*c=='+') {			/* valid + sign */
82636ac495dSmrg 	  cfirst++;
82736ac495dSmrg 	  continue;}
82836ac495dSmrg 	}
82936ac495dSmrg       /* *c is not a digit, terminator, or a valid +, -, or '.' */
83036ac495dSmrg       break;
83136ac495dSmrg       } /* c loop */
83236ac495dSmrg 
83336ac495dSmrg     digits=(uInt)(c-cfirst);		/* digits (+1 if a dot) */
83436ac495dSmrg 
83536ac495dSmrg     if (digits>0) {			/* had digits and/or dot */
83636ac495dSmrg       const char *clast=c-1;		/* note last coefficient char position */
83736ac495dSmrg       Int exp=0;			/* exponent accumulator */
83836ac495dSmrg       if (*c!='\0') {			/* something follows the coefficient */
83936ac495dSmrg 	uInt edig;			/* unsigned work */
84036ac495dSmrg 	/* had some digits and more to come; expect E[+|-]nnn now */
84136ac495dSmrg 	const char *firstexp;		/* exponent first non-zero */
84236ac495dSmrg 	if (*c!='E' && *c!='e') break;
84336ac495dSmrg 	c++;				/* to (optional) sign */
84436ac495dSmrg 	if (*c=='-' || *c=='+') c++;	/* step over sign (c=clast+2) */
84536ac495dSmrg 	if (*c=='\0') break;		/* no digits!  (e.g., '1.2E') */
84636ac495dSmrg 	for (; *c=='0';) c++;		/* skip leading zeros [even last] */
84736ac495dSmrg 	firstexp=c;			/* remember start [maybe '\0'] */
84836ac495dSmrg 	/* gather exponent digits */
84936ac495dSmrg 	edig=(uInt)*c-(uInt)'0';
85036ac495dSmrg 	if (edig<=9) {			/* [check not bad or terminator] */
85136ac495dSmrg 	  exp+=edig;			/* avoid initial X10 */
85236ac495dSmrg 	  c++;
85336ac495dSmrg 	  for (;; c++) {
85436ac495dSmrg 	    edig=(uInt)*c-(uInt)'0';
85536ac495dSmrg 	    if (edig>9) break;
85636ac495dSmrg 	    exp=exp*10+edig;
85736ac495dSmrg 	    }
85836ac495dSmrg 	  }
85936ac495dSmrg 	/* if not now on the '\0', *c must not be a digit */
86036ac495dSmrg 	if (*c!='\0') break;
86136ac495dSmrg 
86236ac495dSmrg 	/* (this next test must be after the syntax checks) */
86336ac495dSmrg 	/* if definitely more than the possible digits for format then */
86436ac495dSmrg 	/* the exponent may have wrapped, so simply set it to a certain */
86536ac495dSmrg 	/* over/underflow value */
86636ac495dSmrg 	if (c>firstexp+DECEMAXD) exp=DECEMAX*2;
86736ac495dSmrg 	if (*(clast+2)=='-') exp=-exp;	/* was negative */
86836ac495dSmrg 	} /* digits>0 */
86936ac495dSmrg 
87036ac495dSmrg       if (dotchar!=NULL) {		/* had a '.' */
87136ac495dSmrg 	digits--;			/* remove from digits count */
87236ac495dSmrg 	if (digits==0) break;		/* was dot alone: bad syntax */
87336ac495dSmrg 	exp-=(Int)(clast-dotchar);	/* adjust exponent */
87436ac495dSmrg 	/* [the '.' can now be ignored] */
87536ac495dSmrg 	}
87636ac495dSmrg       num.exponent=exp; 		/* exponent is good; store it */
87736ac495dSmrg 
87836ac495dSmrg       /* Here when whole string has been inspected and syntax is good */
87936ac495dSmrg       /* cfirst->first digit or dot, clast->last digit or dot */
88036ac495dSmrg       error=0;				/* no error possible now */
88136ac495dSmrg 
88236ac495dSmrg       /* if the number of digits in the coefficient will fit in buffer */
88336ac495dSmrg       /* then it can simply be converted to bcd8 and copied -- decFinalize */
88436ac495dSmrg       /* will take care of leading zeros and rounding; the buffer is big */
88536ac495dSmrg       /* enough for all canonical coefficients, including 0.00000nn... */
88636ac495dSmrg       ub=buffer;
88736ac495dSmrg       if (digits<=(Int)(sizeof(buffer)-3)) { /* [-3 allows by-4s copy] */
88836ac495dSmrg 	c=cfirst;
88936ac495dSmrg 	if (dotchar!=NULL) {		     /* a dot to worry about */
89036ac495dSmrg 	  if (*(c+1)=='.') {		     /* common canonical case */
89136ac495dSmrg 	    *ub++=(uByte)(*c-'0');	     /* copy leading digit */
89236ac495dSmrg 	    c+=2;			     /* prepare to handle rest */
89336ac495dSmrg 	    }
89436ac495dSmrg 	   else for (; c<=clast;) {	     /* '.' could be anywhere */
89536ac495dSmrg 	    /* as usual, go by fours when safe; NB it has been asserted */
89636ac495dSmrg 	    /* that a '.' does not have the same mask as a digit */
89736ac495dSmrg 	    if (c<=clast-3			       /* safe for four */
89836ac495dSmrg 	     && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) {    /* test four */
89936ac495dSmrg 	      UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);      /* to BCD8 */
90036ac495dSmrg 	      ub+=4;
90136ac495dSmrg 	      c+=4;
90236ac495dSmrg 	      continue;
90336ac495dSmrg 	      }
90436ac495dSmrg 	    if (*c=='.') {		     /* found the dot */
90536ac495dSmrg 	      c++;			     /* step over it .. */
90636ac495dSmrg 	      break;			     /* .. and handle the rest */
90736ac495dSmrg 	      }
90836ac495dSmrg 	    *ub++=(uByte)(*c++-'0');
90936ac495dSmrg 	    }
91036ac495dSmrg 	  } /* had dot */
91136ac495dSmrg 	/* Now no dot; do this by fours (where safe) */
91236ac495dSmrg 	for (; c<=clast-3; c+=4, ub+=4) UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);
91336ac495dSmrg 	for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0');
91436ac495dSmrg 	num.lsd=buffer+digits-1;	     /* record new LSD */
91536ac495dSmrg 	} /* fits */
91636ac495dSmrg 
91736ac495dSmrg        else {				     /* too long for buffer */
91836ac495dSmrg 	/* [This is a rare and unusual case; arbitrary-length input] */
91936ac495dSmrg 	/* strip leading zeros [but leave final 0 if all 0's] */
92036ac495dSmrg 	if (*cfirst=='.') cfirst++;	     /* step past dot at start */
92136ac495dSmrg 	if (*cfirst=='0') {		     /* [cfirst always -> digit] */
92236ac495dSmrg 	  for (; cfirst<clast; cfirst++) {
92336ac495dSmrg 	    if (*cfirst!='0') { 	     /* non-zero found */
92436ac495dSmrg 	      if (*cfirst=='.') continue;    /* [ignore] */
92536ac495dSmrg 	      break;			     /* done */
92636ac495dSmrg 	      }
92736ac495dSmrg 	    digits--;			     /* 0 stripped */
92836ac495dSmrg 	    } /* cfirst */
92936ac495dSmrg 	  } /* at least one leading 0 */
93036ac495dSmrg 
93136ac495dSmrg 	/* the coefficient is now as short as possible, but may still */
93236ac495dSmrg 	/* be too long; copy up to Pmax+1 digits to the buffer, then */
93336ac495dSmrg 	/* just record any non-zeros (set round-for-reround digit) */
93436ac495dSmrg 	for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
93536ac495dSmrg 	  /* (see commentary just above) */
93636ac495dSmrg 	  if (c<=clast-3			  /* safe for four */
93736ac495dSmrg 	   && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
93836ac495dSmrg 	    UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);   /* to BCD8 */
93936ac495dSmrg 	    ub+=4;
94036ac495dSmrg 	    c+=3;			     /* [will become 4] */
94136ac495dSmrg 	    continue;
94236ac495dSmrg 	    }
94336ac495dSmrg 	  if (*c=='.') continue;	     /* [ignore] */
94436ac495dSmrg 	  *ub++=(uByte)(*c-'0');
94536ac495dSmrg 	  }
94636ac495dSmrg 	ub--;				     /* -> LSD */
94736ac495dSmrg 	for (; c<=clast; c++) { 	     /* inspect remaining chars */
94836ac495dSmrg 	  if (*c!='0') {		     /* sticky bit needed */
94936ac495dSmrg 	    if (*c=='.') continue;	     /* [ignore] */
95036ac495dSmrg 	    *ub=DECSTICKYTAB[*ub];	     /* update round-for-reround */
95136ac495dSmrg 	    break;			     /* no need to look at more */
95236ac495dSmrg 	    }
95336ac495dSmrg 	  }
95436ac495dSmrg 	num.lsd=ub;			     /* record LSD */
95536ac495dSmrg 	/* adjust exponent for dropped digits */
95636ac495dSmrg 	num.exponent+=digits-(Int)(ub-buffer+1);
95736ac495dSmrg 	} /* too long for buffer */
95836ac495dSmrg       } /* digits or dot */
95936ac495dSmrg 
96036ac495dSmrg      else {				/* no digits or dot were found */
96136ac495dSmrg       if (*c=='\0') break;		/* nothing to come is bad */
96236ac495dSmrg       /* only Infinities and NaNs are allowed, here */
96336ac495dSmrg       buffer[0]=0;			/* default a coefficient of 0 */
96436ac495dSmrg       num.lsd=buffer;			/* .. */
96536ac495dSmrg       if (decBiStr(c, "infinity", "INFINITY")
96636ac495dSmrg        || decBiStr(c, "inf", "INF")) num.exponent=DECFLOAT_Inf;
96736ac495dSmrg        else {				/* should be a NaN */
96836ac495dSmrg 	num.exponent=DECFLOAT_qNaN;	/* assume quiet NaN */
96936ac495dSmrg 	if (*c=='s' || *c=='S') {	/* probably an sNaN */
97036ac495dSmrg 	  c++;
97136ac495dSmrg 	  num.exponent=DECFLOAT_sNaN;	/* assume is in fact sNaN */
97236ac495dSmrg 	  }
97336ac495dSmrg 	if (*c!='N' && *c!='n') break;	/* check caseless "NaN" */
97436ac495dSmrg 	c++;
97536ac495dSmrg 	if (*c!='a' && *c!='A') break;	/* .. */
97636ac495dSmrg 	c++;
97736ac495dSmrg 	if (*c!='N' && *c!='n') break;	/* .. */
97836ac495dSmrg 	c++;
97936ac495dSmrg 	/* now either nothing, or nnnn payload (no dots), expected */
98036ac495dSmrg 	/* -> start of integer, and skip leading 0s [including plain 0] */
98136ac495dSmrg 	for (cfirst=c; *cfirst=='0';) cfirst++;
98236ac495dSmrg 	if (*cfirst!='\0') {		/* not empty or all-0, payload */
98336ac495dSmrg 	  /* payload found; check all valid digits and copy to buffer as bcd8 */
98436ac495dSmrg 	  ub=buffer;
98536ac495dSmrg 	  for (c=cfirst;; c++, ub++) {
98636ac495dSmrg 	    if ((unsigned)(*c-'0')>9) break; /* quit if not 0-9 */
98736ac495dSmrg 	    if (c-cfirst==DECPMAX-1) break;  /* too many digits */
98836ac495dSmrg 	    *ub=(uByte)(*c-'0');	/* good bcd8 */
98936ac495dSmrg 	    }
99036ac495dSmrg 	  if (*c!='\0') break;		/* not all digits, or too many */
99136ac495dSmrg 	  num.lsd=ub-1; 		/* record new LSD */
99236ac495dSmrg 	  }
99336ac495dSmrg 	} /* NaN or sNaN */
99436ac495dSmrg       error=0;				/* syntax is OK */
99536ac495dSmrg       break;				/* done with specials */
99636ac495dSmrg       } /* digits=0 (special expected) */
99736ac495dSmrg     break;
99836ac495dSmrg     }					/* [for(;;) break] */
99936ac495dSmrg 
100036ac495dSmrg   /* decShowNum(&num, "fromStr"); */
100136ac495dSmrg 
100236ac495dSmrg   if (error!=0) {
100336ac495dSmrg     set->status|=error;
100436ac495dSmrg     num.exponent=DECFLOAT_qNaN; 	/* set up quiet NaN */
100536ac495dSmrg     num.sign=0; 			/* .. with 0 sign */
100636ac495dSmrg     buffer[0]=0;			/* .. and coefficient */
100736ac495dSmrg     num.lsd=buffer;			/* .. */
100836ac495dSmrg     /* decShowNum(&num, "oops"); */
100936ac495dSmrg     }
101036ac495dSmrg 
101136ac495dSmrg   /* decShowNum(&num, "dffs"); */
101236ac495dSmrg   decFinalize(result, &num, set);	/* round, check, and lay out */
101336ac495dSmrg   /* decFloatShow(result, "fromString"); */
101436ac495dSmrg   return result;
101536ac495dSmrg   } /* decFloatFromString */
101636ac495dSmrg 
101736ac495dSmrg /* ------------------------------------------------------------------ */
101836ac495dSmrg /* decFloatFromWider -- conversion from next-wider format	      */
101936ac495dSmrg /*								      */
102036ac495dSmrg /*  result  is the decFloat format number which gets the result of    */
102136ac495dSmrg /*	    the conversion					      */
102236ac495dSmrg /*  wider   is the decFloatWider format number which will be narrowed */
102336ac495dSmrg /*  set     is the context					      */
102436ac495dSmrg /*  returns result						      */
102536ac495dSmrg /*								      */
102636ac495dSmrg /* Narrowing can cause rounding, overflow, etc., but not Invalid      */
102736ac495dSmrg /* operation (sNaNs are copied and do not signal).		      */
102836ac495dSmrg /* ------------------------------------------------------------------ */
102936ac495dSmrg /* narrow-to is not possible for decQuad format numbers; simply omit */
103036ac495dSmrg #if !QUAD
decFloatFromWider(decFloat * result,const decFloatWider * wider,decContext * set)103136ac495dSmrg decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
103236ac495dSmrg 			     decContext *set) {
103336ac495dSmrg   bcdnum num;				/* collects data for finishing */
103436ac495dSmrg   uByte  bcdar[DECWPMAX];		/* room for wider coefficient */
103536ac495dSmrg   uInt	 widerhi=DFWWORD(wider, 0);	/* top word */
103636ac495dSmrg   Int	 exp;
103736ac495dSmrg 
103836ac495dSmrg   GETWCOEFF(wider, bcdar);
103936ac495dSmrg 
104036ac495dSmrg   num.msd=bcdar;			/* MSD is here always */
104136ac495dSmrg   num.lsd=bcdar+DECWPMAX-1;		/* LSD is here always */
104236ac495dSmrg   num.sign=widerhi&0x80000000;		/* extract sign [DECFLOAT_Sign=Neg] */
104336ac495dSmrg 
104436ac495dSmrg   /* decode the wider combination field to exponent */
104536ac495dSmrg   exp=DECCOMBWEXP[widerhi>>26]; 	/* decode from wider combination field */
104636ac495dSmrg   /* if it is a special there's nothing to do unless sNaN; if it's */
104736ac495dSmrg   /* finite then add the (wider) exponent continuation and unbias */
104836ac495dSmrg   if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */
104936ac495dSmrg    else exp+=GETWECON(wider)-DECWBIAS;
105036ac495dSmrg   num.exponent=exp;
105136ac495dSmrg 
105236ac495dSmrg   /* decShowNum(&num, "dffw"); */
105336ac495dSmrg   return decFinalize(result, &num, set);/* round, check, and lay out */
105436ac495dSmrg   } /* decFloatFromWider */
105536ac495dSmrg #endif
105636ac495dSmrg 
105736ac495dSmrg /* ------------------------------------------------------------------ */
105836ac495dSmrg /* decFloatGetCoefficient -- get coefficient as BCD8		      */
105936ac495dSmrg /*								      */
106036ac495dSmrg /*  df is the decFloat from which to extract the coefficient	      */
106136ac495dSmrg /*  bcdar is where DECPMAX bytes will be written, one BCD digit in    */
106236ac495dSmrg /*    each byte (BCD8 encoding); if df is a NaN the first byte will   */
106336ac495dSmrg /*    be zero, and if it is infinite they will all be zero	      */
106436ac495dSmrg /*  returns the sign of the coefficient (DECFLOAT_Sign if negative,   */
106536ac495dSmrg /*    0 otherwise)						      */
106636ac495dSmrg /*								      */
106736ac495dSmrg /* No error is possible, and no status will be set.  If df is a       */
106836ac495dSmrg /* special value the array is set to zeros (for Infinity) or to the   */
106936ac495dSmrg /* payload of a qNaN or sNaN.					      */
107036ac495dSmrg /* ------------------------------------------------------------------ */
decFloatGetCoefficient(const decFloat * df,uByte * bcdar)107136ac495dSmrg Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) {
107236ac495dSmrg   if (DFISINF(df)) memset(bcdar, 0, DECPMAX);
107336ac495dSmrg    else {
107436ac495dSmrg     GETCOEFF(df, bcdar);	   /* use macro */
107536ac495dSmrg     if (DFISNAN(df)) bcdar[0]=0;   /* MSD needs correcting */
107636ac495dSmrg     }
107736ac495dSmrg   return DFISSIGNED(df);
107836ac495dSmrg   } /* decFloatGetCoefficient */
107936ac495dSmrg 
108036ac495dSmrg /* ------------------------------------------------------------------ */
108136ac495dSmrg /* decFloatGetExponent -- get unbiased exponent 		      */
108236ac495dSmrg /*								      */
108336ac495dSmrg /*  df is the decFloat from which to extract the exponent	      */
108436ac495dSmrg /*  returns the exponent, q.					      */
108536ac495dSmrg /*								      */
108636ac495dSmrg /* No error is possible, and no status will be set.  If df is a       */
108736ac495dSmrg /* special value the first seven bits of the decFloat are returned,   */
108836ac495dSmrg /* left adjusted and with the first (sign) bit set to 0 (followed by  */
108936ac495dSmrg /* 25 0 bits).	e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN).  */
109036ac495dSmrg /* ------------------------------------------------------------------ */
decFloatGetExponent(const decFloat * df)109136ac495dSmrg Int decFloatGetExponent(const decFloat *df) {
109236ac495dSmrg   if (DFISSPECIAL(df)) return DFWORD(df, 0)&0x7e000000;
109336ac495dSmrg   return GETEXPUN(df);
109436ac495dSmrg   } /* decFloatGetExponent */
109536ac495dSmrg 
109636ac495dSmrg /* ------------------------------------------------------------------ */
109736ac495dSmrg /* decFloatSetCoefficient -- set coefficient from BCD8		      */
109836ac495dSmrg /*								      */
109936ac495dSmrg /*  df is the target decFloat (and source of exponent/special value)  */
110036ac495dSmrg /*  bcdar holds DECPMAX digits to set the coefficient from, one       */
110136ac495dSmrg /*    digit in each byte (BCD8 encoding); the first (MSD) is ignored  */
110236ac495dSmrg /*    if df is a NaN; all are ignored if df is infinite.	      */
110336ac495dSmrg /*  sig is DECFLOAT_Sign to set the sign bit, 0 otherwise	      */
110436ac495dSmrg /*  returns df, which will be canonical 			      */
110536ac495dSmrg /*								      */
110636ac495dSmrg /* No error is possible, and no status will be set.		      */
110736ac495dSmrg /* ------------------------------------------------------------------ */
decFloatSetCoefficient(decFloat * df,const uByte * bcdar,Int sig)110836ac495dSmrg decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar,
110936ac495dSmrg 				  Int sig) {
111036ac495dSmrg   uInt exp;			   /* for exponent */
111136ac495dSmrg   uByte bcdzero[DECPMAX];	   /* for infinities */
111236ac495dSmrg 
111336ac495dSmrg   /* Exponent/special code is extracted from df */
111436ac495dSmrg   if (DFISSPECIAL(df)) {
111536ac495dSmrg     exp=DFWORD(df, 0)&0x7e000000;
111636ac495dSmrg     if (DFISINF(df)) {
111736ac495dSmrg       memset(bcdzero, 0, DECPMAX);
111836ac495dSmrg       return decFloatFromBCD(df, exp, bcdzero, sig);
111936ac495dSmrg       }
112036ac495dSmrg     }
112136ac495dSmrg    else exp=GETEXPUN(df);
112236ac495dSmrg   return decFloatFromBCD(df, exp, bcdar, sig);
112336ac495dSmrg   } /* decFloatSetCoefficient */
112436ac495dSmrg 
112536ac495dSmrg /* ------------------------------------------------------------------ */
112636ac495dSmrg /* decFloatSetExponent -- set exponent or special value 	      */
112736ac495dSmrg /*								      */
112836ac495dSmrg /*  df	is the target decFloat (and source of coefficient/payload)    */
112936ac495dSmrg /*  set is the context for reporting status			      */
113036ac495dSmrg /*  exp is the unbiased exponent, q, or a special value in the form   */
113136ac495dSmrg /*    returned by decFloatGetExponent				      */
113236ac495dSmrg /*  returns df, which will be canonical 			      */
113336ac495dSmrg /*								      */
113436ac495dSmrg /* No error is possible, but Overflow or Underflow might occur.       */
113536ac495dSmrg /* ------------------------------------------------------------------ */
decFloatSetExponent(decFloat * df,decContext * set,Int exp)113636ac495dSmrg decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) {
113736ac495dSmrg   uByte  bcdcopy[DECPMAX];	   /* for coefficient */
113836ac495dSmrg   bcdnum num;			   /* work */
113936ac495dSmrg   num.exponent=exp;
114036ac495dSmrg   num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */
114136ac495dSmrg   if (DFISSPECIAL(df)) {	   /* MSD or more needs correcting */
114236ac495dSmrg     if (DFISINF(df)) memset(bcdcopy, 0, DECPMAX);
114336ac495dSmrg     bcdcopy[0]=0;
114436ac495dSmrg     }
114536ac495dSmrg   num.msd=bcdcopy;
114636ac495dSmrg   num.lsd=bcdcopy+DECPMAX-1;
114736ac495dSmrg   return decFinalize(df, &num, set);
114836ac495dSmrg   } /* decFloatSetExponent */
114936ac495dSmrg 
115036ac495dSmrg /* ------------------------------------------------------------------ */
115136ac495dSmrg /* decFloatRadix -- returns the base (10)			      */
115236ac495dSmrg /*								      */
115336ac495dSmrg /*   df is any decFloat of this format				      */
115436ac495dSmrg /* ------------------------------------------------------------------ */
decFloatRadix(const decFloat * df)115536ac495dSmrg uInt decFloatRadix(const decFloat *df) {
115636ac495dSmrg   if (df) return 10;			     /* to placate compiler */
115736ac495dSmrg   return 10;
115836ac495dSmrg   } /* decFloatRadix */
115936ac495dSmrg 
116036ac495dSmrg #if (DECCHECK || DECTRACE)
116136ac495dSmrg /* ------------------------------------------------------------------ */
116236ac495dSmrg /* decFloatShow -- printf a decFloat in hexadecimal and decimal       */
116336ac495dSmrg /*   df  is the decFloat to show				      */
116436ac495dSmrg /*   tag is a tag string displayed with the number		      */
116536ac495dSmrg /*								      */
116636ac495dSmrg /* This is a debug aid; the precise format of the string may change.  */
116736ac495dSmrg /* ------------------------------------------------------------------ */
decFloatShow(const decFloat * df,const char * tag)116836ac495dSmrg void decFloatShow(const decFloat *df, const char *tag) {
116936ac495dSmrg   char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */
117036ac495dSmrg   char buff[DECSTRING]; 		/* for value in decimal */
117136ac495dSmrg   Int i, j=0;
117236ac495dSmrg 
117336ac495dSmrg   for (i=0; i<DECBYTES; i++) {
117436ac495dSmrg     #if DECLITEND
117536ac495dSmrg       sprintf(&hexbuf[j], "%02x", df->bytes[DECBYTES-1-i]);
117636ac495dSmrg     #else
117736ac495dSmrg       sprintf(&hexbuf[j], "%02x", df->bytes[i]);
117836ac495dSmrg     #endif
117936ac495dSmrg     j+=2;
118036ac495dSmrg     /* the next line adds blank (and terminator) after final pair, too */
118136ac495dSmrg     if ((i+1)%4==0) {strcpy(&hexbuf[j], " "); j++;}
118236ac495dSmrg     }
118336ac495dSmrg   decFloatToString(df, buff);
118436ac495dSmrg   printf(">%s> %s [big-endian]	%s\n", tag, hexbuf, buff);
118536ac495dSmrg   return;
118636ac495dSmrg   } /* decFloatShow */
118736ac495dSmrg #endif
118836ac495dSmrg 
118936ac495dSmrg /* ------------------------------------------------------------------ */
119036ac495dSmrg /* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat      */
119136ac495dSmrg /*								      */
119236ac495dSmrg /*  df is the source decFloat					      */
119336ac495dSmrg /*  exp will be set to the unbiased exponent, q, or to a special      */
119436ac495dSmrg /*    value in the form returned by decFloatGetExponent 	      */
119536ac495dSmrg /*  bcdar is where DECPMAX bytes will be written, one BCD digit in    */
119636ac495dSmrg /*    each byte (BCD8 encoding); if df is a NaN the first byte will   */
119736ac495dSmrg /*    be zero, and if it is infinite they will all be zero	      */
119836ac495dSmrg /*  returns the sign of the coefficient (DECFLOAT_Sign if negative,   */
119936ac495dSmrg /*    0 otherwise)						      */
120036ac495dSmrg /*								      */
120136ac495dSmrg /* No error is possible, and no status will be set.		      */
120236ac495dSmrg /* ------------------------------------------------------------------ */
decFloatToBCD(const decFloat * df,Int * exp,uByte * bcdar)120336ac495dSmrg Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) {
120436ac495dSmrg   if (DFISINF(df)) {
120536ac495dSmrg     memset(bcdar, 0, DECPMAX);
120636ac495dSmrg     *exp=DFWORD(df, 0)&0x7e000000;
120736ac495dSmrg     }
120836ac495dSmrg    else {
120936ac495dSmrg     GETCOEFF(df, bcdar);	   /* use macro */
121036ac495dSmrg     if (DFISNAN(df)) {
121136ac495dSmrg       bcdar[0]=0;		   /* MSD needs correcting */
121236ac495dSmrg       *exp=DFWORD(df, 0)&0x7e000000;
121336ac495dSmrg       }
121436ac495dSmrg      else {			   /* finite */
121536ac495dSmrg       *exp=GETEXPUN(df);
121636ac495dSmrg       }
121736ac495dSmrg     }
121836ac495dSmrg   return DFISSIGNED(df);
121936ac495dSmrg   } /* decFloatToBCD */
122036ac495dSmrg 
122136ac495dSmrg /* ------------------------------------------------------------------ */
122236ac495dSmrg /* decFloatToEngString -- conversion to numeric string, engineering   */
122336ac495dSmrg /*								      */
122436ac495dSmrg /*  df is the decFloat format number to convert 		      */
122536ac495dSmrg /*  string is the string where the result will be laid out	      */
122636ac495dSmrg /*								      */
122736ac495dSmrg /* string must be at least DECPMAX+9 characters (the worst case is    */
122836ac495dSmrg /* "-0.00000nnn...nnn\0", which is as long as the exponent form when  */
122936ac495dSmrg /* DECEMAXD<=4); this condition is asserted above		      */
123036ac495dSmrg /*								      */
123136ac495dSmrg /* No error is possible, and no status will be set		      */
123236ac495dSmrg /* ------------------------------------------------------------------ */
decFloatToEngString(const decFloat * df,char * string)123336ac495dSmrg char * decFloatToEngString(const decFloat *df, char *string){
123436ac495dSmrg   uInt msd;			   /* coefficient MSD */
123536ac495dSmrg   Int  exp;			   /* exponent top two bits or full */
123636ac495dSmrg   uInt comb;			   /* combination field */
123736ac495dSmrg   char *cstart; 		   /* coefficient start */
123836ac495dSmrg   char *c;			   /* output pointer in string */
123936ac495dSmrg   char *s, *t;			   /* .. (source, target) */
124036ac495dSmrg   Int  pre, e;			   /* work */
124136ac495dSmrg   const uByte *u;		   /* .. */
124236ac495dSmrg   uInt	uiwork; 		   /* for macros [one compiler needs */
124336ac495dSmrg 				   /* volatile here to avoid bug, but */
124436ac495dSmrg 				   /* that doubles execution time] */
124536ac495dSmrg 
124636ac495dSmrg   /* Source words; macro handles endianness */
124736ac495dSmrg   uInt sourhi=DFWORD(df, 0);	   /* word with sign */
124836ac495dSmrg   #if DECPMAX==16
124936ac495dSmrg   uInt sourlo=DFWORD(df, 1);
125036ac495dSmrg   #elif DECPMAX==34
125136ac495dSmrg   uInt sourmh=DFWORD(df, 1);
125236ac495dSmrg   uInt sourml=DFWORD(df, 2);
125336ac495dSmrg   uInt sourlo=DFWORD(df, 3);
125436ac495dSmrg   #endif
125536ac495dSmrg 
125636ac495dSmrg   c=string;			   /* where result will go */
125736ac495dSmrg   if (((Int)sourhi)<0) *c++='-';   /* handle sign */
125836ac495dSmrg   comb=sourhi>>26;		   /* sign+combination field */
125936ac495dSmrg   msd=DECCOMBMSD[comb]; 	   /* decode the combination field */
126036ac495dSmrg   exp=DECCOMBEXP[comb]; 	   /* .. */
126136ac495dSmrg 
126236ac495dSmrg   if (EXPISSPECIAL(exp)) {	   /* special */
126336ac495dSmrg     if (exp==DECFLOAT_Inf) {	   /* infinity */
126436ac495dSmrg       strcpy(c,   "Inf");
126536ac495dSmrg       strcpy(c+3, "inity");
126636ac495dSmrg       return string;		   /* easy */
126736ac495dSmrg       }
126836ac495dSmrg     if (sourhi&0x02000000) *c++='s'; /* sNaN */
126936ac495dSmrg     strcpy(c, "NaN");		   /* complete word */
127036ac495dSmrg     c+=3;			   /* step past */
127136ac495dSmrg     /* quick exit if the payload is zero */
127236ac495dSmrg     #if DECPMAX==7
127336ac495dSmrg     if ((sourhi&0x000fffff)==0) return string;
127436ac495dSmrg     #elif DECPMAX==16
127536ac495dSmrg     if (sourlo==0 && (sourhi&0x0003ffff)==0) return string;
127636ac495dSmrg     #elif DECPMAX==34
127736ac495dSmrg     if (sourlo==0 && sourml==0 && sourmh==0
127836ac495dSmrg      && (sourhi&0x00003fff)==0) return string;
127936ac495dSmrg     #endif
128036ac495dSmrg     /* otherwise drop through to add integer; set correct exp etc. */
128136ac495dSmrg     exp=0; msd=0;		   /* setup for following code */
128236ac495dSmrg     }
128336ac495dSmrg    else { /* complete exponent; top two bits are in place */
128436ac495dSmrg     exp+=GETECON(df)-DECBIAS;	   /* .. + continuation and unbias */
128536ac495dSmrg     }
128636ac495dSmrg 
128736ac495dSmrg   /* convert the digits of the significand to characters */
128836ac495dSmrg   cstart=c;			   /* save start of coefficient */
128936ac495dSmrg   if (msd) *c++=(char)('0'+(char)msd);	/* non-zero most significant digit */
129036ac495dSmrg 
129136ac495dSmrg   /* Decode the declets.  After extracting each declet, it is */
129236ac495dSmrg   /* decoded to a 4-uByte sequence by table lookup; the four uBytes */
129336ac495dSmrg   /* are the three encoded BCD8 digits followed by a 1-byte length */
129436ac495dSmrg   /* (significant digits, except that 000 has length 0).  This allows */
129536ac495dSmrg   /* us to left-align the first declet with non-zero content, then */
129636ac495dSmrg   /* the remaining ones are full 3-char length.  Fixed-length copies */
129736ac495dSmrg   /* are used because variable-length memcpy causes a subroutine call */
129836ac495dSmrg   /* in at least two compilers.  (The copies are length 4 for speed */
129936ac495dSmrg   /* and are safe because the last item in the array is of length */
130036ac495dSmrg   /* three and has the length byte following.) */
130136ac495dSmrg   #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4];	 \
130236ac495dSmrg 	 if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
130336ac495dSmrg 	  else if (*(u+3)) {					 \
130436ac495dSmrg 	   UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
130536ac495dSmrg 
130636ac495dSmrg   #if DECPMAX==7
130736ac495dSmrg   dpd2char(sourhi>>10); 		/* declet 1 */
130836ac495dSmrg   dpd2char(sourhi);			/* declet 2 */
130936ac495dSmrg 
131036ac495dSmrg   #elif DECPMAX==16
131136ac495dSmrg   dpd2char(sourhi>>8);			/* declet 1 */
131236ac495dSmrg   dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
131336ac495dSmrg   dpd2char(sourlo>>20); 		/* declet 3 */
131436ac495dSmrg   dpd2char(sourlo>>10); 		/* declet 4 */
131536ac495dSmrg   dpd2char(sourlo);			/* declet 5 */
131636ac495dSmrg 
131736ac495dSmrg   #elif DECPMAX==34
131836ac495dSmrg   dpd2char(sourhi>>4);			/* declet 1 */
131936ac495dSmrg   dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
132036ac495dSmrg   dpd2char(sourmh>>16); 		/* declet 3 */
132136ac495dSmrg   dpd2char(sourmh>>6);			/* declet 4 */
132236ac495dSmrg   dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
132336ac495dSmrg   dpd2char(sourml>>18); 		/* declet 6 */
132436ac495dSmrg   dpd2char(sourml>>8);			/* declet 7 */
132536ac495dSmrg   dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
132636ac495dSmrg   dpd2char(sourlo>>20); 		/* declet 9 */
132736ac495dSmrg   dpd2char(sourlo>>10); 		/* declet 10 */
132836ac495dSmrg   dpd2char(sourlo);			/* declet 11 */
132936ac495dSmrg   #endif
133036ac495dSmrg 
133136ac495dSmrg   if (c==cstart) *c++='0';	   /* all zeros, empty -- make "0" */
133236ac495dSmrg 
133336ac495dSmrg   if (exp==0) { 		   /* integer or NaN case -- easy */
133436ac495dSmrg     *c='\0';			   /* terminate */
133536ac495dSmrg     return string;
133636ac495dSmrg     }
133736ac495dSmrg   /* non-0 exponent */
133836ac495dSmrg 
133936ac495dSmrg   e=0;				   /* assume no E */
134036ac495dSmrg   pre=(Int)(c-cstart)+exp;	   /* length+exp  [c->LSD+1] */
134136ac495dSmrg   /* [here, pre-exp is the digits count (==1 for zero)] */
134236ac495dSmrg 
134336ac495dSmrg   if (exp>0 || pre<-5) {	   /* need exponential form */
134436ac495dSmrg     e=pre-1;			   /* calculate E value */
134536ac495dSmrg     pre=1;			   /* assume one digit before '.' */
134636ac495dSmrg     if (e!=0) { 		   /* engineering: may need to adjust */
134736ac495dSmrg       Int adj;			   /* adjustment */
134836ac495dSmrg       /* The C remainder operator is undefined for negative numbers, so */
134936ac495dSmrg       /* a positive remainder calculation must be used here */
135036ac495dSmrg       if (e<0) {
135136ac495dSmrg 	adj=(-e)%3;
135236ac495dSmrg 	if (adj!=0) adj=3-adj;
135336ac495dSmrg 	}
135436ac495dSmrg        else { /* e>0 */
135536ac495dSmrg 	adj=e%3;
135636ac495dSmrg 	}
135736ac495dSmrg       e=e-adj;
135836ac495dSmrg       /* if dealing with zero still produce an exponent which is a */
135936ac495dSmrg       /* multiple of three, as expected, but there will only be the */
136036ac495dSmrg       /* one zero before the E, still.	Otherwise note the padding. */
136136ac495dSmrg       if (!DFISZERO(df)) pre+=adj;
136236ac495dSmrg        else {  /* is zero */
136336ac495dSmrg 	if (adj!=0) {		   /* 0.00Esnn needed */
136436ac495dSmrg 	  e=e+3;
136536ac495dSmrg 	  pre=-(2-adj);
136636ac495dSmrg 	  }
136736ac495dSmrg 	} /* zero */
136836ac495dSmrg       } /* engineering adjustment */
136936ac495dSmrg     } /* exponential form */
137036ac495dSmrg   /* printf("e=%ld pre=%ld exp=%ld\n", (LI)e, (LI)pre, (LI)exp); */
137136ac495dSmrg 
137236ac495dSmrg   /* modify the coefficient, adding 0s, '.', and E+nn as needed */
137336ac495dSmrg   if (pre>0) {			   /* ddd.ddd (plain), perhaps with E */
137436ac495dSmrg 				   /* or dd00 padding for engineering */
137536ac495dSmrg     char *dotat=cstart+pre;
137636ac495dSmrg     if (dotat<c) {			/* if embedded dot needed... */
137736ac495dSmrg       /* move by fours; there must be space for junk at the end */
137836ac495dSmrg       /* because there is still space for exponent */
137936ac495dSmrg       s=dotat+ROUNDDOWN4(c-dotat);	/* source */
138036ac495dSmrg       t=s+1;				/* target */
138136ac495dSmrg       /* open the gap [cannot use memcpy] */
138236ac495dSmrg       for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
138336ac495dSmrg       *dotat='.';
138436ac495dSmrg       c++;				/* length increased by one */
138536ac495dSmrg       } /* need dot? */
138636ac495dSmrg      else for (; c<dotat; c++) *c='0';	/* pad for engineering */
138736ac495dSmrg     } /* pre>0 */
138836ac495dSmrg    else {
138936ac495dSmrg     /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have
139036ac495dSmrg        E, but only for 0.00E+3 kind of case -- with plenty of spare
139136ac495dSmrg        space in this case */
139236ac495dSmrg     pre=-pre+2; 			/* gap width, including "0." */
139336ac495dSmrg     t=cstart+ROUNDDOWN4(c-cstart)+pre;	/* preferred first target point */
139436ac495dSmrg     /* backoff if too far to the right */
139536ac495dSmrg     if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
139636ac495dSmrg     /* now shift the entire coefficient to the right, being careful not */
139736ac495dSmrg     /* to access to the left of string [cannot use memcpy] */
139836ac495dSmrg     for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
139936ac495dSmrg     /* for Quads and Singles there may be a character or two left... */
140036ac495dSmrg     s+=3;				/* where next would come from */
140136ac495dSmrg     for(; s>=cstart; s--, t--) *(t+3)=*(s);
140236ac495dSmrg     /* now have fill 0. through 0.00000; use overlaps to avoid tests */
140336ac495dSmrg     if (pre>=4) {
140436ac495dSmrg       memcpy(cstart+pre-4, "0000", 4);
140536ac495dSmrg       memcpy(cstart, "0.00", 4);
140636ac495dSmrg       }
140736ac495dSmrg      else { /* 2 or 3 */
140836ac495dSmrg       *(cstart+pre-1)='0';
140936ac495dSmrg       memcpy(cstart, "0.", 2);
141036ac495dSmrg       }
141136ac495dSmrg     c+=pre;				/* to end */
141236ac495dSmrg     }
141336ac495dSmrg 
141436ac495dSmrg   /* finally add the E-part, if needed; it will never be 0, and has */
141536ac495dSmrg   /* a maximum length of 3 or 4 digits (asserted above) */
141636ac495dSmrg   if (e!=0) {
141736ac495dSmrg     memcpy(c, "E+", 2); 		/* starts with E, assume + */
141836ac495dSmrg     c++;
141936ac495dSmrg     if (e<0) {
142036ac495dSmrg       *c='-';				/* oops, need '-' */
142136ac495dSmrg       e=-e;				/* uInt, please */
142236ac495dSmrg       }
142336ac495dSmrg     c++;
142436ac495dSmrg     /* Three-character exponents are easy; 4-character a little trickier */
142536ac495dSmrg     #if DECEMAXD<=3
142636ac495dSmrg       u=&BIN2BCD8[e*4]; 		/* -> 3 digits + length byte */
142736ac495dSmrg       /* copy fixed 4 characters [is safe], starting at non-zero */
142836ac495dSmrg       /* and with character mask to convert BCD to char */
142936ac495dSmrg       UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
143036ac495dSmrg       c+=*(u+3);			/* bump pointer appropriately */
143136ac495dSmrg     #elif DECEMAXD==4
143236ac495dSmrg       if (e<1000) {			/* 3 (or fewer) digits case */
143336ac495dSmrg 	u=&BIN2BCD8[e*4];		/* -> 3 digits + length byte */
143436ac495dSmrg 	UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
143536ac495dSmrg 	c+=*(u+3);			/* bump pointer appropriately */
143636ac495dSmrg 	}
143736ac495dSmrg        else {				/* 4-digits */
143836ac495dSmrg 	Int thou=((e>>3)*1049)>>17;	/* e/1000 */
143936ac495dSmrg 	Int rem=e-(1000*thou);		/* e%1000 */
144036ac495dSmrg 	*c++=(char)('0'+(char)thou);	/* the thousands digit */
144136ac495dSmrg 	u=&BIN2BCD8[rem*4];		/* -> 3 digits + length byte */
144236ac495dSmrg 	UBFROMUI(c, UBTOUI(u)|CHARMASK);/* copy fixed 3+1 characters [is safe] */
144336ac495dSmrg 	c+=3;				/* bump pointer, always 3 digits */
144436ac495dSmrg 	}
144536ac495dSmrg     #endif
144636ac495dSmrg     }
144736ac495dSmrg   *c='\0';				/* terminate */
144836ac495dSmrg   /*printf("res %s\n", string); */
144936ac495dSmrg   return string;
145036ac495dSmrg   } /* decFloatToEngString */
145136ac495dSmrg 
145236ac495dSmrg /* ------------------------------------------------------------------ */
145336ac495dSmrg /* decFloatToPacked -- convert decFloat to Packed decimal + exponent  */
145436ac495dSmrg /*								      */
145536ac495dSmrg /*  df is the source decFloat					      */
145636ac495dSmrg /*  exp will be set to the unbiased exponent, q, or to a special      */
145736ac495dSmrg /*    value in the form returned by decFloatGetExponent 	      */
145836ac495dSmrg /*  packed is where DECPMAX nibbles will be written with the sign as  */
145936ac495dSmrg /*    final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */
146036ac495dSmrg /*    of zero, and an infinity is all zeros. decDouble and decQuad    */
146136ac495dSmrg /*    have a additional leading zero nibble, leading to result	      */
146236ac495dSmrg /*    lengths of 4, 9, and 18 bytes.				      */
146336ac495dSmrg /*  returns the sign of the coefficient (DECFLOAT_Sign if negative,   */
146436ac495dSmrg /*    0 otherwise)						      */
146536ac495dSmrg /*								      */
146636ac495dSmrg /* No error is possible, and no status will be set.		      */
146736ac495dSmrg /* ------------------------------------------------------------------ */
decFloatToPacked(const decFloat * df,Int * exp,uByte * packed)146836ac495dSmrg Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) {
146936ac495dSmrg   uByte bcdar[DECPMAX+2];	   /* work buffer */
147036ac495dSmrg   uByte *ip=bcdar, *op=packed;	   /* work pointers */
147136ac495dSmrg   if (DFISINF(df)) {
147236ac495dSmrg     memset(bcdar, 0, DECPMAX+2);
147336ac495dSmrg     *exp=DECFLOAT_Inf;
147436ac495dSmrg     }
147536ac495dSmrg    else {
147636ac495dSmrg     GETCOEFF(df, bcdar+1);	   /* use macro */
147736ac495dSmrg     if (DFISNAN(df)) {
147836ac495dSmrg       bcdar[1]=0;		   /* MSD needs clearing */
147936ac495dSmrg       *exp=DFWORD(df, 0)&0x7e000000;
148036ac495dSmrg       }
148136ac495dSmrg      else {			   /* finite */
148236ac495dSmrg       *exp=GETEXPUN(df);
148336ac495dSmrg       }
148436ac495dSmrg     }
148536ac495dSmrg   /* now pack; coefficient currently at bcdar+1 */
148636ac495dSmrg   #if SINGLE
148736ac495dSmrg     ip++;			   /* ignore first byte */
148836ac495dSmrg   #else
148936ac495dSmrg     *ip=0;			   /* need leading zero */
149036ac495dSmrg   #endif
149136ac495dSmrg   /* set final byte to Packed BCD sign value */
149236ac495dSmrg   bcdar[DECPMAX+1]=(DFISSIGNED(df) ? DECPMINUS : DECPPLUS);
149336ac495dSmrg   /* pack an even number of bytes... */
149436ac495dSmrg   for (; op<packed+((DECPMAX+2)/2); op++, ip+=2) {
149536ac495dSmrg     *op=(uByte)((*ip<<4)+*(ip+1));
149636ac495dSmrg     }
149736ac495dSmrg   return (bcdar[DECPMAX+1]==DECPMINUS ? DECFLOAT_Sign : 0);
149836ac495dSmrg   } /* decFloatToPacked */
149936ac495dSmrg 
150036ac495dSmrg /* ------------------------------------------------------------------ */
150136ac495dSmrg /* decFloatToString -- conversion to numeric string		      */
150236ac495dSmrg /*								      */
150336ac495dSmrg /*  df is the decFloat format number to convert 		      */
150436ac495dSmrg /*  string is the string where the result will be laid out	      */
150536ac495dSmrg /*								      */
150636ac495dSmrg /* string must be at least DECPMAX+9 characters (the worst case is    */
150736ac495dSmrg /* "-0.00000nnn...nnn\0", which is as long as the exponent form when  */
150836ac495dSmrg /* DECEMAXD<=4); this condition is asserted above		      */
150936ac495dSmrg /*								      */
151036ac495dSmrg /* No error is possible, and no status will be set		      */
151136ac495dSmrg /* ------------------------------------------------------------------ */
decFloatToString(const decFloat * df,char * string)151236ac495dSmrg char * decFloatToString(const decFloat *df, char *string){
151336ac495dSmrg   uInt msd;			   /* coefficient MSD */
151436ac495dSmrg   Int  exp;			   /* exponent top two bits or full */
151536ac495dSmrg   uInt comb;			   /* combination field */
151636ac495dSmrg   char *cstart; 		   /* coefficient start */
151736ac495dSmrg   char *c;			   /* output pointer in string */
151836ac495dSmrg   char *s, *t;			   /* .. (source, target) */
151936ac495dSmrg   Int  pre, e;			   /* work */
152036ac495dSmrg   const uByte *u;		   /* .. */
152136ac495dSmrg   uInt	uiwork; 		   /* for macros [one compiler needs */
152236ac495dSmrg 				   /* volatile here to avoid bug, but */
152336ac495dSmrg 				   /* that doubles execution time] */
152436ac495dSmrg 
152536ac495dSmrg   /* Source words; macro handles endianness */
152636ac495dSmrg   uInt sourhi=DFWORD(df, 0);	   /* word with sign */
152736ac495dSmrg   #if DECPMAX==16
152836ac495dSmrg   uInt sourlo=DFWORD(df, 1);
152936ac495dSmrg   #elif DECPMAX==34
153036ac495dSmrg   uInt sourmh=DFWORD(df, 1);
153136ac495dSmrg   uInt sourml=DFWORD(df, 2);
153236ac495dSmrg   uInt sourlo=DFWORD(df, 3);
153336ac495dSmrg   #endif
153436ac495dSmrg 
153536ac495dSmrg   c=string;			   /* where result will go */
153636ac495dSmrg   if (((Int)sourhi)<0) *c++='-';   /* handle sign */
153736ac495dSmrg   comb=sourhi>>26;		   /* sign+combination field */
153836ac495dSmrg   msd=DECCOMBMSD[comb]; 	   /* decode the combination field */
153936ac495dSmrg   exp=DECCOMBEXP[comb]; 	   /* .. */
154036ac495dSmrg 
154136ac495dSmrg   if (!EXPISSPECIAL(exp)) {	   /* finite */
154236ac495dSmrg     /* complete exponent; top two bits are in place */
154336ac495dSmrg     exp+=GETECON(df)-DECBIAS;	   /* .. + continuation and unbias */
154436ac495dSmrg     }
154536ac495dSmrg    else {			   /* IS special */
154636ac495dSmrg     if (exp==DECFLOAT_Inf) {	   /* infinity */
154736ac495dSmrg       strcpy(c, "Infinity");
154836ac495dSmrg       return string;		   /* easy */
154936ac495dSmrg       }
155036ac495dSmrg     if (sourhi&0x02000000) *c++='s'; /* sNaN */
155136ac495dSmrg     strcpy(c, "NaN");		   /* complete word */
155236ac495dSmrg     c+=3;			   /* step past */
155336ac495dSmrg     /* quick exit if the payload is zero */
155436ac495dSmrg     #if DECPMAX==7
155536ac495dSmrg     if ((sourhi&0x000fffff)==0) return string;
155636ac495dSmrg     #elif DECPMAX==16
155736ac495dSmrg     if (sourlo==0 && (sourhi&0x0003ffff)==0) return string;
155836ac495dSmrg     #elif DECPMAX==34
155936ac495dSmrg     if (sourlo==0 && sourml==0 && sourmh==0
156036ac495dSmrg      && (sourhi&0x00003fff)==0) return string;
156136ac495dSmrg     #endif
156236ac495dSmrg     /* otherwise drop through to add integer; set correct exp etc. */
156336ac495dSmrg     exp=0; msd=0;		   /* setup for following code */
156436ac495dSmrg     }
156536ac495dSmrg 
156636ac495dSmrg   /* convert the digits of the significand to characters */
156736ac495dSmrg   cstart=c;			   /* save start of coefficient */
156836ac495dSmrg   if (msd) *c++=(char)('0'+(char)msd);	/* non-zero most significant digit */
156936ac495dSmrg 
157036ac495dSmrg   /* Decode the declets.  After extracting each declet, it is */
157136ac495dSmrg   /* decoded to a 4-uByte sequence by table lookup; the four uBytes */
157236ac495dSmrg   /* are the three encoded BCD8 digits followed by a 1-byte length */
157336ac495dSmrg   /* (significant digits, except that 000 has length 0).  This allows */
157436ac495dSmrg   /* us to left-align the first declet with non-zero content, then */
157536ac495dSmrg   /* the remaining ones are full 3-char length.  Fixed-length copies */
157636ac495dSmrg   /* are used because variable-length memcpy causes a subroutine call */
157736ac495dSmrg   /* in at least two compilers.  (The copies are length 4 for speed */
157836ac495dSmrg   /* and are safe because the last item in the array is of length */
157936ac495dSmrg   /* three and has the length byte following.) */
158036ac495dSmrg   #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4];	 \
158136ac495dSmrg 	 if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
158236ac495dSmrg 	  else if (*(u+3)) {					 \
158336ac495dSmrg 	   UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
158436ac495dSmrg 
158536ac495dSmrg   #if DECPMAX==7
158636ac495dSmrg   dpd2char(sourhi>>10); 		/* declet 1 */
158736ac495dSmrg   dpd2char(sourhi);			/* declet 2 */
158836ac495dSmrg 
158936ac495dSmrg   #elif DECPMAX==16
159036ac495dSmrg   dpd2char(sourhi>>8);			/* declet 1 */
159136ac495dSmrg   dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
159236ac495dSmrg   dpd2char(sourlo>>20); 		/* declet 3 */
159336ac495dSmrg   dpd2char(sourlo>>10); 		/* declet 4 */
159436ac495dSmrg   dpd2char(sourlo);			/* declet 5 */
159536ac495dSmrg 
159636ac495dSmrg   #elif DECPMAX==34
159736ac495dSmrg   dpd2char(sourhi>>4);			/* declet 1 */
159836ac495dSmrg   dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
159936ac495dSmrg   dpd2char(sourmh>>16); 		/* declet 3 */
160036ac495dSmrg   dpd2char(sourmh>>6);			/* declet 4 */
160136ac495dSmrg   dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
160236ac495dSmrg   dpd2char(sourml>>18); 		/* declet 6 */
160336ac495dSmrg   dpd2char(sourml>>8);			/* declet 7 */
160436ac495dSmrg   dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
160536ac495dSmrg   dpd2char(sourlo>>20); 		/* declet 9 */
160636ac495dSmrg   dpd2char(sourlo>>10); 		/* declet 10 */
160736ac495dSmrg   dpd2char(sourlo);			/* declet 11 */
160836ac495dSmrg   #endif
160936ac495dSmrg 
161036ac495dSmrg   if (c==cstart) *c++='0';	   /* all zeros, empty -- make "0" */
161136ac495dSmrg 
161236ac495dSmrg   /*[This fast path is valid but adds 3-5 cycles to worst case length] */
161336ac495dSmrg   /*if (exp==0) {		   // integer or NaN case -- easy */
161436ac495dSmrg   /*  *c='\0';			   // terminate */
161536ac495dSmrg   /*  return string; */
161636ac495dSmrg   /*  } */
161736ac495dSmrg 
161836ac495dSmrg   e=0;				   /* assume no E */
161936ac495dSmrg   pre=(Int)(c-cstart)+exp;	   /* length+exp  [c->LSD+1] */
162036ac495dSmrg   /* [here, pre-exp is the digits count (==1 for zero)] */
162136ac495dSmrg 
162236ac495dSmrg   if (exp>0 || pre<-5) {	   /* need exponential form */
162336ac495dSmrg     e=pre-1;			   /* calculate E value */
162436ac495dSmrg     pre=1;			   /* assume one digit before '.' */
162536ac495dSmrg     } /* exponential form */
162636ac495dSmrg 
162736ac495dSmrg   /* modify the coefficient, adding 0s, '.', and E+nn as needed */
162836ac495dSmrg   if (pre>0) {			   /* ddd.ddd (plain), perhaps with E */
162936ac495dSmrg     char *dotat=cstart+pre;
163036ac495dSmrg     if (dotat<c) {			/* if embedded dot needed... */
163136ac495dSmrg       /* [memmove is a disaster, here] */
163236ac495dSmrg       /* move by fours; there must be space for junk at the end */
163336ac495dSmrg       /* because exponent is still possible */
163436ac495dSmrg       s=dotat+ROUNDDOWN4(c-dotat);	/* source */
163536ac495dSmrg       t=s+1;				/* target */
163636ac495dSmrg       /* open the gap [cannot use memcpy] */
163736ac495dSmrg       for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
163836ac495dSmrg       *dotat='.';
163936ac495dSmrg       c++;				/* length increased by one */
164036ac495dSmrg       } /* need dot? */
164136ac495dSmrg 
164236ac495dSmrg     /* finally add the E-part, if needed; it will never be 0, and has */
164336ac495dSmrg     /* a maximum length of 3 or 4 digits (asserted above) */
164436ac495dSmrg     if (e!=0) {
164536ac495dSmrg       memcpy(c, "E+", 2);		/* starts with E, assume + */
164636ac495dSmrg       c++;
164736ac495dSmrg       if (e<0) {
164836ac495dSmrg 	*c='-'; 			/* oops, need '-' */
164936ac495dSmrg 	e=-e;				/* uInt, please */
165036ac495dSmrg 	}
165136ac495dSmrg       c++;
165236ac495dSmrg       /* Three-character exponents are easy; 4-character a little trickier */
165336ac495dSmrg       #if DECEMAXD<=3
165436ac495dSmrg 	u=&BIN2BCD8[e*4];		/* -> 3 digits + length byte */
165536ac495dSmrg 	/* copy fixed 4 characters [is safe], starting at non-zero */
165636ac495dSmrg 	/* and with character mask to convert BCD to char */
165736ac495dSmrg 	UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
165836ac495dSmrg 	c+=*(u+3);			/* bump pointer appropriately */
165936ac495dSmrg       #elif DECEMAXD==4
166036ac495dSmrg 	if (e<1000) {			/* 3 (or fewer) digits case */
166136ac495dSmrg 	  u=&BIN2BCD8[e*4];		/* -> 3 digits + length byte */
166236ac495dSmrg 	  UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
166336ac495dSmrg 	  c+=*(u+3);			/* bump pointer appropriately */
166436ac495dSmrg 	  }
166536ac495dSmrg 	 else { 			/* 4-digits */
166636ac495dSmrg 	  Int thou=((e>>3)*1049)>>17;	/* e/1000 */
166736ac495dSmrg 	  Int rem=e-(1000*thou);	/* e%1000 */
166836ac495dSmrg 	  *c++=(char)('0'+(char)thou);	/* the thousands digit */
166936ac495dSmrg 	  u=&BIN2BCD8[rem*4];		/* -> 3 digits + length byte */
167036ac495dSmrg 	  UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
167136ac495dSmrg 	  c+=3; 			/* bump pointer, always 3 digits */
167236ac495dSmrg 	  }
167336ac495dSmrg       #endif
167436ac495dSmrg       }
167536ac495dSmrg     *c='\0';				/* add terminator */
167636ac495dSmrg     /*printf("res %s\n", string); */
167736ac495dSmrg     return string;
167836ac495dSmrg     } /* pre>0 */
167936ac495dSmrg 
168036ac495dSmrg   /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
168136ac495dSmrg   /* Surprisingly, this is close to being the worst-case path, so the */
168236ac495dSmrg   /* shift is done by fours; this is a little tricky because the */
168336ac495dSmrg   /* rightmost character to be written must not be beyond where the */
168436ac495dSmrg   /* rightmost terminator could be -- so backoff to not touch */
168536ac495dSmrg   /* terminator position if need be (this can make exact alignments */
168636ac495dSmrg   /* for full Doubles, but in some cases needs care not to access too */
168736ac495dSmrg   /* far to the left) */
168836ac495dSmrg 
168936ac495dSmrg   pre=-pre+2;				/* gap width, including "0." */
169036ac495dSmrg   t=cstart+ROUNDDOWN4(c-cstart)+pre;	/* preferred first target point */
169136ac495dSmrg   /* backoff if too far to the right */
169236ac495dSmrg   if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
169336ac495dSmrg   /* now shift the entire coefficient to the right, being careful not */
169436ac495dSmrg   /* to access to the left of string [cannot use memcpy] */
169536ac495dSmrg   for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
169636ac495dSmrg   /* for Quads and Singles there may be a character or two left... */
169736ac495dSmrg   s+=3; 				/* where next would come from */
169836ac495dSmrg   for(; s>=cstart; s--, t--) *(t+3)=*(s);
169936ac495dSmrg   /* now have fill 0. through 0.00000; use overlaps to avoid tests */
170036ac495dSmrg   if (pre>=4) {
170136ac495dSmrg     memcpy(cstart+pre-4, "0000", 4);
170236ac495dSmrg     memcpy(cstart, "0.00", 4);
170336ac495dSmrg     }
170436ac495dSmrg    else { /* 2 or 3 */
170536ac495dSmrg     *(cstart+pre-1)='0';
170636ac495dSmrg     memcpy(cstart, "0.", 2);
170736ac495dSmrg     }
170836ac495dSmrg   *(c+pre)='\0';			/* terminate */
170936ac495dSmrg   return string;
171036ac495dSmrg   } /* decFloatToString */
171136ac495dSmrg 
171236ac495dSmrg /* ------------------------------------------------------------------ */
171336ac495dSmrg /* decFloatToWider -- conversion to next-wider format		      */
171436ac495dSmrg /*								      */
171536ac495dSmrg /*  source  is the decFloat format number which gets the result of    */
171636ac495dSmrg /*	    the conversion					      */
171736ac495dSmrg /*  wider   is the decFloatWider format number which will be narrowed */
171836ac495dSmrg /*  returns wider						      */
171936ac495dSmrg /*								      */
172036ac495dSmrg /* Widening is always exact; no status is set (sNaNs are copied and   */
172136ac495dSmrg /* do not signal).  The result will be canonical if the source is,    */
172236ac495dSmrg /* and may or may not be if the source is not.			      */
172336ac495dSmrg /* ------------------------------------------------------------------ */
172436ac495dSmrg /* widening is not possible for decQuad format numbers; simply omit */
172536ac495dSmrg #if !QUAD
decFloatToWider(const decFloat * source,decFloatWider * wider)172636ac495dSmrg decFloatWider * decFloatToWider(const decFloat *source, decFloatWider *wider) {
172736ac495dSmrg   uInt msd;
172836ac495dSmrg 
172936ac495dSmrg   /* Construct and copy the sign word */
173036ac495dSmrg   if (DFISSPECIAL(source)) {
173136ac495dSmrg     /* copy sign, combination, and first bit of exponent (sNaN selector) */
173236ac495dSmrg     DFWWORD(wider, 0)=DFWORD(source, 0)&0xfe000000;
173336ac495dSmrg     msd=0;
173436ac495dSmrg     }
173536ac495dSmrg    else { /* is finite number */
173636ac495dSmrg     uInt exp=GETEXPUN(source)+DECWBIAS; /* get unbiased exponent and rebias */
173736ac495dSmrg     uInt code=(exp>>DECWECONL)<<29;	/* set two bits of exp [msd=0] */
173836ac495dSmrg     code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */
173936ac495dSmrg     code|=DFWORD(source, 0)&0x80000000; /* add sign */
174036ac495dSmrg     DFWWORD(wider, 0)=code;		/* .. and place top word in wider */
174136ac495dSmrg     msd=GETMSD(source); 		/* get source coefficient MSD [0-9] */
174236ac495dSmrg     }
174336ac495dSmrg   /* Copy the coefficient and clear any 'unused' words to left */
174436ac495dSmrg   #if SINGLE
174536ac495dSmrg     DFWWORD(wider, 1)=(DFWORD(source, 0)&0x000fffff)|(msd<<20);
174636ac495dSmrg   #elif DOUBLE
174736ac495dSmrg     DFWWORD(wider, 2)=(DFWORD(source, 0)&0x0003ffff)|(msd<<18);
174836ac495dSmrg     DFWWORD(wider, 3)=DFWORD(source, 1);
174936ac495dSmrg     DFWWORD(wider, 1)=0;
175036ac495dSmrg   #endif
175136ac495dSmrg   return wider;
175236ac495dSmrg   } /* decFloatToWider */
175336ac495dSmrg #endif
175436ac495dSmrg 
175536ac495dSmrg /* ------------------------------------------------------------------ */
175636ac495dSmrg /* decFloatVersion -- return package version string		      */
175736ac495dSmrg /*								      */
175836ac495dSmrg /*  returns a constant string describing this package		      */
175936ac495dSmrg /* ------------------------------------------------------------------ */
decFloatVersion(void)176036ac495dSmrg const char *decFloatVersion(void) {
176136ac495dSmrg   return DECVERSION;
176236ac495dSmrg   } /* decFloatVersion */
176336ac495dSmrg 
176436ac495dSmrg /* ------------------------------------------------------------------ */
176536ac495dSmrg /* decFloatZero -- set to canonical (integer) zero		      */
176636ac495dSmrg /*								      */
176736ac495dSmrg /*  df is the decFloat format number to integer +0 (q=0, c=+0)	      */
176836ac495dSmrg /*  returns df							      */
176936ac495dSmrg /*								      */
177036ac495dSmrg /* No error is possible, and no status can be set.		      */
177136ac495dSmrg /* ------------------------------------------------------------------ */
decFloatZero(decFloat * df)177236ac495dSmrg decFloat * decFloatZero(decFloat *df){
177336ac495dSmrg   DFWORD(df, 0)=ZEROWORD;     /* set appropriate top word */
177436ac495dSmrg   #if DOUBLE || QUAD
177536ac495dSmrg     DFWORD(df, 1)=0;
177636ac495dSmrg     #if QUAD
177736ac495dSmrg       DFWORD(df, 2)=0;
177836ac495dSmrg       DFWORD(df, 3)=0;
177936ac495dSmrg     #endif
178036ac495dSmrg   #endif
178136ac495dSmrg   /* decFloatShow(df, "zero"); */
178236ac495dSmrg   return df;
178336ac495dSmrg   } /* decFloatZero */
178436ac495dSmrg 
178536ac495dSmrg /* ------------------------------------------------------------------ */
178636ac495dSmrg /* Private generic function (not format-specific) for development use */
178736ac495dSmrg /* ------------------------------------------------------------------ */
178836ac495dSmrg /* This is included once only, for all to use */
178936ac495dSmrg #if QUAD && (DECCHECK || DECTRACE)
179036ac495dSmrg   /* ---------------------------------------------------------------- */
179136ac495dSmrg   /* decShowNum -- display bcd8 number in debug form		      */
179236ac495dSmrg   /*								      */
179336ac495dSmrg   /*   num is the bcdnum to display				      */
179436ac495dSmrg   /*   tag is a string to label the display			      */
179536ac495dSmrg   /* ---------------------------------------------------------------- */
decShowNum(const bcdnum * num,const char * tag)179636ac495dSmrg   void decShowNum(const bcdnum *num, const char *tag) {
179736ac495dSmrg     const char *csign="+";		/* sign character */
179836ac495dSmrg     uByte *ub;				/* work */
179936ac495dSmrg     uInt  uiwork;			/* for macros */
180036ac495dSmrg     if (num->sign==DECFLOAT_Sign) csign="-";
180136ac495dSmrg 
180236ac495dSmrg     printf(">%s> ", tag);
180336ac495dSmrg     if (num->exponent==DECFLOAT_Inf) printf("%sInfinity", csign);
180436ac495dSmrg     else if (num->exponent==DECFLOAT_qNaN) printf("%sqNaN", csign);
180536ac495dSmrg     else if (num->exponent==DECFLOAT_sNaN) printf("%ssNaN", csign);
180636ac495dSmrg     else {				/* finite */
180736ac495dSmrg      char qbuf[10];			/* for right-aligned q */
180836ac495dSmrg      char *c;				/* work */
180936ac495dSmrg      const uByte *u;			/* .. */
181036ac495dSmrg      Int e=num->exponent;		/* .. exponent */
181136ac495dSmrg      strcpy(qbuf, "q=");
181236ac495dSmrg      c=&qbuf[2];			/* where exponent will go */
181336ac495dSmrg      /* lay out the exponent */
181436ac495dSmrg      if (e<0) {
181536ac495dSmrg        *c++='-';			/* add '-' */
181636ac495dSmrg        e=-e;				/* uInt, please */
181736ac495dSmrg        }
181836ac495dSmrg      #if DECEMAXD>4
181936ac495dSmrg        #error Exponent form is too long for ShowNum to lay out
182036ac495dSmrg      #endif
182136ac495dSmrg      if (e==0) *c++='0';		/* 0-length case */
182236ac495dSmrg       else if (e<1000) {		/* 3 (or fewer) digits case */
182336ac495dSmrg        u=&BIN2BCD8[e*4];		/* -> 3 digits + length byte */
182436ac495dSmrg        UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
182536ac495dSmrg        c+=*(u+3);			/* bump pointer appropriately */
182636ac495dSmrg        }
182736ac495dSmrg       else {				/* 4-digits */
182836ac495dSmrg        Int thou=((e>>3)*1049)>>17;	/* e/1000 */
182936ac495dSmrg        Int rem=e-(1000*thou);		/* e%1000 */
183036ac495dSmrg        *c++=(char)('0'+(char)thou);	/* the thousands digit */
183136ac495dSmrg        u=&BIN2BCD8[rem*4];		/* -> 3 digits + length byte */
183236ac495dSmrg        UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
183336ac495dSmrg        c+=3;				/* bump pointer, always 3 digits */
183436ac495dSmrg        }
183536ac495dSmrg      *c='\0';				/* add terminator */
183636ac495dSmrg      printf("%7s c=%s", qbuf, csign);
183736ac495dSmrg      }
183836ac495dSmrg 
183936ac495dSmrg     if (!EXPISSPECIAL(num->exponent) || num->msd!=num->lsd || *num->lsd!=0) {
184036ac495dSmrg       for (ub=num->msd; ub<=num->lsd; ub++) { /* coefficient... */
184136ac495dSmrg 	printf("%1x", *ub);
184236ac495dSmrg 	if ((num->lsd-ub)%3==0 && ub!=num->lsd) printf(" "); /* 4-space */
184336ac495dSmrg 	}
184436ac495dSmrg       }
184536ac495dSmrg     printf("\n");
184636ac495dSmrg     } /* decShowNum */
184736ac495dSmrg #endif
1848