xref: /netbsd-src/external/gpl3/gcc/dist/libdecnumber/decCommon.c (revision b1e838363e3c6fc78a55519254d99869742dd33c)
14fee23f9Smrg /* Common code for fixed-size types in the decNumber C Library.
2*b1e83836Smrg    Copyright (C) 2007-2022 Free Software Foundation, Inc.
34fee23f9Smrg    Contributed by IBM Corporation.  Author Mike Cowlishaw.
44fee23f9Smrg 
54fee23f9Smrg    This file is part of GCC.
64fee23f9Smrg 
74fee23f9Smrg    GCC is free software; you can redistribute it and/or modify it under
84fee23f9Smrg    the terms of the GNU General Public License as published by the Free
94fee23f9Smrg    Software Foundation; either version 3, or (at your option) any later
104fee23f9Smrg    version.
114fee23f9Smrg 
124fee23f9Smrg    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
134fee23f9Smrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or
144fee23f9Smrg    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
154fee23f9Smrg    for more details.
164fee23f9Smrg 
174fee23f9Smrg Under Section 7 of GPL version 3, you are granted additional
184fee23f9Smrg permissions described in the GCC Runtime Library Exception, version
194fee23f9Smrg 3.1, as published by the Free Software Foundation.
204fee23f9Smrg 
214fee23f9Smrg You should have received a copy of the GNU General Public License and
224fee23f9Smrg a copy of the GCC Runtime Library Exception along with this program;
234fee23f9Smrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
244fee23f9Smrg <http://www.gnu.org/licenses/>.  */
254fee23f9Smrg 
264fee23f9Smrg /* ------------------------------------------------------------------ */
274fee23f9Smrg /* decCommon.c -- common code for all three fixed-size types	      */
284fee23f9Smrg /* ------------------------------------------------------------------ */
294fee23f9Smrg /* This module comprises code that is shared between all the formats  */
304fee23f9Smrg /* (decSingle, decDouble, and decQuad); it includes set and extract   */
314fee23f9Smrg /* of format components, widening, narrowing, and string conversions. */
324fee23f9Smrg /*								      */
334fee23f9Smrg /* Unlike decNumber, parameterization takes place at compile time     */
344fee23f9Smrg /* rather than at runtime.  The parameters are set in the decDouble.c */
354fee23f9Smrg /* (etc.) files, which then include this one to produce the compiled  */
364fee23f9Smrg /* code.  The functions here, therefore, are code shared between      */
374fee23f9Smrg /* multiple formats.						      */
384fee23f9Smrg /* ------------------------------------------------------------------ */
394fee23f9Smrg /* Names here refer to decFloat rather than to decDouble, etc., and */
404fee23f9Smrg /* the functions are in strict alphabetical order. */
414fee23f9Smrg /* Constants, tables, and debug function(s) are included only for QUAD */
424fee23f9Smrg /* (which will always be compiled if DOUBLE or SINGLE are used). */
434fee23f9Smrg /* */
444fee23f9Smrg /* Whenever a decContext is used, only the status may be set (using */
454fee23f9Smrg /* OR) or the rounding mode read; all other fields are ignored and */
464fee23f9Smrg /* untouched. */
474fee23f9Smrg 
484fee23f9Smrg #include "decCommonSymbols.h"
494fee23f9Smrg 
504fee23f9Smrg /* names for simpler testing and default context */
514fee23f9Smrg #if DECPMAX==7
524fee23f9Smrg   #define SINGLE     1
534fee23f9Smrg   #define DOUBLE     0
544fee23f9Smrg   #define QUAD	     0
554fee23f9Smrg   #define DEFCONTEXT DEC_INIT_DECIMAL32
564fee23f9Smrg #elif DECPMAX==16
574fee23f9Smrg   #define SINGLE     0
584fee23f9Smrg   #define DOUBLE     1
594fee23f9Smrg   #define QUAD	     0
604fee23f9Smrg   #define DEFCONTEXT DEC_INIT_DECIMAL64
614fee23f9Smrg #elif DECPMAX==34
624fee23f9Smrg   #define SINGLE     0
634fee23f9Smrg   #define DOUBLE     0
644fee23f9Smrg   #define QUAD	     1
654fee23f9Smrg   #define DEFCONTEXT DEC_INIT_DECIMAL128
664fee23f9Smrg #else
674fee23f9Smrg   #error Unexpected DECPMAX value
684fee23f9Smrg #endif
694fee23f9Smrg 
704fee23f9Smrg /* Assertions */
714fee23f9Smrg 
724fee23f9Smrg #if DECPMAX!=7 && DECPMAX!=16 && DECPMAX!=34
734fee23f9Smrg   #error Unexpected Pmax (DECPMAX) value for this module
744fee23f9Smrg #endif
754fee23f9Smrg 
764fee23f9Smrg /* Assert facts about digit characters, etc. */
774fee23f9Smrg #if ('9'&0x0f)!=9
784fee23f9Smrg   #error This module assumes characters are of the form 0b....nnnn
794fee23f9Smrg   /* where .... are don't care 4 bits and nnnn is 0000 through 1001 */
804fee23f9Smrg #endif
814fee23f9Smrg #if ('9'&0xf0)==('.'&0xf0)
824fee23f9Smrg   #error This module assumes '.' has a different mask than a digit
834fee23f9Smrg #endif
844fee23f9Smrg 
854fee23f9Smrg /* Assert ToString lay-out conditions */
864fee23f9Smrg #if DECSTRING<DECPMAX+9
874fee23f9Smrg   #error ToString needs at least 8 characters for lead-in and dot
884fee23f9Smrg #endif
894fee23f9Smrg #if DECPMAX+DECEMAXD+5 > DECSTRING
904fee23f9Smrg   #error Exponent form can be too long for ToString to lay out safely
914fee23f9Smrg #endif
924fee23f9Smrg #if DECEMAXD > 4
934fee23f9Smrg   #error Exponent form is too long for ToString to lay out
944fee23f9Smrg   /* Note: code for up to 9 digits exists in archives [decOct] */
954fee23f9Smrg #endif
964fee23f9Smrg 
974fee23f9Smrg /* Private functions used here and possibly in decBasic.c, etc. */
984fee23f9Smrg static decFloat * decFinalize(decFloat *, bcdnum *, decContext *);
994fee23f9Smrg static Flag decBiStr(const char *, const char *, const char *);
1004fee23f9Smrg 
1014fee23f9Smrg /* Macros and private tables; those which are not format-dependent    */
1024fee23f9Smrg /* are only included if decQuad is being built. 		      */
1034fee23f9Smrg 
1044fee23f9Smrg /* ------------------------------------------------------------------ */
1054fee23f9Smrg /* Combination field lookup tables (uInts to save measurable work)    */
1064fee23f9Smrg /*								      */
1074fee23f9Smrg /*   DECCOMBEXP  - 2 most-significant-bits of exponent (00, 01, or    */
1084fee23f9Smrg /*		   10), shifted left for format, or DECFLOAT_Inf/NaN  */
1094fee23f9Smrg /*   DECCOMBWEXP - The same, for the next-wider format (unless QUAD)  */
1104fee23f9Smrg /*   DECCOMBMSD  - 4-bit most-significant-digit 		      */
1114fee23f9Smrg /*		   [0 if the index is a special (Infinity or NaN)]    */
1124fee23f9Smrg /*   DECCOMBFROM - 5-bit combination field from EXP top bits and MSD  */
1134fee23f9Smrg /*		   (placed in uInt so no shift is needed)	      */
1144fee23f9Smrg /*								      */
1154fee23f9Smrg /* DECCOMBEXP, DECCOMBWEXP, and DECCOMBMSD are indexed by the sign    */
1164fee23f9Smrg /*   and 5-bit combination field (0-63, the second half of the table  */
1174fee23f9Smrg /*   identical to the first half)				      */
1184fee23f9Smrg /* DECCOMBFROM is indexed by expTopTwoBits*16 + msd		      */
1194fee23f9Smrg /*								      */
1204fee23f9Smrg /* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are     */
1214fee23f9Smrg /* only included once, when QUAD is being built 		      */
1224fee23f9Smrg /* ------------------------------------------------------------------ */
1234fee23f9Smrg static const uInt DECCOMBEXP[64]={
1244fee23f9Smrg   0, 0, 0, 0, 0, 0, 0, 0,
1254fee23f9Smrg   1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
1264fee23f9Smrg   1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
1274fee23f9Smrg   2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
1284fee23f9Smrg   2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
1294fee23f9Smrg   0,	       0,	    1<<DECECONL, 1<<DECECONL,
1304fee23f9Smrg   2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN,
1314fee23f9Smrg   0, 0, 0, 0, 0, 0, 0, 0,
1324fee23f9Smrg   1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
1334fee23f9Smrg   1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
1344fee23f9Smrg   2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
1354fee23f9Smrg   2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
1364fee23f9Smrg   0,	       0,	    1<<DECECONL, 1<<DECECONL,
1374fee23f9Smrg   2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN};
1384fee23f9Smrg #if !QUAD
1394fee23f9Smrg static const uInt DECCOMBWEXP[64]={
1404fee23f9Smrg   0, 0, 0, 0, 0, 0, 0, 0,
1414fee23f9Smrg   1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
1424fee23f9Smrg   1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
1434fee23f9Smrg   2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
1444fee23f9Smrg   2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
1454fee23f9Smrg   0,		0,	      1<<DECWECONL, 1<<DECWECONL,
1464fee23f9Smrg   2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN,
1474fee23f9Smrg   0, 0, 0, 0, 0, 0, 0, 0,
1484fee23f9Smrg   1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
1494fee23f9Smrg   1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
1504fee23f9Smrg   2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
1514fee23f9Smrg   2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
1524fee23f9Smrg   0,		0,	      1<<DECWECONL, 1<<DECWECONL,
1534fee23f9Smrg   2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN};
1544fee23f9Smrg #endif
1554fee23f9Smrg 
1564fee23f9Smrg #if QUAD
1574fee23f9Smrg const uInt DECCOMBMSD[64]={
1584fee23f9Smrg   0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
1594fee23f9Smrg   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0,
1604fee23f9Smrg   0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
1614fee23f9Smrg   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0};
1624fee23f9Smrg 
1634fee23f9Smrg const uInt DECCOMBFROM[48]={
1644fee23f9Smrg   0x00000000, 0x04000000, 0x08000000, 0x0C000000, 0x10000000, 0x14000000,
1654fee23f9Smrg   0x18000000, 0x1C000000, 0x60000000, 0x64000000, 0x00000000, 0x00000000,
1664fee23f9Smrg   0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20000000, 0x24000000,
1674fee23f9Smrg   0x28000000, 0x2C000000, 0x30000000, 0x34000000, 0x38000000, 0x3C000000,
1684fee23f9Smrg   0x68000000, 0x6C000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1694fee23f9Smrg   0x00000000, 0x00000000, 0x40000000, 0x44000000, 0x48000000, 0x4C000000,
1704fee23f9Smrg   0x50000000, 0x54000000, 0x58000000, 0x5C000000, 0x70000000, 0x74000000,
1714fee23f9Smrg   0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
1724fee23f9Smrg 
1734fee23f9Smrg /* ------------------------------------------------------------------ */
1744fee23f9Smrg /* Request and include the tables to use for conversions	      */
1754fee23f9Smrg /* ------------------------------------------------------------------ */
1764fee23f9Smrg #define DEC_BCD2DPD  1	      /* 0-0x999 -> DPD */
1774fee23f9Smrg #define DEC_BIN2DPD  1	      /* 0-999 -> DPD */
1784fee23f9Smrg #define DEC_BIN2BCD8 1	      /* 0-999 -> ddd, len */
1794fee23f9Smrg #define DEC_DPD2BCD8 1	      /* DPD -> ddd, len */
1804fee23f9Smrg #define DEC_DPD2BIN  1	      /* DPD -> 0-999 */
1814fee23f9Smrg #define DEC_DPD2BINK 1	      /* DPD -> 0-999000 */
1824fee23f9Smrg #define DEC_DPD2BINM 1	      /* DPD -> 0-999000000 */
1834fee23f9Smrg #include "decDPD.h"	      /* source of the lookup tables */
1844fee23f9Smrg 
1854fee23f9Smrg #endif
1864fee23f9Smrg 
1874fee23f9Smrg /* ----------------------------------------------------------------- */
1884fee23f9Smrg /* decBiStr -- compare string with pairwise options		     */
1894fee23f9Smrg /*								     */
1904fee23f9Smrg /*   targ is the string to compare				     */
1914fee23f9Smrg /*   str1 is one of the strings to compare against (length may be 0) */
1924fee23f9Smrg /*   str2 is the other; it must be the same length as str1	     */
1934fee23f9Smrg /*								     */
1944fee23f9Smrg /*   returns 1 if strings compare equal, (that is, targ is the same  */
1954fee23f9Smrg /*   length as str1 and str2, and each character of targ is in one   */
1964fee23f9Smrg /*   of str1 or str2 in the corresponding position), or 0 otherwise  */
1974fee23f9Smrg /*								     */
1984fee23f9Smrg /* This is used for generic caseless compare, including the awkward  */
1994fee23f9Smrg /* case of the Turkish dotted and dotless Is.  Use as (for example): */
2004fee23f9Smrg /*   if (decBiStr(test, "mike", "MIKE")) ...			     */
2014fee23f9Smrg /* ----------------------------------------------------------------- */
decBiStr(const char * targ,const char * str1,const char * str2)2024fee23f9Smrg static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
2034fee23f9Smrg   for (;;targ++, str1++, str2++) {
2044fee23f9Smrg     if (*targ!=*str1 && *targ!=*str2) return 0;
2054fee23f9Smrg     /* *targ has a match in one (or both, if terminator) */
2064fee23f9Smrg     if (*targ=='\0') break;
2074fee23f9Smrg     } /* forever */
2084fee23f9Smrg   return 1;
2094fee23f9Smrg   } /* decBiStr */
2104fee23f9Smrg 
2114fee23f9Smrg /* ------------------------------------------------------------------ */
2124fee23f9Smrg /* decFinalize -- adjust and store a final result		      */
2134fee23f9Smrg /*								      */
2144fee23f9Smrg /*  df	is the decFloat format number which gets the final result     */
2154fee23f9Smrg /*  num is the descriptor of the number to be checked and encoded     */
2164fee23f9Smrg /*	   [its values, including the coefficient, may be modified]   */
2174fee23f9Smrg /*  set is the context to use					      */
2184fee23f9Smrg /*  returns df							      */
2194fee23f9Smrg /*								      */
2204fee23f9Smrg /* The num descriptor may point to a bcd8 string of any length; this  */
2214fee23f9Smrg /* string may have leading insignificant zeros.  If it has more than  */
2224fee23f9Smrg /* DECPMAX digits then the final digit can be a round-for-reround     */
2234fee23f9Smrg /* digit (i.e., it may include a sticky bit residue).		      */
2244fee23f9Smrg /*								      */
2254fee23f9Smrg /* The exponent (q) may be one of the codes for a special value and   */
2264fee23f9Smrg /* can be up to 999999999 for conversion from string.		      */
2274fee23f9Smrg /*								      */
2284fee23f9Smrg /* No error is possible, but Inexact, Underflow, and/or Overflow may  */
2294fee23f9Smrg /* be set.							      */
2304fee23f9Smrg /* ------------------------------------------------------------------ */
2314fee23f9Smrg /* Constant whose size varies with format; also the check for surprises */
2324fee23f9Smrg static uByte allnines[DECPMAX]=
2334fee23f9Smrg #if SINGLE
2344fee23f9Smrg   {9, 9, 9, 9, 9, 9, 9};
2354fee23f9Smrg #elif DOUBLE
2364fee23f9Smrg   {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
2374fee23f9Smrg #elif QUAD
2384fee23f9Smrg   {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
2394fee23f9Smrg    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
2404fee23f9Smrg #endif
2414fee23f9Smrg 
decFinalize(decFloat * df,bcdnum * num,decContext * set)2424fee23f9Smrg static decFloat * decFinalize(decFloat *df, bcdnum *num,
2434fee23f9Smrg 			      decContext *set) {
2444fee23f9Smrg   uByte *ub;		      /* work */
2454fee23f9Smrg   uInt	 dpd;		      /* .. */
2464fee23f9Smrg   uInt	 uiwork;	      /* for macros */
2474fee23f9Smrg   uByte *umsd=num->msd;       /* local copy */
2484fee23f9Smrg   uByte *ulsd=num->lsd;       /* .. */
2494fee23f9Smrg   uInt	 encode;	      /* encoding accumulator */
2504fee23f9Smrg   Int	 length;	      /* coefficient length */
2514fee23f9Smrg 
2524fee23f9Smrg   #if DECCHECK
2534fee23f9Smrg   Int clen=ulsd-umsd+1;
2544fee23f9Smrg   #if QUAD
2554fee23f9Smrg     #define COEXTRA 2			     /* extra-long coefficent */
2564fee23f9Smrg   #else
2574fee23f9Smrg     #define COEXTRA 0
2584fee23f9Smrg   #endif
2594fee23f9Smrg   if (clen<1 || clen>DECPMAX*3+2+COEXTRA)
2604fee23f9Smrg     printf("decFinalize: suspect coefficient [length=%ld]\n", (LI)clen);
2614fee23f9Smrg   if (num->sign!=0 && num->sign!=DECFLOAT_Sign)
2624fee23f9Smrg     printf("decFinalize: bad sign [%08lx]\n", (LI)num->sign);
2634fee23f9Smrg   if (!EXPISSPECIAL(num->exponent)
2644fee23f9Smrg       && (num->exponent>1999999999 || num->exponent<-1999999999))
2654fee23f9Smrg     printf("decFinalize: improbable exponent [%ld]\n", (LI)num->exponent);
2664fee23f9Smrg   /* decShowNum(num, "final"); */
2674fee23f9Smrg   #endif
2684fee23f9Smrg 
2694fee23f9Smrg   /* A special will have an 'exponent' which is very positive and a */
2704fee23f9Smrg   /* coefficient < DECPMAX */
2714fee23f9Smrg   length=(uInt)(ulsd-umsd+1);		     /* coefficient length */
2724fee23f9Smrg 
2734fee23f9Smrg   if (!NUMISSPECIAL(num)) {
2744fee23f9Smrg     Int   drop; 			     /* digits to be dropped */
2754fee23f9Smrg     /* skip leading insignificant zeros to calculate an exact length */
2764fee23f9Smrg     /* [this is quite expensive] */
2774fee23f9Smrg     if (*umsd==0) {
2784fee23f9Smrg       for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4;
2794fee23f9Smrg       for (; *umsd==0 && umsd<ulsd;) umsd++;
2804fee23f9Smrg       length=ulsd-umsd+1;		     /* recalculate */
2814fee23f9Smrg       }
2824fee23f9Smrg     drop=MAXI(length-DECPMAX, DECQTINY-num->exponent);
2834fee23f9Smrg     /* drop can now be > digits for bottom-clamp (subnormal) cases */
2844fee23f9Smrg     if (drop>0) {			     /* rounding needed */
2854fee23f9Smrg       /* (decFloatQuantize has very similar code to this, so any */
2864fee23f9Smrg       /* changes may need to be made there, too) */
2874fee23f9Smrg       uByte *roundat;			     /* -> re-round digit */
2884fee23f9Smrg       uByte reround;			     /* reround value */
2894fee23f9Smrg       /* printf("Rounding; drop=%ld\n", (LI)drop); */
2904fee23f9Smrg 
2914fee23f9Smrg       num->exponent+=drop;		     /* always update exponent */
2924fee23f9Smrg 
2934fee23f9Smrg       /* Three cases here: */
2944fee23f9Smrg       /*   1. new LSD is in coefficient (almost always) */
2954fee23f9Smrg       /*   2. new LSD is digit to left of coefficient (so MSD is */
2964fee23f9Smrg       /*      round-for-reround digit) */
2974fee23f9Smrg       /*   3. new LSD is to left of case 2 (whole coefficient is sticky) */
2984fee23f9Smrg       /* [duplicate check-stickies code to save a test] */
2994fee23f9Smrg       /* [by-digit check for stickies as runs of zeros are rare] */
3004fee23f9Smrg       if (drop<length) {		     /* NB lengths not addresses */
3014fee23f9Smrg 	roundat=umsd+length-drop;
3024fee23f9Smrg 	reround=*roundat;
3034fee23f9Smrg 	for (ub=roundat+1; ub<=ulsd; ub++) {
3044fee23f9Smrg 	  if (*ub!=0) { 		     /* non-zero to be discarded */
3054fee23f9Smrg 	    reround=DECSTICKYTAB[reround];   /* apply sticky bit */
3064fee23f9Smrg 	    break;			     /* [remainder don't-care] */
3074fee23f9Smrg 	    }
3084fee23f9Smrg 	  } /* check stickies */
3094fee23f9Smrg 	ulsd=roundat-1; 		     /* new LSD */
3104fee23f9Smrg 	}
3114fee23f9Smrg        else {				     /* edge case */
3124fee23f9Smrg 	if (drop==length) {
3134fee23f9Smrg 	  roundat=umsd;
3144fee23f9Smrg 	  reround=*roundat;
3154fee23f9Smrg 	  }
3164fee23f9Smrg 	 else {
3174fee23f9Smrg 	  roundat=umsd-1;
3184fee23f9Smrg 	  reround=0;
3194fee23f9Smrg 	  }
3204fee23f9Smrg 	for (ub=roundat+1; ub<=ulsd; ub++) {
3214fee23f9Smrg 	  if (*ub!=0) { 		     /* non-zero to be discarded */
3224fee23f9Smrg 	    reround=DECSTICKYTAB[reround];   /* apply sticky bit */
3234fee23f9Smrg 	    break;			     /* [remainder don't-care] */
3244fee23f9Smrg 	    }
3254fee23f9Smrg 	  } /* check stickies */
3264fee23f9Smrg 	*umsd=0;			     /* coefficient is a 0 */
3274fee23f9Smrg 	ulsd=umsd;			     /* .. */
3284fee23f9Smrg 	}
3294fee23f9Smrg 
3304fee23f9Smrg       if (reround!=0) { 		     /* discarding non-zero */
3314fee23f9Smrg 	uInt bump=0;
3324fee23f9Smrg 	set->status|=DEC_Inexact;
3334fee23f9Smrg 	/* if adjusted exponent [exp+digits-1] is < EMIN then num is */
3344fee23f9Smrg 	/* subnormal -- so raise Underflow */
3354fee23f9Smrg 	if (num->exponent<DECEMIN && (num->exponent+(ulsd-umsd+1)-1)<DECEMIN)
3364fee23f9Smrg 	  set->status|=DEC_Underflow;
3374fee23f9Smrg 
3384fee23f9Smrg 	/* next decide whether increment of the coefficient is needed */
3394fee23f9Smrg 	if (set->round==DEC_ROUND_HALF_EVEN) {	  /* fastpath slowest case */
3404fee23f9Smrg 	  if (reround>5) bump=1;		  /* >0.5 goes up */
3414fee23f9Smrg 	   else if (reround==5) 		  /* exactly 0.5000 .. */
3424fee23f9Smrg 	    bump=*ulsd & 0x01;			  /* .. up iff [new] lsd is odd */
3434fee23f9Smrg 	  } /* r-h-e */
3444fee23f9Smrg 	 else switch (set->round) {
3454fee23f9Smrg 	  case DEC_ROUND_DOWN: {
3464fee23f9Smrg 	    /* no change */
3474fee23f9Smrg 	    break;} /* r-d */
3484fee23f9Smrg 	  case DEC_ROUND_HALF_DOWN: {
3494fee23f9Smrg 	    if (reround>5) bump=1;
3504fee23f9Smrg 	    break;} /* r-h-d */
3514fee23f9Smrg 	  case DEC_ROUND_HALF_UP: {
3524fee23f9Smrg 	    if (reround>=5) bump=1;
3534fee23f9Smrg 	    break;} /* r-h-u */
3544fee23f9Smrg 	  case DEC_ROUND_UP: {
3554fee23f9Smrg 	    if (reround>0) bump=1;
3564fee23f9Smrg 	    break;} /* r-u */
3574fee23f9Smrg 	  case DEC_ROUND_CEILING: {
3584fee23f9Smrg 	    /* same as _UP for positive numbers, and as _DOWN for negatives */
3594fee23f9Smrg 	    if (!num->sign && reround>0) bump=1;
3604fee23f9Smrg 	    break;} /* r-c */
3614fee23f9Smrg 	  case DEC_ROUND_FLOOR: {
3624fee23f9Smrg 	    /* same as _UP for negative numbers, and as _DOWN for positive */
3634fee23f9Smrg 	    /* [negative reround cannot occur on 0] */
3644fee23f9Smrg 	    if (num->sign && reround>0) bump=1;
3654fee23f9Smrg 	    break;} /* r-f */
3664fee23f9Smrg 	  case DEC_ROUND_05UP: {
3674fee23f9Smrg 	    if (reround>0) { /* anything out there is 'sticky' */
3684fee23f9Smrg 	      /* bump iff lsd=0 or 5; this cannot carry so it could be */
3694fee23f9Smrg 	      /* effected immediately with no bump -- but the code */
3704fee23f9Smrg 	      /* is clearer if this is done the same way as the others */
3714fee23f9Smrg 	      if (*ulsd==0 || *ulsd==5) bump=1;
3724fee23f9Smrg 	      }
3734fee23f9Smrg 	    break;} /* r-r */
3744fee23f9Smrg 	  default: {	  /* e.g., DEC_ROUND_MAX */
3754fee23f9Smrg 	    set->status|=DEC_Invalid_context;
3764fee23f9Smrg 	    #if DECCHECK
3774fee23f9Smrg 	    printf("Unknown rounding mode: %ld\n", (LI)set->round);
3784fee23f9Smrg 	    #endif
3794fee23f9Smrg 	    break;}
3804fee23f9Smrg 	  } /* switch (not r-h-e) */
3814fee23f9Smrg 	/* printf("ReRound: %ld  bump: %ld\n", (LI)reround, (LI)bump); */
3824fee23f9Smrg 
3834fee23f9Smrg 	if (bump!=0) {			     /* need increment */
3844fee23f9Smrg 	  /* increment the coefficient; this might end up with 1000... */
3854fee23f9Smrg 	  /* (after the all nines case) */
3864fee23f9Smrg 	  ub=ulsd;
3874fee23f9Smrg 	  for(; ub-3>=umsd && UBTOUI(ub-3)==0x09090909; ub-=4)	{
3884fee23f9Smrg 	    UBFROMUI(ub-3, 0);		     /* to 00000000 */
3894fee23f9Smrg 	    }
3904fee23f9Smrg 	  /* [note ub could now be to left of msd, and it is not safe */
3914fee23f9Smrg 	  /* to write to the the left of the msd] */
3924fee23f9Smrg 	  /* now at most 3 digits left to non-9 (usually just the one) */
3934fee23f9Smrg 	  for (; ub>=umsd; *ub=0, ub--) {
3944fee23f9Smrg 	    if (*ub==9) continue;	     /* carry */
3954fee23f9Smrg 	    *ub+=1;
3964fee23f9Smrg 	    break;
3974fee23f9Smrg 	    }
3984fee23f9Smrg 	  if (ub<umsd) {		     /* had all-nines */
3994fee23f9Smrg 	    *umsd=1;			     /* coefficient to 1000... */
4004fee23f9Smrg 	    /* usually the 1000... coefficient can be used as-is */
4014fee23f9Smrg 	    if ((ulsd-umsd+1)==DECPMAX) {
4024fee23f9Smrg 	      num->exponent++;
4034fee23f9Smrg 	      }
4044fee23f9Smrg 	     else {
4054fee23f9Smrg 	      /* if coefficient is shorter than Pmax then num is */
4064fee23f9Smrg 	      /* subnormal, so extend it; this is safe as drop>0 */
4074fee23f9Smrg 	      /* (or, if the coefficient was supplied above, it could */
4084fee23f9Smrg 	      /* not be 9); this may make the result normal. */
4094fee23f9Smrg 	      ulsd++;
4104fee23f9Smrg 	      *ulsd=0;
4114fee23f9Smrg 	      /* [exponent unchanged] */
4124fee23f9Smrg 	      #if DECCHECK
4134fee23f9Smrg 	      if (num->exponent!=DECQTINY) /* sanity check */
4144fee23f9Smrg 		printf("decFinalize: bad all-nines extend [^%ld, %ld]\n",
4154fee23f9Smrg 		       (LI)num->exponent, (LI)(ulsd-umsd+1));
4164fee23f9Smrg 	      #endif
4174fee23f9Smrg 	      } /* subnormal extend */
4184fee23f9Smrg 	    } /* had all-nines */
4194fee23f9Smrg 	  } /* bump needed */
4204fee23f9Smrg 	} /* inexact rounding */
4214fee23f9Smrg 
4224fee23f9Smrg       length=ulsd-umsd+1;		/* recalculate (may be <DECPMAX) */
4234fee23f9Smrg       } /* need round (drop>0) */
4244fee23f9Smrg 
4254fee23f9Smrg     /* The coefficient will now fit and has final length unless overflow */
4264fee23f9Smrg     /* decShowNum(num, "rounded"); */
4274fee23f9Smrg 
4284fee23f9Smrg     /* if exponent is >=emax may have to clamp, overflow, or fold-down */
4294fee23f9Smrg     if (num->exponent>DECEMAX-(DECPMAX-1)) { /* is edge case */
4304fee23f9Smrg       /* printf("overflow checks...\n"); */
4314fee23f9Smrg       if (*ulsd==0 && ulsd==umsd) {	/* have zero */
4324fee23f9Smrg 	num->exponent=DECEMAX-(DECPMAX-1); /* clamp to max */
4334fee23f9Smrg 	}
4344fee23f9Smrg        else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */
4354fee23f9Smrg 	/* Overflow -- these could go straight to encoding, here, but */
4364fee23f9Smrg 	/* instead num is adjusted to keep the code cleaner */
4374fee23f9Smrg 	Flag needmax=0; 		/* 1 for finite result */
4384fee23f9Smrg 	set->status|=(DEC_Overflow | DEC_Inexact);
4394fee23f9Smrg 	switch (set->round) {
4404fee23f9Smrg 	  case DEC_ROUND_DOWN: {
4414fee23f9Smrg 	    needmax=1;			/* never Infinity */
4424fee23f9Smrg 	    break;} /* r-d */
4434fee23f9Smrg 	  case DEC_ROUND_05UP: {
4444fee23f9Smrg 	    needmax=1;			/* never Infinity */
4454fee23f9Smrg 	    break;} /* r-05 */
4464fee23f9Smrg 	  case DEC_ROUND_CEILING: {
4474fee23f9Smrg 	    if (num->sign) needmax=1;	/* Infinity iff non-negative */
4484fee23f9Smrg 	    break;} /* r-c */
4494fee23f9Smrg 	  case DEC_ROUND_FLOOR: {
4504fee23f9Smrg 	    if (!num->sign) needmax=1;	/* Infinity iff negative */
4514fee23f9Smrg 	    break;} /* r-f */
4524fee23f9Smrg 	  default: break;		/* Infinity in all other cases */
4534fee23f9Smrg 	  }
4544fee23f9Smrg 	if (!needmax) { 		/* easy .. set Infinity */
4554fee23f9Smrg 	  num->exponent=DECFLOAT_Inf;
4564fee23f9Smrg 	  *umsd=0;			/* be clean: coefficient to 0 */
4574fee23f9Smrg 	  ulsd=umsd;			/* .. */
4584fee23f9Smrg 	  }
4594fee23f9Smrg 	 else { 			/* return Nmax */
4604fee23f9Smrg 	  umsd=allnines;		/* use constant array */
4614fee23f9Smrg 	  ulsd=allnines+DECPMAX-1;
4624fee23f9Smrg 	  num->exponent=DECEMAX-(DECPMAX-1);
4634fee23f9Smrg 	  }
4644fee23f9Smrg 	}
4654fee23f9Smrg        else { /* no overflow but non-zero and may have to fold-down */
4664fee23f9Smrg 	Int shift=num->exponent-(DECEMAX-(DECPMAX-1));
4674fee23f9Smrg 	if (shift>0) {			/* fold-down needed */
4684fee23f9Smrg 	  /* fold down needed; must copy to buffer in order to pad */
4694fee23f9Smrg 	  /* with zeros safely; fortunately this is not the worst case */
4704fee23f9Smrg 	  /* path because cannot have had a round */
4714fee23f9Smrg 	  uByte buffer[ROUNDUP(DECPMAX+3, 4)]; /* [+3 allows uInt padding] */
4724fee23f9Smrg 	  uByte *s=umsd;		/* source */
4734fee23f9Smrg 	  uByte *t=buffer;		/* safe target */
4744fee23f9Smrg 	  uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
4754fee23f9Smrg 	  /* printf("folddown shift=%ld\n", (LI)shift); */
4764fee23f9Smrg 	  for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s));
4774fee23f9Smrg 	  for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0);  /* pad 0s */
4784fee23f9Smrg 	  num->exponent-=shift;
4794fee23f9Smrg 	  umsd=buffer;
4804fee23f9Smrg 	  ulsd=tlsd;
4814fee23f9Smrg 	  }
4824fee23f9Smrg 	} /* fold-down? */
4834fee23f9Smrg       length=ulsd-umsd+1;		/* recalculate length */
4844fee23f9Smrg       } /* high-end edge case */
4854fee23f9Smrg     } /* finite number */
4864fee23f9Smrg 
4874fee23f9Smrg   /*------------------------------------------------------------------*/
4884fee23f9Smrg   /* At this point the result will properly fit the decFloat	      */
4894fee23f9Smrg   /* encoding, and it can be encoded with no possibility of error     */
4904fee23f9Smrg   /*------------------------------------------------------------------*/
4914fee23f9Smrg   /* Following code does not alter coefficient (could be allnines array) */
4924fee23f9Smrg 
4934fee23f9Smrg   /* fast path possible when DECPMAX digits */
4944fee23f9Smrg   if (length==DECPMAX) {
4954fee23f9Smrg     return decFloatFromBCD(df, num->exponent, umsd, num->sign);
4964fee23f9Smrg     } /* full-length */
4974fee23f9Smrg 
4984fee23f9Smrg   /* slower path when not a full-length number; must care about length */
4994fee23f9Smrg   /* [coefficient length here will be < DECPMAX] */
5004fee23f9Smrg   if (!NUMISSPECIAL(num)) {		/* is still finite */
5014fee23f9Smrg     /* encode the combination field and exponent continuation */
5024fee23f9Smrg     uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */
5034fee23f9Smrg     uInt code=(uexp>>DECECONL)<<4;	/* top two bits of exp */
5044fee23f9Smrg     /* [msd==0] */
5054fee23f9Smrg     /* look up the combination field and make high word */
5064fee23f9Smrg     encode=DECCOMBFROM[code];		/* indexed by (0-2)*16+msd */
5074fee23f9Smrg     encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
5084fee23f9Smrg     }
5094fee23f9Smrg    else encode=num->exponent;		/* special [already in word] */
5104fee23f9Smrg   encode|=num->sign;			/* add sign */
5114fee23f9Smrg 
5124fee23f9Smrg   /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
5134fee23f9Smrg   /* refers to the declet from the least significant three digits) */
5144fee23f9Smrg   /* and put the corresponding DPD code into dpd.  Access to umsd and */
5154fee23f9Smrg   /* ulsd (pointers to the most and least significant digit of the */
5164fee23f9Smrg   /* variable-length coefficient) is assumed, along with use of a */
5174fee23f9Smrg   /* working pointer, uInt *ub. */
5184fee23f9Smrg   /* As not full-length then chances are there are many leading zeros */
5194fee23f9Smrg   /* [and there may be a partial triad] */
5204fee23f9Smrg   #define getDPDt(dpd, n) ub=ulsd-(3*(n))-2;			      \
5214fee23f9Smrg     if (ub<umsd-2) dpd=0;					      \
5224fee23f9Smrg      else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];  \
5234fee23f9Smrg      else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];}
5244fee23f9Smrg 
5254fee23f9Smrg   /* place the declets in the encoding words and copy to result (df), */
5264fee23f9Smrg   /* according to endianness; in all cases complete the sign word */
5274fee23f9Smrg   /* first */
5284fee23f9Smrg   #if DECPMAX==7
5294fee23f9Smrg     getDPDt(dpd, 1);
5304fee23f9Smrg     encode|=dpd<<10;
5314fee23f9Smrg     getDPDt(dpd, 0);
5324fee23f9Smrg     encode|=dpd;
5334fee23f9Smrg     DFWORD(df, 0)=encode;     /* just the one word */
5344fee23f9Smrg 
5354fee23f9Smrg   #elif DECPMAX==16
5364fee23f9Smrg     getDPDt(dpd, 4); encode|=dpd<<8;
5374fee23f9Smrg     getDPDt(dpd, 3); encode|=dpd>>2;
5384fee23f9Smrg     DFWORD(df, 0)=encode;
5394fee23f9Smrg     encode=dpd<<30;
5404fee23f9Smrg     getDPDt(dpd, 2); encode|=dpd<<20;
5414fee23f9Smrg     getDPDt(dpd, 1); encode|=dpd<<10;
5424fee23f9Smrg     getDPDt(dpd, 0); encode|=dpd;
5434fee23f9Smrg     DFWORD(df, 1)=encode;
5444fee23f9Smrg 
5454fee23f9Smrg   #elif DECPMAX==34
5464fee23f9Smrg     getDPDt(dpd,10); encode|=dpd<<4;
5474fee23f9Smrg     getDPDt(dpd, 9); encode|=dpd>>6;
5484fee23f9Smrg     DFWORD(df, 0)=encode;
5494fee23f9Smrg 
5504fee23f9Smrg     encode=dpd<<26;
5514fee23f9Smrg     getDPDt(dpd, 8); encode|=dpd<<16;
5524fee23f9Smrg     getDPDt(dpd, 7); encode|=dpd<<6;
5534fee23f9Smrg     getDPDt(dpd, 6); encode|=dpd>>4;
5544fee23f9Smrg     DFWORD(df, 1)=encode;
5554fee23f9Smrg 
5564fee23f9Smrg     encode=dpd<<28;
5574fee23f9Smrg     getDPDt(dpd, 5); encode|=dpd<<18;
5584fee23f9Smrg     getDPDt(dpd, 4); encode|=dpd<<8;
5594fee23f9Smrg     getDPDt(dpd, 3); encode|=dpd>>2;
5604fee23f9Smrg     DFWORD(df, 2)=encode;
5614fee23f9Smrg 
5624fee23f9Smrg     encode=dpd<<30;
5634fee23f9Smrg     getDPDt(dpd, 2); encode|=dpd<<20;
5644fee23f9Smrg     getDPDt(dpd, 1); encode|=dpd<<10;
5654fee23f9Smrg     getDPDt(dpd, 0); encode|=dpd;
5664fee23f9Smrg     DFWORD(df, 3)=encode;
5674fee23f9Smrg   #endif
5684fee23f9Smrg 
5694fee23f9Smrg   /* printf("Status: %08lx\n", (LI)set->status); */
5704fee23f9Smrg   /* decFloatShow(df, "final2"); */
5714fee23f9Smrg   return df;
5724fee23f9Smrg   } /* decFinalize */
5734fee23f9Smrg 
5744fee23f9Smrg /* ------------------------------------------------------------------ */
5754fee23f9Smrg /* decFloatFromBCD -- set decFloat from exponent, BCD8, and sign      */
5764fee23f9Smrg /*								      */
5774fee23f9Smrg /*  df is the target decFloat					      */
5784fee23f9Smrg /*  exp is the in-range unbiased exponent, q, or a special value in   */
5794fee23f9Smrg /*    the form returned by decFloatGetExponent			      */
5804fee23f9Smrg /*  bcdar holds DECPMAX digits to set the coefficient from, one       */
5814fee23f9Smrg /*    digit in each byte (BCD8 encoding); the first (MSD) is ignored  */
5824fee23f9Smrg /*    if df is a NaN; all are ignored if df is infinite.	      */
5834fee23f9Smrg /*    All bytes must be in 0-9; results are undefined otherwise.      */
5844fee23f9Smrg /*  sig is DECFLOAT_Sign to set the sign bit, 0 otherwise	      */
5854fee23f9Smrg /*  returns df, which will be canonical 			      */
5864fee23f9Smrg /*								      */
5874fee23f9Smrg /* No error is possible, and no status will be set.		      */
5884fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatFromBCD(decFloat * df,Int exp,const uByte * bcdar,Int sig)5894fee23f9Smrg decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
5904fee23f9Smrg 			   Int sig) {
5914fee23f9Smrg   uInt encode, dpd;			/* work */
5924fee23f9Smrg   const uByte *ub;			/* .. */
5934fee23f9Smrg 
5944fee23f9Smrg   if (EXPISSPECIAL(exp)) encode=exp|sig;/* specials already encoded */
5954fee23f9Smrg    else {				/* is finite */
5964fee23f9Smrg     /* encode the combination field and exponent continuation */
5974fee23f9Smrg     uInt uexp=(uInt)(exp+DECBIAS);	/* biased exponent */
5984fee23f9Smrg     uInt code=(uexp>>DECECONL)<<4;	/* top two bits of exp */
5994fee23f9Smrg     code+=bcdar[0];			/* add msd */
6004fee23f9Smrg     /* look up the combination field and make high word */
6014fee23f9Smrg     encode=DECCOMBFROM[code]|sig;	/* indexed by (0-2)*16+msd */
6024fee23f9Smrg     encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
6034fee23f9Smrg     }
6044fee23f9Smrg 
6054fee23f9Smrg   /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
6064fee23f9Smrg   /* refers to the declet from the least significant three digits) */
6074fee23f9Smrg   /* and put the corresponding DPD code into dpd. */
6084fee23f9Smrg   /* Use of a working pointer, uInt *ub, is assumed. */
6094fee23f9Smrg 
6104fee23f9Smrg   #define getDPDb(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2;     \
6114fee23f9Smrg     dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];
6124fee23f9Smrg 
6134fee23f9Smrg   /* place the declets in the encoding words and copy to result (df), */
6144fee23f9Smrg   /* according to endianness; in all cases complete the sign word */
6154fee23f9Smrg   /* first */
6164fee23f9Smrg   #if DECPMAX==7
6174fee23f9Smrg     getDPDb(dpd, 1);
6184fee23f9Smrg     encode|=dpd<<10;
6194fee23f9Smrg     getDPDb(dpd, 0);
6204fee23f9Smrg     encode|=dpd;
6214fee23f9Smrg     DFWORD(df, 0)=encode;     /* just the one word */
6224fee23f9Smrg 
6234fee23f9Smrg   #elif DECPMAX==16
6244fee23f9Smrg     getDPDb(dpd, 4); encode|=dpd<<8;
6254fee23f9Smrg     getDPDb(dpd, 3); encode|=dpd>>2;
6264fee23f9Smrg     DFWORD(df, 0)=encode;
6274fee23f9Smrg     encode=dpd<<30;
6284fee23f9Smrg     getDPDb(dpd, 2); encode|=dpd<<20;
6294fee23f9Smrg     getDPDb(dpd, 1); encode|=dpd<<10;
6304fee23f9Smrg     getDPDb(dpd, 0); encode|=dpd;
6314fee23f9Smrg     DFWORD(df, 1)=encode;
6324fee23f9Smrg 
6334fee23f9Smrg   #elif DECPMAX==34
6344fee23f9Smrg     getDPDb(dpd,10); encode|=dpd<<4;
6354fee23f9Smrg     getDPDb(dpd, 9); encode|=dpd>>6;
6364fee23f9Smrg     DFWORD(df, 0)=encode;
6374fee23f9Smrg 
6384fee23f9Smrg     encode=dpd<<26;
6394fee23f9Smrg     getDPDb(dpd, 8); encode|=dpd<<16;
6404fee23f9Smrg     getDPDb(dpd, 7); encode|=dpd<<6;
6414fee23f9Smrg     getDPDb(dpd, 6); encode|=dpd>>4;
6424fee23f9Smrg     DFWORD(df, 1)=encode;
6434fee23f9Smrg 
6444fee23f9Smrg     encode=dpd<<28;
6454fee23f9Smrg     getDPDb(dpd, 5); encode|=dpd<<18;
6464fee23f9Smrg     getDPDb(dpd, 4); encode|=dpd<<8;
6474fee23f9Smrg     getDPDb(dpd, 3); encode|=dpd>>2;
6484fee23f9Smrg     DFWORD(df, 2)=encode;
6494fee23f9Smrg 
6504fee23f9Smrg     encode=dpd<<30;
6514fee23f9Smrg     getDPDb(dpd, 2); encode|=dpd<<20;
6524fee23f9Smrg     getDPDb(dpd, 1); encode|=dpd<<10;
6534fee23f9Smrg     getDPDb(dpd, 0); encode|=dpd;
6544fee23f9Smrg     DFWORD(df, 3)=encode;
6554fee23f9Smrg   #endif
6564fee23f9Smrg   /* decFloatShow(df, "fromB"); */
6574fee23f9Smrg   return df;
6584fee23f9Smrg   } /* decFloatFromBCD */
6594fee23f9Smrg 
6604fee23f9Smrg /* ------------------------------------------------------------------ */
6614fee23f9Smrg /* decFloatFromPacked -- set decFloat from exponent and packed BCD    */
6624fee23f9Smrg /*								      */
6634fee23f9Smrg /*  df is the target decFloat					      */
6644fee23f9Smrg /*  exp is the in-range unbiased exponent, q, or a special value in   */
6654fee23f9Smrg /*    the form returned by decFloatGetExponent			      */
6664fee23f9Smrg /*  packed holds DECPMAX packed decimal digits plus a sign nibble     */
6674fee23f9Smrg /*    (all 6 codes are OK); the first (MSD) is ignored if df is a NaN */
6684fee23f9Smrg /*    and all except sign are ignored if df is infinite.  For DOUBLE  */
6694fee23f9Smrg /*    and QUAD the first (pad) nibble is also ignored in all cases.   */
6704fee23f9Smrg /*    All coefficient nibbles must be in 0-9 and sign in A-F; results */
6714fee23f9Smrg /*    are undefined otherwise.					      */
6724fee23f9Smrg /*  returns df, which will be canonical 			      */
6734fee23f9Smrg /*								      */
6744fee23f9Smrg /* No error is possible, and no status will be set.		      */
6754fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatFromPacked(decFloat * df,Int exp,const uByte * packed)6764fee23f9Smrg decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
6774fee23f9Smrg   uByte bcdar[DECPMAX+2];		/* work [+1 for pad, +1 for sign] */
6784fee23f9Smrg   const uByte *ip;			/* .. */
6794fee23f9Smrg   uByte *op;				/* .. */
6804fee23f9Smrg   Int	sig=0;				/* sign */
6814fee23f9Smrg 
6824fee23f9Smrg   /* expand coefficient and sign to BCDAR */
6834fee23f9Smrg   #if SINGLE
6844fee23f9Smrg   op=bcdar+1;				/* no pad digit */
6854fee23f9Smrg   #else
6864fee23f9Smrg   op=bcdar;				/* first (pad) digit ignored */
6874fee23f9Smrg   #endif
6884fee23f9Smrg   for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) {
6894fee23f9Smrg     *op++=*ip>>4;
6904fee23f9Smrg     *op++=(uByte)(*ip&0x0f);		/* [final nibble is sign] */
6914fee23f9Smrg     }
6924fee23f9Smrg   op--; 				/* -> sign byte */
6934fee23f9Smrg   if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
6944fee23f9Smrg 
6954fee23f9Smrg   if (EXPISSPECIAL(exp)) {		/* Infinity or NaN */
6964fee23f9Smrg     if (!EXPISINF(exp)) bcdar[1]=0;	/* a NaN: ignore MSD */
6974fee23f9Smrg      else memset(bcdar+1, 0, DECPMAX);	/* Infinite: coefficient to 0 */
6984fee23f9Smrg     }
6994fee23f9Smrg   return decFloatFromBCD(df, exp, bcdar+1, sig);
7004fee23f9Smrg   } /* decFloatFromPacked */
7014fee23f9Smrg 
7024fee23f9Smrg /* ------------------------------------------------------------------ */
7034fee23f9Smrg /* decFloatFromPackedChecked -- set from exponent and packed; checked */
7044fee23f9Smrg /*								      */
7054fee23f9Smrg /*  df is the target decFloat					      */
7064fee23f9Smrg /*  exp is the in-range unbiased exponent, q, or a special value in   */
7074fee23f9Smrg /*    the form returned by decFloatGetExponent			      */
7084fee23f9Smrg /*  packed holds DECPMAX packed decimal digits plus a sign nibble     */
7094fee23f9Smrg /*    (all 6 codes are OK); the first (MSD) must be 0 if df is a NaN  */
7104fee23f9Smrg /*    and all digits must be 0 if df is infinite.  For DOUBLE and     */
7114fee23f9Smrg /*    QUAD the first (pad) nibble must be 0.			      */
7124fee23f9Smrg /*    All coefficient nibbles must be in 0-9 and sign in A-F.	      */
7134fee23f9Smrg /*  returns df, which will be canonical or NULL if any of the	      */
7144fee23f9Smrg /*    requirements are not met (if this case df is unchanged); that   */
7154fee23f9Smrg /*    is, the input data must be as returned by decFloatToPacked,     */
716b17d1066Smrg /*    except that all six sign codes are accepted.		      */
7174fee23f9Smrg /*								      */
7184fee23f9Smrg /* No status will be set.					      */
7194fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatFromPackedChecked(decFloat * df,Int exp,const uByte * packed)7204fee23f9Smrg decFloat * decFloatFromPackedChecked(decFloat *df, Int exp,
7214fee23f9Smrg 				     const uByte *packed) {
7224fee23f9Smrg   uByte bcdar[DECPMAX+2];		/* work [+1 for pad, +1 for sign] */
7234fee23f9Smrg   const uByte *ip;			/* .. */
7244fee23f9Smrg   uByte *op;				/* .. */
7254fee23f9Smrg   Int	sig=0;				/* sign */
7264fee23f9Smrg 
7274fee23f9Smrg   /* expand coefficient and sign to BCDAR */
7284fee23f9Smrg   #if SINGLE
7294fee23f9Smrg   op=bcdar+1;				/* no pad digit */
7304fee23f9Smrg   #else
7314fee23f9Smrg   op=bcdar;				/* first (pad) digit here */
7324fee23f9Smrg   #endif
7334fee23f9Smrg   for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) {
7344fee23f9Smrg     *op=*ip>>4;
7354fee23f9Smrg     if (*op>9) return NULL;
7364fee23f9Smrg     op++;
7374fee23f9Smrg     *op=(uByte)(*ip&0x0f);		/* [final nibble is sign] */
7384fee23f9Smrg     if (*op>9 && ip<packed+((DECPMAX+2)/2)-1) return NULL;
7394fee23f9Smrg     op++;
7404fee23f9Smrg     }
7414fee23f9Smrg   op--; 				/* -> sign byte */
7424fee23f9Smrg   if (*op<=9) return NULL;		/* bad sign */
7434fee23f9Smrg   if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
7444fee23f9Smrg 
7454fee23f9Smrg   #if !SINGLE
7464fee23f9Smrg   if (bcdar[0]!=0) return NULL; 	/* bad pad nibble */
7474fee23f9Smrg   #endif
7484fee23f9Smrg 
7494fee23f9Smrg   if (EXPISNAN(exp)) {			/* a NaN */
7504fee23f9Smrg     if (bcdar[1]!=0) return NULL;	/* bad msd */
7514fee23f9Smrg     } /* NaN */
7524fee23f9Smrg    else if (EXPISINF(exp)) {		/* is infinite */
7534fee23f9Smrg     Int i;
7544fee23f9Smrg     for (i=0; i<DECPMAX; i++) {
7554fee23f9Smrg       if (bcdar[i+1]!=0) return NULL;	/* should be all zeros */
7564fee23f9Smrg       }
7574fee23f9Smrg     } /* infinity */
7584fee23f9Smrg    else {				/* finite */
7594fee23f9Smrg     /* check the exponent is in range */
7604fee23f9Smrg     if (exp>DECEMAX-DECPMAX+1) return NULL;
7614fee23f9Smrg     if (exp<DECEMIN-DECPMAX+1) return NULL;
7624fee23f9Smrg     }
7634fee23f9Smrg   return decFloatFromBCD(df, exp, bcdar+1, sig);
7644fee23f9Smrg   } /* decFloatFromPacked */
7654fee23f9Smrg 
7664fee23f9Smrg /* ------------------------------------------------------------------ */
7674fee23f9Smrg /* decFloatFromString -- conversion from numeric string 	      */
7684fee23f9Smrg /*								      */
7694fee23f9Smrg /*  result  is the decFloat format number which gets the result of    */
7704fee23f9Smrg /*	    the conversion					      */
7714fee23f9Smrg /*  *string is the character string which should contain a valid      */
7724fee23f9Smrg /*	    number (which may be a special value), \0-terminated      */
7734fee23f9Smrg /*	    If there are too many significant digits in the	      */
7744fee23f9Smrg /*	    coefficient it will be rounded.			      */
7754fee23f9Smrg /*  set     is the context					      */
7764fee23f9Smrg /*  returns result						      */
7774fee23f9Smrg /*								      */
7784fee23f9Smrg /* The length of the coefficient and the size of the exponent are     */
7794fee23f9Smrg /* checked by this routine, so the correct error (Underflow or	      */
7804fee23f9Smrg /* Overflow) can be reported or rounding applied, as necessary.       */
7814fee23f9Smrg /*								      */
7824fee23f9Smrg /* There is no limit to the coefficient length for finite inputs;     */
7834fee23f9Smrg /* NaN payloads must be integers with no more than DECPMAX-1 digits.  */
7844fee23f9Smrg /* Exponents may have up to nine significant digits.		      */
7854fee23f9Smrg /*								      */
7864fee23f9Smrg /* If bad syntax is detected, the result will be a quiet NaN.	      */
7874fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatFromString(decFloat * result,const char * string,decContext * set)7884fee23f9Smrg decFloat * decFloatFromString(decFloat *result, const char *string,
7894fee23f9Smrg 			      decContext *set) {
7904fee23f9Smrg   Int	 digits;		   /* count of digits in coefficient */
7914fee23f9Smrg   const  char *dotchar=NULL;	   /* where dot was found [NULL if none] */
7924fee23f9Smrg   const  char *cfirst=string;	   /* -> first character of decimal part */
7934fee23f9Smrg   const  char *c;		   /* work */
7944fee23f9Smrg   uByte *ub;			   /* .. */
7954fee23f9Smrg   uInt	 uiwork;		   /* for macros */
7964fee23f9Smrg   bcdnum num;			   /* collects data for finishing */
7974fee23f9Smrg   uInt	 error=DEC_Conversion_syntax;	/* assume the worst */
7984fee23f9Smrg   uByte  buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */
7994fee23f9Smrg 				   /* some common rounding, +3, & pad */
8004fee23f9Smrg   #if DECTRACE
8014fee23f9Smrg   /* printf("FromString %s ...\n", string); */
8024fee23f9Smrg   #endif
8034fee23f9Smrg 
8044fee23f9Smrg   for(;;) {				/* once-only 'loop' */
8054fee23f9Smrg     num.sign=0; 			/* assume non-negative */
8064fee23f9Smrg     num.msd=buffer;			/* MSD is here always */
8074fee23f9Smrg 
8084fee23f9Smrg     /* detect and validate the coefficient, including any leading, */
8094fee23f9Smrg     /* trailing, or embedded '.' */
8104fee23f9Smrg     /* [could test four-at-a-time here (saving 10% for decQuads), */
8114fee23f9Smrg     /* but that risks storage violation because the position of the */
8124fee23f9Smrg     /* terminator is unknown] */
8134fee23f9Smrg     for (c=string;; c++) {		/* -> input character */
8144fee23f9Smrg       if (((unsigned)(*c-'0'))<=9) continue; /* '0' through '9' is good */
8154fee23f9Smrg       if (*c=='\0') break;		/* most common non-digit */
8164fee23f9Smrg       if (*c=='.') {
8174fee23f9Smrg 	if (dotchar!=NULL) break;	/* not first '.' */
8184fee23f9Smrg 	dotchar=c;			/* record offset into decimal part */
8194fee23f9Smrg 	continue;}
8204fee23f9Smrg       if (c==string) {			/* first in string... */
8214fee23f9Smrg 	if (*c=='-') {			/* valid - sign */
8224fee23f9Smrg 	  cfirst++;
8234fee23f9Smrg 	  num.sign=DECFLOAT_Sign;
8244fee23f9Smrg 	  continue;}
8254fee23f9Smrg 	if (*c=='+') {			/* valid + sign */
8264fee23f9Smrg 	  cfirst++;
8274fee23f9Smrg 	  continue;}
8284fee23f9Smrg 	}
8294fee23f9Smrg       /* *c is not a digit, terminator, or a valid +, -, or '.' */
8304fee23f9Smrg       break;
8314fee23f9Smrg       } /* c loop */
8324fee23f9Smrg 
8334fee23f9Smrg     digits=(uInt)(c-cfirst);		/* digits (+1 if a dot) */
8344fee23f9Smrg 
8354fee23f9Smrg     if (digits>0) {			/* had digits and/or dot */
8364fee23f9Smrg       const char *clast=c-1;		/* note last coefficient char position */
8374fee23f9Smrg       Int exp=0;			/* exponent accumulator */
8384fee23f9Smrg       if (*c!='\0') {			/* something follows the coefficient */
8394fee23f9Smrg 	uInt edig;			/* unsigned work */
8404fee23f9Smrg 	/* had some digits and more to come; expect E[+|-]nnn now */
8414fee23f9Smrg 	const char *firstexp;		/* exponent first non-zero */
8424fee23f9Smrg 	if (*c!='E' && *c!='e') break;
8434fee23f9Smrg 	c++;				/* to (optional) sign */
8444fee23f9Smrg 	if (*c=='-' || *c=='+') c++;	/* step over sign (c=clast+2) */
8454fee23f9Smrg 	if (*c=='\0') break;		/* no digits!  (e.g., '1.2E') */
8464fee23f9Smrg 	for (; *c=='0';) c++;		/* skip leading zeros [even last] */
8474fee23f9Smrg 	firstexp=c;			/* remember start [maybe '\0'] */
8484fee23f9Smrg 	/* gather exponent digits */
8494fee23f9Smrg 	edig=(uInt)*c-(uInt)'0';
8504fee23f9Smrg 	if (edig<=9) {			/* [check not bad or terminator] */
8514fee23f9Smrg 	  exp+=edig;			/* avoid initial X10 */
8524fee23f9Smrg 	  c++;
8534fee23f9Smrg 	  for (;; c++) {
8544fee23f9Smrg 	    edig=(uInt)*c-(uInt)'0';
8554fee23f9Smrg 	    if (edig>9) break;
8564fee23f9Smrg 	    exp=exp*10+edig;
8574fee23f9Smrg 	    }
8584fee23f9Smrg 	  }
8594fee23f9Smrg 	/* if not now on the '\0', *c must not be a digit */
8604fee23f9Smrg 	if (*c!='\0') break;
8614fee23f9Smrg 
8624fee23f9Smrg 	/* (this next test must be after the syntax checks) */
8634fee23f9Smrg 	/* if definitely more than the possible digits for format then */
8644fee23f9Smrg 	/* the exponent may have wrapped, so simply set it to a certain */
8654fee23f9Smrg 	/* over/underflow value */
8664fee23f9Smrg 	if (c>firstexp+DECEMAXD) exp=DECEMAX*2;
8674fee23f9Smrg 	if (*(clast+2)=='-') exp=-exp;	/* was negative */
8684fee23f9Smrg 	} /* digits>0 */
8694fee23f9Smrg 
8704fee23f9Smrg       if (dotchar!=NULL) {		/* had a '.' */
8714fee23f9Smrg 	digits--;			/* remove from digits count */
8724fee23f9Smrg 	if (digits==0) break;		/* was dot alone: bad syntax */
8734fee23f9Smrg 	exp-=(Int)(clast-dotchar);	/* adjust exponent */
8744fee23f9Smrg 	/* [the '.' can now be ignored] */
8754fee23f9Smrg 	}
8764fee23f9Smrg       num.exponent=exp; 		/* exponent is good; store it */
8774fee23f9Smrg 
8784fee23f9Smrg       /* Here when whole string has been inspected and syntax is good */
8794fee23f9Smrg       /* cfirst->first digit or dot, clast->last digit or dot */
8804fee23f9Smrg       error=0;				/* no error possible now */
8814fee23f9Smrg 
8824fee23f9Smrg       /* if the number of digits in the coefficient will fit in buffer */
8834fee23f9Smrg       /* then it can simply be converted to bcd8 and copied -- decFinalize */
8844fee23f9Smrg       /* will take care of leading zeros and rounding; the buffer is big */
8854fee23f9Smrg       /* enough for all canonical coefficients, including 0.00000nn... */
8864fee23f9Smrg       ub=buffer;
8874fee23f9Smrg       if (digits<=(Int)(sizeof(buffer)-3)) { /* [-3 allows by-4s copy] */
8884fee23f9Smrg 	c=cfirst;
8894fee23f9Smrg 	if (dotchar!=NULL) {		     /* a dot to worry about */
8904fee23f9Smrg 	  if (*(c+1)=='.') {		     /* common canonical case */
8914fee23f9Smrg 	    *ub++=(uByte)(*c-'0');	     /* copy leading digit */
8924fee23f9Smrg 	    c+=2;			     /* prepare to handle rest */
8934fee23f9Smrg 	    }
8944fee23f9Smrg 	   else for (; c<=clast;) {	     /* '.' could be anywhere */
8954fee23f9Smrg 	    /* as usual, go by fours when safe; NB it has been asserted */
8964fee23f9Smrg 	    /* that a '.' does not have the same mask as a digit */
8974fee23f9Smrg 	    if (c<=clast-3			       /* safe for four */
8984fee23f9Smrg 	     && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) {    /* test four */
8994fee23f9Smrg 	      UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);      /* to BCD8 */
9004fee23f9Smrg 	      ub+=4;
9014fee23f9Smrg 	      c+=4;
9024fee23f9Smrg 	      continue;
9034fee23f9Smrg 	      }
9044fee23f9Smrg 	    if (*c=='.') {		     /* found the dot */
9054fee23f9Smrg 	      c++;			     /* step over it .. */
9064fee23f9Smrg 	      break;			     /* .. and handle the rest */
9074fee23f9Smrg 	      }
9084fee23f9Smrg 	    *ub++=(uByte)(*c++-'0');
9094fee23f9Smrg 	    }
9104fee23f9Smrg 	  } /* had dot */
9114fee23f9Smrg 	/* Now no dot; do this by fours (where safe) */
9124fee23f9Smrg 	for (; c<=clast-3; c+=4, ub+=4) UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);
9134fee23f9Smrg 	for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0');
9144fee23f9Smrg 	num.lsd=buffer+digits-1;	     /* record new LSD */
9154fee23f9Smrg 	} /* fits */
9164fee23f9Smrg 
9174fee23f9Smrg        else {				     /* too long for buffer */
9184fee23f9Smrg 	/* [This is a rare and unusual case; arbitrary-length input] */
9194fee23f9Smrg 	/* strip leading zeros [but leave final 0 if all 0's] */
9204fee23f9Smrg 	if (*cfirst=='.') cfirst++;	     /* step past dot at start */
9214fee23f9Smrg 	if (*cfirst=='0') {		     /* [cfirst always -> digit] */
9224fee23f9Smrg 	  for (; cfirst<clast; cfirst++) {
9234fee23f9Smrg 	    if (*cfirst!='0') { 	     /* non-zero found */
9244fee23f9Smrg 	      if (*cfirst=='.') continue;    /* [ignore] */
9254fee23f9Smrg 	      break;			     /* done */
9264fee23f9Smrg 	      }
9274fee23f9Smrg 	    digits--;			     /* 0 stripped */
9284fee23f9Smrg 	    } /* cfirst */
9294fee23f9Smrg 	  } /* at least one leading 0 */
9304fee23f9Smrg 
9314fee23f9Smrg 	/* the coefficient is now as short as possible, but may still */
9324fee23f9Smrg 	/* be too long; copy up to Pmax+1 digits to the buffer, then */
9334fee23f9Smrg 	/* just record any non-zeros (set round-for-reround digit) */
9344fee23f9Smrg 	for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
9354fee23f9Smrg 	  /* (see commentary just above) */
9364fee23f9Smrg 	  if (c<=clast-3			  /* safe for four */
9374fee23f9Smrg 	   && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
9384fee23f9Smrg 	    UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);   /* to BCD8 */
9394fee23f9Smrg 	    ub+=4;
9404fee23f9Smrg 	    c+=3;			     /* [will become 4] */
9414fee23f9Smrg 	    continue;
9424fee23f9Smrg 	    }
9434fee23f9Smrg 	  if (*c=='.') continue;	     /* [ignore] */
9444fee23f9Smrg 	  *ub++=(uByte)(*c-'0');
9454fee23f9Smrg 	  }
9464fee23f9Smrg 	ub--;				     /* -> LSD */
9474fee23f9Smrg 	for (; c<=clast; c++) { 	     /* inspect remaining chars */
9484fee23f9Smrg 	  if (*c!='0') {		     /* sticky bit needed */
9494fee23f9Smrg 	    if (*c=='.') continue;	     /* [ignore] */
9504fee23f9Smrg 	    *ub=DECSTICKYTAB[*ub];	     /* update round-for-reround */
9514fee23f9Smrg 	    break;			     /* no need to look at more */
9524fee23f9Smrg 	    }
9534fee23f9Smrg 	  }
9544fee23f9Smrg 	num.lsd=ub;			     /* record LSD */
9554fee23f9Smrg 	/* adjust exponent for dropped digits */
9564fee23f9Smrg 	num.exponent+=digits-(Int)(ub-buffer+1);
9574fee23f9Smrg 	} /* too long for buffer */
9584fee23f9Smrg       } /* digits or dot */
9594fee23f9Smrg 
9604fee23f9Smrg      else {				/* no digits or dot were found */
9614fee23f9Smrg       if (*c=='\0') break;		/* nothing to come is bad */
9624fee23f9Smrg       /* only Infinities and NaNs are allowed, here */
9634fee23f9Smrg       buffer[0]=0;			/* default a coefficient of 0 */
9644fee23f9Smrg       num.lsd=buffer;			/* .. */
9654fee23f9Smrg       if (decBiStr(c, "infinity", "INFINITY")
9664fee23f9Smrg        || decBiStr(c, "inf", "INF")) num.exponent=DECFLOAT_Inf;
9674fee23f9Smrg        else {				/* should be a NaN */
9684fee23f9Smrg 	num.exponent=DECFLOAT_qNaN;	/* assume quiet NaN */
9694fee23f9Smrg 	if (*c=='s' || *c=='S') {	/* probably an sNaN */
9704fee23f9Smrg 	  c++;
9714fee23f9Smrg 	  num.exponent=DECFLOAT_sNaN;	/* assume is in fact sNaN */
9724fee23f9Smrg 	  }
9734fee23f9Smrg 	if (*c!='N' && *c!='n') break;	/* check caseless "NaN" */
9744fee23f9Smrg 	c++;
9754fee23f9Smrg 	if (*c!='a' && *c!='A') break;	/* .. */
9764fee23f9Smrg 	c++;
9774fee23f9Smrg 	if (*c!='N' && *c!='n') break;	/* .. */
9784fee23f9Smrg 	c++;
9794fee23f9Smrg 	/* now either nothing, or nnnn payload (no dots), expected */
9804fee23f9Smrg 	/* -> start of integer, and skip leading 0s [including plain 0] */
9814fee23f9Smrg 	for (cfirst=c; *cfirst=='0';) cfirst++;
9824fee23f9Smrg 	if (*cfirst!='\0') {		/* not empty or all-0, payload */
9834fee23f9Smrg 	  /* payload found; check all valid digits and copy to buffer as bcd8 */
9844fee23f9Smrg 	  ub=buffer;
9854fee23f9Smrg 	  for (c=cfirst;; c++, ub++) {
9864fee23f9Smrg 	    if ((unsigned)(*c-'0')>9) break; /* quit if not 0-9 */
9874fee23f9Smrg 	    if (c-cfirst==DECPMAX-1) break;  /* too many digits */
9884fee23f9Smrg 	    *ub=(uByte)(*c-'0');	/* good bcd8 */
9894fee23f9Smrg 	    }
9904fee23f9Smrg 	  if (*c!='\0') break;		/* not all digits, or too many */
9914fee23f9Smrg 	  num.lsd=ub-1; 		/* record new LSD */
9924fee23f9Smrg 	  }
9934fee23f9Smrg 	} /* NaN or sNaN */
9944fee23f9Smrg       error=0;				/* syntax is OK */
9954fee23f9Smrg       break;				/* done with specials */
9964fee23f9Smrg       } /* digits=0 (special expected) */
9974fee23f9Smrg     break;
9984fee23f9Smrg     }					/* [for(;;) break] */
9994fee23f9Smrg 
10004fee23f9Smrg   /* decShowNum(&num, "fromStr"); */
10014fee23f9Smrg 
10024fee23f9Smrg   if (error!=0) {
10034fee23f9Smrg     set->status|=error;
10044fee23f9Smrg     num.exponent=DECFLOAT_qNaN; 	/* set up quiet NaN */
10054fee23f9Smrg     num.sign=0; 			/* .. with 0 sign */
10064fee23f9Smrg     buffer[0]=0;			/* .. and coefficient */
10074fee23f9Smrg     num.lsd=buffer;			/* .. */
10084fee23f9Smrg     /* decShowNum(&num, "oops"); */
10094fee23f9Smrg     }
10104fee23f9Smrg 
10114fee23f9Smrg   /* decShowNum(&num, "dffs"); */
10124fee23f9Smrg   decFinalize(result, &num, set);	/* round, check, and lay out */
10134fee23f9Smrg   /* decFloatShow(result, "fromString"); */
10144fee23f9Smrg   return result;
10154fee23f9Smrg   } /* decFloatFromString */
10164fee23f9Smrg 
10174fee23f9Smrg /* ------------------------------------------------------------------ */
10184fee23f9Smrg /* decFloatFromWider -- conversion from next-wider format	      */
10194fee23f9Smrg /*								      */
10204fee23f9Smrg /*  result  is the decFloat format number which gets the result of    */
10214fee23f9Smrg /*	    the conversion					      */
10224fee23f9Smrg /*  wider   is the decFloatWider format number which will be narrowed */
10234fee23f9Smrg /*  set     is the context					      */
10244fee23f9Smrg /*  returns result						      */
10254fee23f9Smrg /*								      */
10264fee23f9Smrg /* Narrowing can cause rounding, overflow, etc., but not Invalid      */
10274fee23f9Smrg /* operation (sNaNs are copied and do not signal).		      */
10284fee23f9Smrg /* ------------------------------------------------------------------ */
10294fee23f9Smrg /* narrow-to is not possible for decQuad format numbers; simply omit */
10304fee23f9Smrg #if !QUAD
decFloatFromWider(decFloat * result,const decFloatWider * wider,decContext * set)10314fee23f9Smrg decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
10324fee23f9Smrg 			     decContext *set) {
10334fee23f9Smrg   bcdnum num;				/* collects data for finishing */
10344fee23f9Smrg   uByte  bcdar[DECWPMAX];		/* room for wider coefficient */
10354fee23f9Smrg   uInt	 widerhi=DFWWORD(wider, 0);	/* top word */
10364fee23f9Smrg   Int	 exp;
10374fee23f9Smrg 
10384fee23f9Smrg   GETWCOEFF(wider, bcdar);
10394fee23f9Smrg 
10404fee23f9Smrg   num.msd=bcdar;			/* MSD is here always */
10414fee23f9Smrg   num.lsd=bcdar+DECWPMAX-1;		/* LSD is here always */
10424fee23f9Smrg   num.sign=widerhi&0x80000000;		/* extract sign [DECFLOAT_Sign=Neg] */
10434fee23f9Smrg 
10444fee23f9Smrg   /* decode the wider combination field to exponent */
10454fee23f9Smrg   exp=DECCOMBWEXP[widerhi>>26]; 	/* decode from wider combination field */
10464fee23f9Smrg   /* if it is a special there's nothing to do unless sNaN; if it's */
10474fee23f9Smrg   /* finite then add the (wider) exponent continuation and unbias */
10484fee23f9Smrg   if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */
10494fee23f9Smrg    else exp+=GETWECON(wider)-DECWBIAS;
10504fee23f9Smrg   num.exponent=exp;
10514fee23f9Smrg 
10524fee23f9Smrg   /* decShowNum(&num, "dffw"); */
10534fee23f9Smrg   return decFinalize(result, &num, set);/* round, check, and lay out */
10544fee23f9Smrg   } /* decFloatFromWider */
10554fee23f9Smrg #endif
10564fee23f9Smrg 
10574fee23f9Smrg /* ------------------------------------------------------------------ */
10584fee23f9Smrg /* decFloatGetCoefficient -- get coefficient as BCD8		      */
10594fee23f9Smrg /*								      */
10604fee23f9Smrg /*  df is the decFloat from which to extract the coefficient	      */
10614fee23f9Smrg /*  bcdar is where DECPMAX bytes will be written, one BCD digit in    */
10624fee23f9Smrg /*    each byte (BCD8 encoding); if df is a NaN the first byte will   */
10634fee23f9Smrg /*    be zero, and if it is infinite they will all be zero	      */
10644fee23f9Smrg /*  returns the sign of the coefficient (DECFLOAT_Sign if negative,   */
10654fee23f9Smrg /*    0 otherwise)						      */
10664fee23f9Smrg /*								      */
10674fee23f9Smrg /* No error is possible, and no status will be set.  If df is a       */
10684fee23f9Smrg /* special value the array is set to zeros (for Infinity) or to the   */
10694fee23f9Smrg /* payload of a qNaN or sNaN.					      */
10704fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatGetCoefficient(const decFloat * df,uByte * bcdar)10714fee23f9Smrg Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) {
10724fee23f9Smrg   if (DFISINF(df)) memset(bcdar, 0, DECPMAX);
10734fee23f9Smrg    else {
10744fee23f9Smrg     GETCOEFF(df, bcdar);	   /* use macro */
10754fee23f9Smrg     if (DFISNAN(df)) bcdar[0]=0;   /* MSD needs correcting */
10764fee23f9Smrg     }
10774fee23f9Smrg   return DFISSIGNED(df);
10784fee23f9Smrg   } /* decFloatGetCoefficient */
10794fee23f9Smrg 
10804fee23f9Smrg /* ------------------------------------------------------------------ */
10814fee23f9Smrg /* decFloatGetExponent -- get unbiased exponent 		      */
10824fee23f9Smrg /*								      */
10834fee23f9Smrg /*  df is the decFloat from which to extract the exponent	      */
10844fee23f9Smrg /*  returns the exponent, q.					      */
10854fee23f9Smrg /*								      */
10864fee23f9Smrg /* No error is possible, and no status will be set.  If df is a       */
10874fee23f9Smrg /* special value the first seven bits of the decFloat are returned,   */
10884fee23f9Smrg /* left adjusted and with the first (sign) bit set to 0 (followed by  */
10894fee23f9Smrg /* 25 0 bits).	e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN).  */
10904fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatGetExponent(const decFloat * df)10914fee23f9Smrg Int decFloatGetExponent(const decFloat *df) {
10924fee23f9Smrg   if (DFISSPECIAL(df)) return DFWORD(df, 0)&0x7e000000;
10934fee23f9Smrg   return GETEXPUN(df);
10944fee23f9Smrg   } /* decFloatGetExponent */
10954fee23f9Smrg 
10964fee23f9Smrg /* ------------------------------------------------------------------ */
10974fee23f9Smrg /* decFloatSetCoefficient -- set coefficient from BCD8		      */
10984fee23f9Smrg /*								      */
10994fee23f9Smrg /*  df is the target decFloat (and source of exponent/special value)  */
11004fee23f9Smrg /*  bcdar holds DECPMAX digits to set the coefficient from, one       */
11014fee23f9Smrg /*    digit in each byte (BCD8 encoding); the first (MSD) is ignored  */
11024fee23f9Smrg /*    if df is a NaN; all are ignored if df is infinite.	      */
11034fee23f9Smrg /*  sig is DECFLOAT_Sign to set the sign bit, 0 otherwise	      */
11044fee23f9Smrg /*  returns df, which will be canonical 			      */
11054fee23f9Smrg /*								      */
11064fee23f9Smrg /* No error is possible, and no status will be set.		      */
11074fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatSetCoefficient(decFloat * df,const uByte * bcdar,Int sig)11084fee23f9Smrg decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar,
11094fee23f9Smrg 				  Int sig) {
11104fee23f9Smrg   uInt exp;			   /* for exponent */
11114fee23f9Smrg   uByte bcdzero[DECPMAX];	   /* for infinities */
11124fee23f9Smrg 
11134fee23f9Smrg   /* Exponent/special code is extracted from df */
11144fee23f9Smrg   if (DFISSPECIAL(df)) {
11154fee23f9Smrg     exp=DFWORD(df, 0)&0x7e000000;
11164fee23f9Smrg     if (DFISINF(df)) {
11174fee23f9Smrg       memset(bcdzero, 0, DECPMAX);
11184fee23f9Smrg       return decFloatFromBCD(df, exp, bcdzero, sig);
11194fee23f9Smrg       }
11204fee23f9Smrg     }
11214fee23f9Smrg    else exp=GETEXPUN(df);
11224fee23f9Smrg   return decFloatFromBCD(df, exp, bcdar, sig);
11234fee23f9Smrg   } /* decFloatSetCoefficient */
11244fee23f9Smrg 
11254fee23f9Smrg /* ------------------------------------------------------------------ */
11264fee23f9Smrg /* decFloatSetExponent -- set exponent or special value 	      */
11274fee23f9Smrg /*								      */
11284fee23f9Smrg /*  df	is the target decFloat (and source of coefficient/payload)    */
11294fee23f9Smrg /*  set is the context for reporting status			      */
11304fee23f9Smrg /*  exp is the unbiased exponent, q, or a special value in the form   */
11314fee23f9Smrg /*    returned by decFloatGetExponent				      */
11324fee23f9Smrg /*  returns df, which will be canonical 			      */
11334fee23f9Smrg /*								      */
11344fee23f9Smrg /* No error is possible, but Overflow or Underflow might occur.       */
11354fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatSetExponent(decFloat * df,decContext * set,Int exp)11364fee23f9Smrg decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) {
11374fee23f9Smrg   uByte  bcdcopy[DECPMAX];	   /* for coefficient */
11384fee23f9Smrg   bcdnum num;			   /* work */
11394fee23f9Smrg   num.exponent=exp;
11404fee23f9Smrg   num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */
11414fee23f9Smrg   if (DFISSPECIAL(df)) {	   /* MSD or more needs correcting */
11424fee23f9Smrg     if (DFISINF(df)) memset(bcdcopy, 0, DECPMAX);
11434fee23f9Smrg     bcdcopy[0]=0;
11444fee23f9Smrg     }
11454fee23f9Smrg   num.msd=bcdcopy;
11464fee23f9Smrg   num.lsd=bcdcopy+DECPMAX-1;
11474fee23f9Smrg   return decFinalize(df, &num, set);
11484fee23f9Smrg   } /* decFloatSetExponent */
11494fee23f9Smrg 
11504fee23f9Smrg /* ------------------------------------------------------------------ */
11514fee23f9Smrg /* decFloatRadix -- returns the base (10)			      */
11524fee23f9Smrg /*								      */
11534fee23f9Smrg /*   df is any decFloat of this format				      */
11544fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatRadix(const decFloat * df)11554fee23f9Smrg uInt decFloatRadix(const decFloat *df) {
11564fee23f9Smrg   if (df) return 10;			     /* to placate compiler */
11574fee23f9Smrg   return 10;
11584fee23f9Smrg   } /* decFloatRadix */
11594fee23f9Smrg 
11604fee23f9Smrg #if (DECCHECK || DECTRACE)
11614fee23f9Smrg /* ------------------------------------------------------------------ */
11624fee23f9Smrg /* decFloatShow -- printf a decFloat in hexadecimal and decimal       */
11634fee23f9Smrg /*   df  is the decFloat to show				      */
11644fee23f9Smrg /*   tag is a tag string displayed with the number		      */
11654fee23f9Smrg /*								      */
11664fee23f9Smrg /* This is a debug aid; the precise format of the string may change.  */
11674fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatShow(const decFloat * df,const char * tag)11684fee23f9Smrg void decFloatShow(const decFloat *df, const char *tag) {
11694fee23f9Smrg   char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */
11704fee23f9Smrg   char buff[DECSTRING]; 		/* for value in decimal */
11714fee23f9Smrg   Int i, j=0;
11724fee23f9Smrg 
11734fee23f9Smrg   for (i=0; i<DECBYTES; i++) {
11744fee23f9Smrg     #if DECLITEND
11754fee23f9Smrg       sprintf(&hexbuf[j], "%02x", df->bytes[DECBYTES-1-i]);
11764fee23f9Smrg     #else
11774fee23f9Smrg       sprintf(&hexbuf[j], "%02x", df->bytes[i]);
11784fee23f9Smrg     #endif
11794fee23f9Smrg     j+=2;
11804fee23f9Smrg     /* the next line adds blank (and terminator) after final pair, too */
11814fee23f9Smrg     if ((i+1)%4==0) {strcpy(&hexbuf[j], " "); j++;}
11824fee23f9Smrg     }
11834fee23f9Smrg   decFloatToString(df, buff);
11844fee23f9Smrg   printf(">%s> %s [big-endian]	%s\n", tag, hexbuf, buff);
11854fee23f9Smrg   return;
11864fee23f9Smrg   } /* decFloatShow */
11874fee23f9Smrg #endif
11884fee23f9Smrg 
11894fee23f9Smrg /* ------------------------------------------------------------------ */
11904fee23f9Smrg /* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat      */
11914fee23f9Smrg /*								      */
11924fee23f9Smrg /*  df is the source decFloat					      */
11934fee23f9Smrg /*  exp will be set to the unbiased exponent, q, or to a special      */
11944fee23f9Smrg /*    value in the form returned by decFloatGetExponent 	      */
11954fee23f9Smrg /*  bcdar is where DECPMAX bytes will be written, one BCD digit in    */
11964fee23f9Smrg /*    each byte (BCD8 encoding); if df is a NaN the first byte will   */
11974fee23f9Smrg /*    be zero, and if it is infinite they will all be zero	      */
11984fee23f9Smrg /*  returns the sign of the coefficient (DECFLOAT_Sign if negative,   */
11994fee23f9Smrg /*    0 otherwise)						      */
12004fee23f9Smrg /*								      */
12014fee23f9Smrg /* No error is possible, and no status will be set.		      */
12024fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatToBCD(const decFloat * df,Int * exp,uByte * bcdar)12034fee23f9Smrg Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) {
12044fee23f9Smrg   if (DFISINF(df)) {
12054fee23f9Smrg     memset(bcdar, 0, DECPMAX);
12064fee23f9Smrg     *exp=DFWORD(df, 0)&0x7e000000;
12074fee23f9Smrg     }
12084fee23f9Smrg    else {
12094fee23f9Smrg     GETCOEFF(df, bcdar);	   /* use macro */
12104fee23f9Smrg     if (DFISNAN(df)) {
12114fee23f9Smrg       bcdar[0]=0;		   /* MSD needs correcting */
12124fee23f9Smrg       *exp=DFWORD(df, 0)&0x7e000000;
12134fee23f9Smrg       }
12144fee23f9Smrg      else {			   /* finite */
12154fee23f9Smrg       *exp=GETEXPUN(df);
12164fee23f9Smrg       }
12174fee23f9Smrg     }
12184fee23f9Smrg   return DFISSIGNED(df);
12194fee23f9Smrg   } /* decFloatToBCD */
12204fee23f9Smrg 
12214fee23f9Smrg /* ------------------------------------------------------------------ */
12224fee23f9Smrg /* decFloatToEngString -- conversion to numeric string, engineering   */
12234fee23f9Smrg /*								      */
12244fee23f9Smrg /*  df is the decFloat format number to convert 		      */
12254fee23f9Smrg /*  string is the string where the result will be laid out	      */
12264fee23f9Smrg /*								      */
12274fee23f9Smrg /* string must be at least DECPMAX+9 characters (the worst case is    */
12284fee23f9Smrg /* "-0.00000nnn...nnn\0", which is as long as the exponent form when  */
12294fee23f9Smrg /* DECEMAXD<=4); this condition is asserted above		      */
12304fee23f9Smrg /*								      */
12314fee23f9Smrg /* No error is possible, and no status will be set		      */
12324fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatToEngString(const decFloat * df,char * string)12334fee23f9Smrg char * decFloatToEngString(const decFloat *df, char *string){
12344fee23f9Smrg   uInt msd;			   /* coefficient MSD */
12354fee23f9Smrg   Int  exp;			   /* exponent top two bits or full */
12364fee23f9Smrg   uInt comb;			   /* combination field */
12374fee23f9Smrg   char *cstart; 		   /* coefficient start */
12384fee23f9Smrg   char *c;			   /* output pointer in string */
12394fee23f9Smrg   char *s, *t;			   /* .. (source, target) */
12404fee23f9Smrg   Int  pre, e;			   /* work */
12414fee23f9Smrg   const uByte *u;		   /* .. */
12424fee23f9Smrg   uInt	uiwork; 		   /* for macros [one compiler needs */
12434fee23f9Smrg 				   /* volatile here to avoid bug, but */
12444fee23f9Smrg 				   /* that doubles execution time] */
12454fee23f9Smrg 
12464fee23f9Smrg   /* Source words; macro handles endianness */
12474fee23f9Smrg   uInt sourhi=DFWORD(df, 0);	   /* word with sign */
12484fee23f9Smrg   #if DECPMAX==16
12494fee23f9Smrg   uInt sourlo=DFWORD(df, 1);
12504fee23f9Smrg   #elif DECPMAX==34
12514fee23f9Smrg   uInt sourmh=DFWORD(df, 1);
12524fee23f9Smrg   uInt sourml=DFWORD(df, 2);
12534fee23f9Smrg   uInt sourlo=DFWORD(df, 3);
12544fee23f9Smrg   #endif
12554fee23f9Smrg 
12564fee23f9Smrg   c=string;			   /* where result will go */
12574fee23f9Smrg   if (((Int)sourhi)<0) *c++='-';   /* handle sign */
12584fee23f9Smrg   comb=sourhi>>26;		   /* sign+combination field */
12594fee23f9Smrg   msd=DECCOMBMSD[comb]; 	   /* decode the combination field */
12604fee23f9Smrg   exp=DECCOMBEXP[comb]; 	   /* .. */
12614fee23f9Smrg 
12624fee23f9Smrg   if (EXPISSPECIAL(exp)) {	   /* special */
12634fee23f9Smrg     if (exp==DECFLOAT_Inf) {	   /* infinity */
12644fee23f9Smrg       strcpy(c,   "Inf");
12654fee23f9Smrg       strcpy(c+3, "inity");
12664fee23f9Smrg       return string;		   /* easy */
12674fee23f9Smrg       }
12684fee23f9Smrg     if (sourhi&0x02000000) *c++='s'; /* sNaN */
12694fee23f9Smrg     strcpy(c, "NaN");		   /* complete word */
12704fee23f9Smrg     c+=3;			   /* step past */
12714fee23f9Smrg     /* quick exit if the payload is zero */
12724fee23f9Smrg     #if DECPMAX==7
12734fee23f9Smrg     if ((sourhi&0x000fffff)==0) return string;
12744fee23f9Smrg     #elif DECPMAX==16
12754fee23f9Smrg     if (sourlo==0 && (sourhi&0x0003ffff)==0) return string;
12764fee23f9Smrg     #elif DECPMAX==34
12774fee23f9Smrg     if (sourlo==0 && sourml==0 && sourmh==0
12784fee23f9Smrg      && (sourhi&0x00003fff)==0) return string;
12794fee23f9Smrg     #endif
12804fee23f9Smrg     /* otherwise drop through to add integer; set correct exp etc. */
12814fee23f9Smrg     exp=0; msd=0;		   /* setup for following code */
12824fee23f9Smrg     }
12834fee23f9Smrg    else { /* complete exponent; top two bits are in place */
12844fee23f9Smrg     exp+=GETECON(df)-DECBIAS;	   /* .. + continuation and unbias */
12854fee23f9Smrg     }
12864fee23f9Smrg 
12874fee23f9Smrg   /* convert the digits of the significand to characters */
12884fee23f9Smrg   cstart=c;			   /* save start of coefficient */
12894fee23f9Smrg   if (msd) *c++=(char)('0'+(char)msd);	/* non-zero most significant digit */
12904fee23f9Smrg 
12914fee23f9Smrg   /* Decode the declets.  After extracting each declet, it is */
12924fee23f9Smrg   /* decoded to a 4-uByte sequence by table lookup; the four uBytes */
12934fee23f9Smrg   /* are the three encoded BCD8 digits followed by a 1-byte length */
12944fee23f9Smrg   /* (significant digits, except that 000 has length 0).  This allows */
12954fee23f9Smrg   /* us to left-align the first declet with non-zero content, then */
12964fee23f9Smrg   /* the remaining ones are full 3-char length.  Fixed-length copies */
12974fee23f9Smrg   /* are used because variable-length memcpy causes a subroutine call */
12984fee23f9Smrg   /* in at least two compilers.  (The copies are length 4 for speed */
12994fee23f9Smrg   /* and are safe because the last item in the array is of length */
13004fee23f9Smrg   /* three and has the length byte following.) */
13014fee23f9Smrg   #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4];	 \
13024fee23f9Smrg 	 if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
13034fee23f9Smrg 	  else if (*(u+3)) {					 \
13044fee23f9Smrg 	   UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
13054fee23f9Smrg 
13064fee23f9Smrg   #if DECPMAX==7
13074fee23f9Smrg   dpd2char(sourhi>>10); 		/* declet 1 */
13084fee23f9Smrg   dpd2char(sourhi);			/* declet 2 */
13094fee23f9Smrg 
13104fee23f9Smrg   #elif DECPMAX==16
13114fee23f9Smrg   dpd2char(sourhi>>8);			/* declet 1 */
13124fee23f9Smrg   dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
13134fee23f9Smrg   dpd2char(sourlo>>20); 		/* declet 3 */
13144fee23f9Smrg   dpd2char(sourlo>>10); 		/* declet 4 */
13154fee23f9Smrg   dpd2char(sourlo);			/* declet 5 */
13164fee23f9Smrg 
13174fee23f9Smrg   #elif DECPMAX==34
13184fee23f9Smrg   dpd2char(sourhi>>4);			/* declet 1 */
13194fee23f9Smrg   dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
13204fee23f9Smrg   dpd2char(sourmh>>16); 		/* declet 3 */
13214fee23f9Smrg   dpd2char(sourmh>>6);			/* declet 4 */
13224fee23f9Smrg   dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
13234fee23f9Smrg   dpd2char(sourml>>18); 		/* declet 6 */
13244fee23f9Smrg   dpd2char(sourml>>8);			/* declet 7 */
13254fee23f9Smrg   dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
13264fee23f9Smrg   dpd2char(sourlo>>20); 		/* declet 9 */
13274fee23f9Smrg   dpd2char(sourlo>>10); 		/* declet 10 */
13284fee23f9Smrg   dpd2char(sourlo);			/* declet 11 */
13294fee23f9Smrg   #endif
13304fee23f9Smrg 
13314fee23f9Smrg   if (c==cstart) *c++='0';	   /* all zeros, empty -- make "0" */
13324fee23f9Smrg 
13334fee23f9Smrg   if (exp==0) { 		   /* integer or NaN case -- easy */
13344fee23f9Smrg     *c='\0';			   /* terminate */
13354fee23f9Smrg     return string;
13364fee23f9Smrg     }
13374fee23f9Smrg   /* non-0 exponent */
13384fee23f9Smrg 
13394fee23f9Smrg   e=0;				   /* assume no E */
13404fee23f9Smrg   pre=(Int)(c-cstart)+exp;	   /* length+exp  [c->LSD+1] */
13414fee23f9Smrg   /* [here, pre-exp is the digits count (==1 for zero)] */
13424fee23f9Smrg 
13434fee23f9Smrg   if (exp>0 || pre<-5) {	   /* need exponential form */
13444fee23f9Smrg     e=pre-1;			   /* calculate E value */
13454fee23f9Smrg     pre=1;			   /* assume one digit before '.' */
13464fee23f9Smrg     if (e!=0) { 		   /* engineering: may need to adjust */
13474fee23f9Smrg       Int adj;			   /* adjustment */
13484fee23f9Smrg       /* The C remainder operator is undefined for negative numbers, so */
13494fee23f9Smrg       /* a positive remainder calculation must be used here */
13504fee23f9Smrg       if (e<0) {
13514fee23f9Smrg 	adj=(-e)%3;
13524fee23f9Smrg 	if (adj!=0) adj=3-adj;
13534fee23f9Smrg 	}
13544fee23f9Smrg        else { /* e>0 */
13554fee23f9Smrg 	adj=e%3;
13564fee23f9Smrg 	}
13574fee23f9Smrg       e=e-adj;
13584fee23f9Smrg       /* if dealing with zero still produce an exponent which is a */
13594fee23f9Smrg       /* multiple of three, as expected, but there will only be the */
13604fee23f9Smrg       /* one zero before the E, still.	Otherwise note the padding. */
13614fee23f9Smrg       if (!DFISZERO(df)) pre+=adj;
13624fee23f9Smrg        else {  /* is zero */
13634fee23f9Smrg 	if (adj!=0) {		   /* 0.00Esnn needed */
13644fee23f9Smrg 	  e=e+3;
13654fee23f9Smrg 	  pre=-(2-adj);
13664fee23f9Smrg 	  }
13674fee23f9Smrg 	} /* zero */
13684fee23f9Smrg       } /* engineering adjustment */
13694fee23f9Smrg     } /* exponential form */
13704fee23f9Smrg   /* printf("e=%ld pre=%ld exp=%ld\n", (LI)e, (LI)pre, (LI)exp); */
13714fee23f9Smrg 
13724fee23f9Smrg   /* modify the coefficient, adding 0s, '.', and E+nn as needed */
13734fee23f9Smrg   if (pre>0) {			   /* ddd.ddd (plain), perhaps with E */
13744fee23f9Smrg 				   /* or dd00 padding for engineering */
13754fee23f9Smrg     char *dotat=cstart+pre;
13764fee23f9Smrg     if (dotat<c) {			/* if embedded dot needed... */
13774fee23f9Smrg       /* move by fours; there must be space for junk at the end */
13784fee23f9Smrg       /* because there is still space for exponent */
13794fee23f9Smrg       s=dotat+ROUNDDOWN4(c-dotat);	/* source */
13804fee23f9Smrg       t=s+1;				/* target */
13814fee23f9Smrg       /* open the gap [cannot use memcpy] */
13824fee23f9Smrg       for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
13834fee23f9Smrg       *dotat='.';
13844fee23f9Smrg       c++;				/* length increased by one */
13854fee23f9Smrg       } /* need dot? */
13864fee23f9Smrg      else for (; c<dotat; c++) *c='0';	/* pad for engineering */
13874fee23f9Smrg     } /* pre>0 */
13884fee23f9Smrg    else {
13894fee23f9Smrg     /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have
13904fee23f9Smrg        E, but only for 0.00E+3 kind of case -- with plenty of spare
13914fee23f9Smrg        space in this case */
13924fee23f9Smrg     pre=-pre+2; 			/* gap width, including "0." */
13934fee23f9Smrg     t=cstart+ROUNDDOWN4(c-cstart)+pre;	/* preferred first target point */
13944fee23f9Smrg     /* backoff if too far to the right */
13954fee23f9Smrg     if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
13964fee23f9Smrg     /* now shift the entire coefficient to the right, being careful not */
13974fee23f9Smrg     /* to access to the left of string [cannot use memcpy] */
13984fee23f9Smrg     for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
13994fee23f9Smrg     /* for Quads and Singles there may be a character or two left... */
14004fee23f9Smrg     s+=3;				/* where next would come from */
14014fee23f9Smrg     for(; s>=cstart; s--, t--) *(t+3)=*(s);
14024fee23f9Smrg     /* now have fill 0. through 0.00000; use overlaps to avoid tests */
14034fee23f9Smrg     if (pre>=4) {
14044fee23f9Smrg       memcpy(cstart+pre-4, "0000", 4);
14054fee23f9Smrg       memcpy(cstart, "0.00", 4);
14064fee23f9Smrg       }
14074fee23f9Smrg      else { /* 2 or 3 */
14084fee23f9Smrg       *(cstart+pre-1)='0';
14094fee23f9Smrg       memcpy(cstart, "0.", 2);
14104fee23f9Smrg       }
14114fee23f9Smrg     c+=pre;				/* to end */
14124fee23f9Smrg     }
14134fee23f9Smrg 
14144fee23f9Smrg   /* finally add the E-part, if needed; it will never be 0, and has */
14154fee23f9Smrg   /* a maximum length of 3 or 4 digits (asserted above) */
14164fee23f9Smrg   if (e!=0) {
14174fee23f9Smrg     memcpy(c, "E+", 2); 		/* starts with E, assume + */
14184fee23f9Smrg     c++;
14194fee23f9Smrg     if (e<0) {
14204fee23f9Smrg       *c='-';				/* oops, need '-' */
14214fee23f9Smrg       e=-e;				/* uInt, please */
14224fee23f9Smrg       }
14234fee23f9Smrg     c++;
14244fee23f9Smrg     /* Three-character exponents are easy; 4-character a little trickier */
14254fee23f9Smrg     #if DECEMAXD<=3
14264fee23f9Smrg       u=&BIN2BCD8[e*4]; 		/* -> 3 digits + length byte */
14274fee23f9Smrg       /* copy fixed 4 characters [is safe], starting at non-zero */
14284fee23f9Smrg       /* and with character mask to convert BCD to char */
14294fee23f9Smrg       UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
14304fee23f9Smrg       c+=*(u+3);			/* bump pointer appropriately */
14314fee23f9Smrg     #elif DECEMAXD==4
14324fee23f9Smrg       if (e<1000) {			/* 3 (or fewer) digits case */
14334fee23f9Smrg 	u=&BIN2BCD8[e*4];		/* -> 3 digits + length byte */
14344fee23f9Smrg 	UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
14354fee23f9Smrg 	c+=*(u+3);			/* bump pointer appropriately */
14364fee23f9Smrg 	}
14374fee23f9Smrg        else {				/* 4-digits */
14384fee23f9Smrg 	Int thou=((e>>3)*1049)>>17;	/* e/1000 */
14394fee23f9Smrg 	Int rem=e-(1000*thou);		/* e%1000 */
14404fee23f9Smrg 	*c++=(char)('0'+(char)thou);	/* the thousands digit */
14414fee23f9Smrg 	u=&BIN2BCD8[rem*4];		/* -> 3 digits + length byte */
14424fee23f9Smrg 	UBFROMUI(c, UBTOUI(u)|CHARMASK);/* copy fixed 3+1 characters [is safe] */
14434fee23f9Smrg 	c+=3;				/* bump pointer, always 3 digits */
14444fee23f9Smrg 	}
14454fee23f9Smrg     #endif
14464fee23f9Smrg     }
14474fee23f9Smrg   *c='\0';				/* terminate */
14484fee23f9Smrg   /*printf("res %s\n", string); */
14494fee23f9Smrg   return string;
14504fee23f9Smrg   } /* decFloatToEngString */
14514fee23f9Smrg 
14524fee23f9Smrg /* ------------------------------------------------------------------ */
14534fee23f9Smrg /* decFloatToPacked -- convert decFloat to Packed decimal + exponent  */
14544fee23f9Smrg /*								      */
14554fee23f9Smrg /*  df is the source decFloat					      */
14564fee23f9Smrg /*  exp will be set to the unbiased exponent, q, or to a special      */
14574fee23f9Smrg /*    value in the form returned by decFloatGetExponent 	      */
14584fee23f9Smrg /*  packed is where DECPMAX nibbles will be written with the sign as  */
14594fee23f9Smrg /*    final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */
14604fee23f9Smrg /*    of zero, and an infinity is all zeros. decDouble and decQuad    */
14614fee23f9Smrg /*    have a additional leading zero nibble, leading to result	      */
14624fee23f9Smrg /*    lengths of 4, 9, and 18 bytes.				      */
14634fee23f9Smrg /*  returns the sign of the coefficient (DECFLOAT_Sign if negative,   */
14644fee23f9Smrg /*    0 otherwise)						      */
14654fee23f9Smrg /*								      */
14664fee23f9Smrg /* No error is possible, and no status will be set.		      */
14674fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatToPacked(const decFloat * df,Int * exp,uByte * packed)14684fee23f9Smrg Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) {
14694fee23f9Smrg   uByte bcdar[DECPMAX+2];	   /* work buffer */
14704fee23f9Smrg   uByte *ip=bcdar, *op=packed;	   /* work pointers */
14714fee23f9Smrg   if (DFISINF(df)) {
14724fee23f9Smrg     memset(bcdar, 0, DECPMAX+2);
14734fee23f9Smrg     *exp=DECFLOAT_Inf;
14744fee23f9Smrg     }
14754fee23f9Smrg    else {
14764fee23f9Smrg     GETCOEFF(df, bcdar+1);	   /* use macro */
14774fee23f9Smrg     if (DFISNAN(df)) {
14784fee23f9Smrg       bcdar[1]=0;		   /* MSD needs clearing */
14794fee23f9Smrg       *exp=DFWORD(df, 0)&0x7e000000;
14804fee23f9Smrg       }
14814fee23f9Smrg      else {			   /* finite */
14824fee23f9Smrg       *exp=GETEXPUN(df);
14834fee23f9Smrg       }
14844fee23f9Smrg     }
14854fee23f9Smrg   /* now pack; coefficient currently at bcdar+1 */
14864fee23f9Smrg   #if SINGLE
14874fee23f9Smrg     ip++;			   /* ignore first byte */
14884fee23f9Smrg   #else
14894fee23f9Smrg     *ip=0;			   /* need leading zero */
14904fee23f9Smrg   #endif
14914fee23f9Smrg   /* set final byte to Packed BCD sign value */
14924fee23f9Smrg   bcdar[DECPMAX+1]=(DFISSIGNED(df) ? DECPMINUS : DECPPLUS);
14934fee23f9Smrg   /* pack an even number of bytes... */
14944fee23f9Smrg   for (; op<packed+((DECPMAX+2)/2); op++, ip+=2) {
14954fee23f9Smrg     *op=(uByte)((*ip<<4)+*(ip+1));
14964fee23f9Smrg     }
14974fee23f9Smrg   return (bcdar[DECPMAX+1]==DECPMINUS ? DECFLOAT_Sign : 0);
14984fee23f9Smrg   } /* decFloatToPacked */
14994fee23f9Smrg 
15004fee23f9Smrg /* ------------------------------------------------------------------ */
15014fee23f9Smrg /* decFloatToString -- conversion to numeric string		      */
15024fee23f9Smrg /*								      */
15034fee23f9Smrg /*  df is the decFloat format number to convert 		      */
15044fee23f9Smrg /*  string is the string where the result will be laid out	      */
15054fee23f9Smrg /*								      */
15064fee23f9Smrg /* string must be at least DECPMAX+9 characters (the worst case is    */
15074fee23f9Smrg /* "-0.00000nnn...nnn\0", which is as long as the exponent form when  */
15084fee23f9Smrg /* DECEMAXD<=4); this condition is asserted above		      */
15094fee23f9Smrg /*								      */
15104fee23f9Smrg /* No error is possible, and no status will be set		      */
15114fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatToString(const decFloat * df,char * string)15124fee23f9Smrg char * decFloatToString(const decFloat *df, char *string){
15134fee23f9Smrg   uInt msd;			   /* coefficient MSD */
15144fee23f9Smrg   Int  exp;			   /* exponent top two bits or full */
15154fee23f9Smrg   uInt comb;			   /* combination field */
15164fee23f9Smrg   char *cstart; 		   /* coefficient start */
15174fee23f9Smrg   char *c;			   /* output pointer in string */
15184fee23f9Smrg   char *s, *t;			   /* .. (source, target) */
15194fee23f9Smrg   Int  pre, e;			   /* work */
15204fee23f9Smrg   const uByte *u;		   /* .. */
15214fee23f9Smrg   uInt	uiwork; 		   /* for macros [one compiler needs */
15224fee23f9Smrg 				   /* volatile here to avoid bug, but */
15234fee23f9Smrg 				   /* that doubles execution time] */
15244fee23f9Smrg 
15254fee23f9Smrg   /* Source words; macro handles endianness */
15264fee23f9Smrg   uInt sourhi=DFWORD(df, 0);	   /* word with sign */
15274fee23f9Smrg   #if DECPMAX==16
15284fee23f9Smrg   uInt sourlo=DFWORD(df, 1);
15294fee23f9Smrg   #elif DECPMAX==34
15304fee23f9Smrg   uInt sourmh=DFWORD(df, 1);
15314fee23f9Smrg   uInt sourml=DFWORD(df, 2);
15324fee23f9Smrg   uInt sourlo=DFWORD(df, 3);
15334fee23f9Smrg   #endif
15344fee23f9Smrg 
15354fee23f9Smrg   c=string;			   /* where result will go */
15364fee23f9Smrg   if (((Int)sourhi)<0) *c++='-';   /* handle sign */
15374fee23f9Smrg   comb=sourhi>>26;		   /* sign+combination field */
15384fee23f9Smrg   msd=DECCOMBMSD[comb]; 	   /* decode the combination field */
15394fee23f9Smrg   exp=DECCOMBEXP[comb]; 	   /* .. */
15404fee23f9Smrg 
15414fee23f9Smrg   if (!EXPISSPECIAL(exp)) {	   /* finite */
15424fee23f9Smrg     /* complete exponent; top two bits are in place */
15434fee23f9Smrg     exp+=GETECON(df)-DECBIAS;	   /* .. + continuation and unbias */
15444fee23f9Smrg     }
15454fee23f9Smrg    else {			   /* IS special */
15464fee23f9Smrg     if (exp==DECFLOAT_Inf) {	   /* infinity */
15474fee23f9Smrg       strcpy(c, "Infinity");
15484fee23f9Smrg       return string;		   /* easy */
15494fee23f9Smrg       }
15504fee23f9Smrg     if (sourhi&0x02000000) *c++='s'; /* sNaN */
15514fee23f9Smrg     strcpy(c, "NaN");		   /* complete word */
15524fee23f9Smrg     c+=3;			   /* step past */
15534fee23f9Smrg     /* quick exit if the payload is zero */
15544fee23f9Smrg     #if DECPMAX==7
15554fee23f9Smrg     if ((sourhi&0x000fffff)==0) return string;
15564fee23f9Smrg     #elif DECPMAX==16
15574fee23f9Smrg     if (sourlo==0 && (sourhi&0x0003ffff)==0) return string;
15584fee23f9Smrg     #elif DECPMAX==34
15594fee23f9Smrg     if (sourlo==0 && sourml==0 && sourmh==0
15604fee23f9Smrg      && (sourhi&0x00003fff)==0) return string;
15614fee23f9Smrg     #endif
15624fee23f9Smrg     /* otherwise drop through to add integer; set correct exp etc. */
15634fee23f9Smrg     exp=0; msd=0;		   /* setup for following code */
15644fee23f9Smrg     }
15654fee23f9Smrg 
15664fee23f9Smrg   /* convert the digits of the significand to characters */
15674fee23f9Smrg   cstart=c;			   /* save start of coefficient */
15684fee23f9Smrg   if (msd) *c++=(char)('0'+(char)msd);	/* non-zero most significant digit */
15694fee23f9Smrg 
15704fee23f9Smrg   /* Decode the declets.  After extracting each declet, it is */
15714fee23f9Smrg   /* decoded to a 4-uByte sequence by table lookup; the four uBytes */
15724fee23f9Smrg   /* are the three encoded BCD8 digits followed by a 1-byte length */
15734fee23f9Smrg   /* (significant digits, except that 000 has length 0).  This allows */
15744fee23f9Smrg   /* us to left-align the first declet with non-zero content, then */
15754fee23f9Smrg   /* the remaining ones are full 3-char length.  Fixed-length copies */
15764fee23f9Smrg   /* are used because variable-length memcpy causes a subroutine call */
15774fee23f9Smrg   /* in at least two compilers.  (The copies are length 4 for speed */
15784fee23f9Smrg   /* and are safe because the last item in the array is of length */
15794fee23f9Smrg   /* three and has the length byte following.) */
15804fee23f9Smrg   #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4];	 \
15814fee23f9Smrg 	 if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
15824fee23f9Smrg 	  else if (*(u+3)) {					 \
15834fee23f9Smrg 	   UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
15844fee23f9Smrg 
15854fee23f9Smrg   #if DECPMAX==7
15864fee23f9Smrg   dpd2char(sourhi>>10); 		/* declet 1 */
15874fee23f9Smrg   dpd2char(sourhi);			/* declet 2 */
15884fee23f9Smrg 
15894fee23f9Smrg   #elif DECPMAX==16
15904fee23f9Smrg   dpd2char(sourhi>>8);			/* declet 1 */
15914fee23f9Smrg   dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
15924fee23f9Smrg   dpd2char(sourlo>>20); 		/* declet 3 */
15934fee23f9Smrg   dpd2char(sourlo>>10); 		/* declet 4 */
15944fee23f9Smrg   dpd2char(sourlo);			/* declet 5 */
15954fee23f9Smrg 
15964fee23f9Smrg   #elif DECPMAX==34
15974fee23f9Smrg   dpd2char(sourhi>>4);			/* declet 1 */
15984fee23f9Smrg   dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
15994fee23f9Smrg   dpd2char(sourmh>>16); 		/* declet 3 */
16004fee23f9Smrg   dpd2char(sourmh>>6);			/* declet 4 */
16014fee23f9Smrg   dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
16024fee23f9Smrg   dpd2char(sourml>>18); 		/* declet 6 */
16034fee23f9Smrg   dpd2char(sourml>>8);			/* declet 7 */
16044fee23f9Smrg   dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
16054fee23f9Smrg   dpd2char(sourlo>>20); 		/* declet 9 */
16064fee23f9Smrg   dpd2char(sourlo>>10); 		/* declet 10 */
16074fee23f9Smrg   dpd2char(sourlo);			/* declet 11 */
16084fee23f9Smrg   #endif
16094fee23f9Smrg 
16104fee23f9Smrg   if (c==cstart) *c++='0';	   /* all zeros, empty -- make "0" */
16114fee23f9Smrg 
16124fee23f9Smrg   /*[This fast path is valid but adds 3-5 cycles to worst case length] */
16134fee23f9Smrg   /*if (exp==0) {		   // integer or NaN case -- easy */
16144fee23f9Smrg   /*  *c='\0';			   // terminate */
16154fee23f9Smrg   /*  return string; */
16164fee23f9Smrg   /*  } */
16174fee23f9Smrg 
16184fee23f9Smrg   e=0;				   /* assume no E */
16194fee23f9Smrg   pre=(Int)(c-cstart)+exp;	   /* length+exp  [c->LSD+1] */
16204fee23f9Smrg   /* [here, pre-exp is the digits count (==1 for zero)] */
16214fee23f9Smrg 
16224fee23f9Smrg   if (exp>0 || pre<-5) {	   /* need exponential form */
16234fee23f9Smrg     e=pre-1;			   /* calculate E value */
16244fee23f9Smrg     pre=1;			   /* assume one digit before '.' */
16254fee23f9Smrg     } /* exponential form */
16264fee23f9Smrg 
16274fee23f9Smrg   /* modify the coefficient, adding 0s, '.', and E+nn as needed */
16284fee23f9Smrg   if (pre>0) {			   /* ddd.ddd (plain), perhaps with E */
16294fee23f9Smrg     char *dotat=cstart+pre;
16304fee23f9Smrg     if (dotat<c) {			/* if embedded dot needed... */
16314fee23f9Smrg       /* [memmove is a disaster, here] */
16324fee23f9Smrg       /* move by fours; there must be space for junk at the end */
16334fee23f9Smrg       /* because exponent is still possible */
16344fee23f9Smrg       s=dotat+ROUNDDOWN4(c-dotat);	/* source */
16354fee23f9Smrg       t=s+1;				/* target */
16364fee23f9Smrg       /* open the gap [cannot use memcpy] */
16374fee23f9Smrg       for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
16384fee23f9Smrg       *dotat='.';
16394fee23f9Smrg       c++;				/* length increased by one */
16404fee23f9Smrg       } /* need dot? */
16414fee23f9Smrg 
16424fee23f9Smrg     /* finally add the E-part, if needed; it will never be 0, and has */
16434fee23f9Smrg     /* a maximum length of 3 or 4 digits (asserted above) */
16444fee23f9Smrg     if (e!=0) {
16454fee23f9Smrg       memcpy(c, "E+", 2);		/* starts with E, assume + */
16464fee23f9Smrg       c++;
16474fee23f9Smrg       if (e<0) {
16484fee23f9Smrg 	*c='-'; 			/* oops, need '-' */
16494fee23f9Smrg 	e=-e;				/* uInt, please */
16504fee23f9Smrg 	}
16514fee23f9Smrg       c++;
16524fee23f9Smrg       /* Three-character exponents are easy; 4-character a little trickier */
16534fee23f9Smrg       #if DECEMAXD<=3
16544fee23f9Smrg 	u=&BIN2BCD8[e*4];		/* -> 3 digits + length byte */
16554fee23f9Smrg 	/* copy fixed 4 characters [is safe], starting at non-zero */
16564fee23f9Smrg 	/* and with character mask to convert BCD to char */
16574fee23f9Smrg 	UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
16584fee23f9Smrg 	c+=*(u+3);			/* bump pointer appropriately */
16594fee23f9Smrg       #elif DECEMAXD==4
16604fee23f9Smrg 	if (e<1000) {			/* 3 (or fewer) digits case */
16614fee23f9Smrg 	  u=&BIN2BCD8[e*4];		/* -> 3 digits + length byte */
16624fee23f9Smrg 	  UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
16634fee23f9Smrg 	  c+=*(u+3);			/* bump pointer appropriately */
16644fee23f9Smrg 	  }
16654fee23f9Smrg 	 else { 			/* 4-digits */
16664fee23f9Smrg 	  Int thou=((e>>3)*1049)>>17;	/* e/1000 */
16674fee23f9Smrg 	  Int rem=e-(1000*thou);	/* e%1000 */
16684fee23f9Smrg 	  *c++=(char)('0'+(char)thou);	/* the thousands digit */
16694fee23f9Smrg 	  u=&BIN2BCD8[rem*4];		/* -> 3 digits + length byte */
16704fee23f9Smrg 	  UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
16714fee23f9Smrg 	  c+=3; 			/* bump pointer, always 3 digits */
16724fee23f9Smrg 	  }
16734fee23f9Smrg       #endif
16744fee23f9Smrg       }
16754fee23f9Smrg     *c='\0';				/* add terminator */
16764fee23f9Smrg     /*printf("res %s\n", string); */
16774fee23f9Smrg     return string;
16784fee23f9Smrg     } /* pre>0 */
16794fee23f9Smrg 
16804fee23f9Smrg   /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
16814fee23f9Smrg   /* Surprisingly, this is close to being the worst-case path, so the */
16824fee23f9Smrg   /* shift is done by fours; this is a little tricky because the */
16834fee23f9Smrg   /* rightmost character to be written must not be beyond where the */
16844fee23f9Smrg   /* rightmost terminator could be -- so backoff to not touch */
16854fee23f9Smrg   /* terminator position if need be (this can make exact alignments */
16864fee23f9Smrg   /* for full Doubles, but in some cases needs care not to access too */
16874fee23f9Smrg   /* far to the left) */
16884fee23f9Smrg 
16894fee23f9Smrg   pre=-pre+2;				/* gap width, including "0." */
16904fee23f9Smrg   t=cstart+ROUNDDOWN4(c-cstart)+pre;	/* preferred first target point */
16914fee23f9Smrg   /* backoff if too far to the right */
16924fee23f9Smrg   if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
16934fee23f9Smrg   /* now shift the entire coefficient to the right, being careful not */
16944fee23f9Smrg   /* to access to the left of string [cannot use memcpy] */
16954fee23f9Smrg   for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
16964fee23f9Smrg   /* for Quads and Singles there may be a character or two left... */
16974fee23f9Smrg   s+=3; 				/* where next would come from */
16984fee23f9Smrg   for(; s>=cstart; s--, t--) *(t+3)=*(s);
16994fee23f9Smrg   /* now have fill 0. through 0.00000; use overlaps to avoid tests */
17004fee23f9Smrg   if (pre>=4) {
17014fee23f9Smrg     memcpy(cstart+pre-4, "0000", 4);
17024fee23f9Smrg     memcpy(cstart, "0.00", 4);
17034fee23f9Smrg     }
17044fee23f9Smrg    else { /* 2 or 3 */
17054fee23f9Smrg     *(cstart+pre-1)='0';
17064fee23f9Smrg     memcpy(cstart, "0.", 2);
17074fee23f9Smrg     }
17084fee23f9Smrg   *(c+pre)='\0';			/* terminate */
17094fee23f9Smrg   return string;
17104fee23f9Smrg   } /* decFloatToString */
17114fee23f9Smrg 
17124fee23f9Smrg /* ------------------------------------------------------------------ */
17134fee23f9Smrg /* decFloatToWider -- conversion to next-wider format		      */
17144fee23f9Smrg /*								      */
17154fee23f9Smrg /*  source  is the decFloat format number which gets the result of    */
17164fee23f9Smrg /*	    the conversion					      */
17174fee23f9Smrg /*  wider   is the decFloatWider format number which will be narrowed */
17184fee23f9Smrg /*  returns wider						      */
17194fee23f9Smrg /*								      */
17204fee23f9Smrg /* Widening is always exact; no status is set (sNaNs are copied and   */
17214fee23f9Smrg /* do not signal).  The result will be canonical if the source is,    */
17224fee23f9Smrg /* and may or may not be if the source is not.			      */
17234fee23f9Smrg /* ------------------------------------------------------------------ */
17244fee23f9Smrg /* widening is not possible for decQuad format numbers; simply omit */
17254fee23f9Smrg #if !QUAD
decFloatToWider(const decFloat * source,decFloatWider * wider)17264fee23f9Smrg decFloatWider * decFloatToWider(const decFloat *source, decFloatWider *wider) {
17274fee23f9Smrg   uInt msd;
17284fee23f9Smrg 
17294fee23f9Smrg   /* Construct and copy the sign word */
17304fee23f9Smrg   if (DFISSPECIAL(source)) {
17314fee23f9Smrg     /* copy sign, combination, and first bit of exponent (sNaN selector) */
17324fee23f9Smrg     DFWWORD(wider, 0)=DFWORD(source, 0)&0xfe000000;
17334fee23f9Smrg     msd=0;
17344fee23f9Smrg     }
17354fee23f9Smrg    else { /* is finite number */
17364fee23f9Smrg     uInt exp=GETEXPUN(source)+DECWBIAS; /* get unbiased exponent and rebias */
17374fee23f9Smrg     uInt code=(exp>>DECWECONL)<<29;	/* set two bits of exp [msd=0] */
17384fee23f9Smrg     code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */
17394fee23f9Smrg     code|=DFWORD(source, 0)&0x80000000; /* add sign */
17404fee23f9Smrg     DFWWORD(wider, 0)=code;		/* .. and place top word in wider */
17414fee23f9Smrg     msd=GETMSD(source); 		/* get source coefficient MSD [0-9] */
17424fee23f9Smrg     }
17434fee23f9Smrg   /* Copy the coefficient and clear any 'unused' words to left */
17444fee23f9Smrg   #if SINGLE
17454fee23f9Smrg     DFWWORD(wider, 1)=(DFWORD(source, 0)&0x000fffff)|(msd<<20);
17464fee23f9Smrg   #elif DOUBLE
17474fee23f9Smrg     DFWWORD(wider, 2)=(DFWORD(source, 0)&0x0003ffff)|(msd<<18);
17484fee23f9Smrg     DFWWORD(wider, 3)=DFWORD(source, 1);
17494fee23f9Smrg     DFWWORD(wider, 1)=0;
17504fee23f9Smrg   #endif
17514fee23f9Smrg   return wider;
17524fee23f9Smrg   } /* decFloatToWider */
17534fee23f9Smrg #endif
17544fee23f9Smrg 
17554fee23f9Smrg /* ------------------------------------------------------------------ */
17564fee23f9Smrg /* decFloatVersion -- return package version string		      */
17574fee23f9Smrg /*								      */
17584fee23f9Smrg /*  returns a constant string describing this package		      */
17594fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatVersion(void)17604fee23f9Smrg const char *decFloatVersion(void) {
17614fee23f9Smrg   return DECVERSION;
17624fee23f9Smrg   } /* decFloatVersion */
17634fee23f9Smrg 
17644fee23f9Smrg /* ------------------------------------------------------------------ */
17654fee23f9Smrg /* decFloatZero -- set to canonical (integer) zero		      */
17664fee23f9Smrg /*								      */
17674fee23f9Smrg /*  df is the decFloat format number to integer +0 (q=0, c=+0)	      */
17684fee23f9Smrg /*  returns df							      */
17694fee23f9Smrg /*								      */
17704fee23f9Smrg /* No error is possible, and no status can be set.		      */
17714fee23f9Smrg /* ------------------------------------------------------------------ */
decFloatZero(decFloat * df)17724fee23f9Smrg decFloat * decFloatZero(decFloat *df){
17734fee23f9Smrg   DFWORD(df, 0)=ZEROWORD;     /* set appropriate top word */
17744fee23f9Smrg   #if DOUBLE || QUAD
17754fee23f9Smrg     DFWORD(df, 1)=0;
17764fee23f9Smrg     #if QUAD
17774fee23f9Smrg       DFWORD(df, 2)=0;
17784fee23f9Smrg       DFWORD(df, 3)=0;
17794fee23f9Smrg     #endif
17804fee23f9Smrg   #endif
17814fee23f9Smrg   /* decFloatShow(df, "zero"); */
17824fee23f9Smrg   return df;
17834fee23f9Smrg   } /* decFloatZero */
17844fee23f9Smrg 
17854fee23f9Smrg /* ------------------------------------------------------------------ */
17864fee23f9Smrg /* Private generic function (not format-specific) for development use */
17874fee23f9Smrg /* ------------------------------------------------------------------ */
17884fee23f9Smrg /* This is included once only, for all to use */
17894fee23f9Smrg #if QUAD && (DECCHECK || DECTRACE)
17904fee23f9Smrg   /* ---------------------------------------------------------------- */
17914fee23f9Smrg   /* decShowNum -- display bcd8 number in debug form		      */
17924fee23f9Smrg   /*								      */
17934fee23f9Smrg   /*   num is the bcdnum to display				      */
17944fee23f9Smrg   /*   tag is a string to label the display			      */
17954fee23f9Smrg   /* ---------------------------------------------------------------- */
decShowNum(const bcdnum * num,const char * tag)17964fee23f9Smrg   void decShowNum(const bcdnum *num, const char *tag) {
17974fee23f9Smrg     const char *csign="+";		/* sign character */
17984fee23f9Smrg     uByte *ub;				/* work */
17994fee23f9Smrg     uInt  uiwork;			/* for macros */
18004fee23f9Smrg     if (num->sign==DECFLOAT_Sign) csign="-";
18014fee23f9Smrg 
18024fee23f9Smrg     printf(">%s> ", tag);
18034fee23f9Smrg     if (num->exponent==DECFLOAT_Inf) printf("%sInfinity", csign);
18044fee23f9Smrg     else if (num->exponent==DECFLOAT_qNaN) printf("%sqNaN", csign);
18054fee23f9Smrg     else if (num->exponent==DECFLOAT_sNaN) printf("%ssNaN", csign);
18064fee23f9Smrg     else {				/* finite */
18074fee23f9Smrg      char qbuf[10];			/* for right-aligned q */
18084fee23f9Smrg      char *c;				/* work */
18094fee23f9Smrg      const uByte *u;			/* .. */
18104fee23f9Smrg      Int e=num->exponent;		/* .. exponent */
18114fee23f9Smrg      strcpy(qbuf, "q=");
18124fee23f9Smrg      c=&qbuf[2];			/* where exponent will go */
18134fee23f9Smrg      /* lay out the exponent */
18144fee23f9Smrg      if (e<0) {
18154fee23f9Smrg        *c++='-';			/* add '-' */
18164fee23f9Smrg        e=-e;				/* uInt, please */
18174fee23f9Smrg        }
18184fee23f9Smrg      #if DECEMAXD>4
18194fee23f9Smrg        #error Exponent form is too long for ShowNum to lay out
18204fee23f9Smrg      #endif
18214fee23f9Smrg      if (e==0) *c++='0';		/* 0-length case */
18224fee23f9Smrg       else if (e<1000) {		/* 3 (or fewer) digits case */
18234fee23f9Smrg        u=&BIN2BCD8[e*4];		/* -> 3 digits + length byte */
18244fee23f9Smrg        UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
18254fee23f9Smrg        c+=*(u+3);			/* bump pointer appropriately */
18264fee23f9Smrg        }
18274fee23f9Smrg       else {				/* 4-digits */
18284fee23f9Smrg        Int thou=((e>>3)*1049)>>17;	/* e/1000 */
18294fee23f9Smrg        Int rem=e-(1000*thou);		/* e%1000 */
18304fee23f9Smrg        *c++=(char)('0'+(char)thou);	/* the thousands digit */
18314fee23f9Smrg        u=&BIN2BCD8[rem*4];		/* -> 3 digits + length byte */
18324fee23f9Smrg        UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
18334fee23f9Smrg        c+=3;				/* bump pointer, always 3 digits */
18344fee23f9Smrg        }
18354fee23f9Smrg      *c='\0';				/* add terminator */
18364fee23f9Smrg      printf("%7s c=%s", qbuf, csign);
18374fee23f9Smrg      }
18384fee23f9Smrg 
18394fee23f9Smrg     if (!EXPISSPECIAL(num->exponent) || num->msd!=num->lsd || *num->lsd!=0) {
18404fee23f9Smrg       for (ub=num->msd; ub<=num->lsd; ub++) { /* coefficient... */
18414fee23f9Smrg 	printf("%1x", *ub);
18424fee23f9Smrg 	if ((num->lsd-ub)%3==0 && ub!=num->lsd) printf(" "); /* 4-space */
18434fee23f9Smrg 	}
18444fee23f9Smrg       }
18454fee23f9Smrg     printf("\n");
18464fee23f9Smrg     } /* decShowNum */
18474fee23f9Smrg #endif
1848