14bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes/****************************************************************
24bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
34bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesThe author of this software is David M. Gay.
44bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
54bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesCopyright (C) 1998, 1999 by Lucent Technologies
64bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesAll Rights Reserved
74bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
84bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesPermission to use, copy, modify, and distribute this software and
94bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesits documentation for any purpose and without fee is hereby
104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesgranted, provided that the above copyright notice appear in all
114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughescopies and that both that the copyright notice and this
124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughespermission notice and warranty disclaimer appear in supporting
134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesdocumentation, and that the name of Lucent or any of its entities
144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesnot be used in advertising or publicity pertaining to
154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesdistribution of the software without specific, written prior
164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughespermission.
174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott HughesTHIS SOFTWARE.
264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes****************************************************************/
284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes/* Please send bug reports to David M. Gay (dmg at acm dot org,
304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * with " at " changed at "@" and " dot " changed to ".").	*/
314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#include "gdtoaimp.h"
334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *
364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * Inspired by "How to Print Floating-Point Numbers Accurately" by
374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *
394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes * Modifications:
404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	1. Rather than iterating, we use a simple numeric overestimate
414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   to determine k = floor(log10(d)).  We scale relevant
424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   quantities using O(log2(k)) rather than O(k) multiplications.
434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   try to generate digits strictly left to right.  Instead, we
454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   compute with fewer bits and propagate the carry if necessary
464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   when rounding the final digit up.  This is often faster.
474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	3. Under the assumption that input will be rounded nearest,
484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   That is, we allow equality in stopping tests when the
504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   round-nearest rule will give the same floating-point value
514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   as would satisfaction of the stopping test with strict
524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   inequality.
534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	4. We remove common factors of powers of 2 from relevant
544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   quantities.
554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	5. When converting floating-point integers less than 1e16,
564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   we use floating-point arithmetic rather than resorting
574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   to multiple-precision integers.
584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	6. When asked to produce fewer than 15 digits, we first try
594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   to get by with floating-point arithmetic; we resort to
604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   multiple-precision integer arithmetic only if we cannot
614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   guarantee that the floating-point calculation has given
624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   the correctly rounded result.  For k requested digits and
634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   "uniformly" distributed input, the probability is
644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   something like 10^(k-15) that we must resort to the Long
654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes *	   calculation.
664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes */
674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#undef Check_FLT_ROUNDS
704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#define Check_FLT_ROUNDS
714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#define Rounding Flt_Rounds
734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes char *
764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughesdtoa
774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef KR_headers
784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	(d0, mode, ndigits, decpt, sign, rve)
794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	double d0; int mode, ndigits, *decpt, *sign; char **rve;
804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes{
844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes /*	Arguments ndigits, decpt, sign are similar to those
854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	of ecvt and fcvt; trailing zeros are suppressed from
864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	the returned string.  If not null, *rve is set to point
874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	to the end of the return value.  If d is +-Infinity or NaN,
884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	then *decpt is set to 9999.
894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	mode:
914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		0 ==> shortest string that yields d when read in
924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			and rounded to nearest.
934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		1 ==> like 0, but with Steele & White stopping rule;
944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			e.g. with IEEE P754 arithmetic , mode 0 gives
954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			1e23 whereas mode 1 gives 9.999999999999999e22.
964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		2 ==> max(1,ndigits) significant digits.  This gives a
974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			return value similar to that of ecvt, except
984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			that trailing zeros are suppressed.
994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		3 ==> through ndigits past the decimal point.  This
1004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			gives a return value similar to that from fcvt,
1014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			except that trailing zeros are suppressed, and
1024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ndigits can be negative.
1034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		4,5 ==> similar to 2 and 3, respectively, but (in
1044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			round-nearest mode) with the tests of mode 0 to
1054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			possibly return a shorter string that rounds to d.
1064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			With IEEE arithmetic and compilation with
1074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
1084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			as modes 2 and 3 when FLT_ROUNDS != 1.
1094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		6-9 ==> Debugging modes similar to mode - 4:  don't try
1104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			fast floating-point estimate (if applicable).
1114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
1124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		Values of mode other than 0-9 are treated as mode 0.
1134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
1144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		Sufficient space is allocated to the return value
1154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		to hold the suppressed trailing zeros.
1164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	*/
1174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
1184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
1194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
1204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		spec_case, try_quick;
1214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	Long L;
1224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef Sudden_Underflow
1234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	int denorm;
1244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	ULong x;
1254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	U d, d2, eps;
1284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	double ds;
1294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	char *s, *s0;
1304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT
1314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	int inexact, oldinexact;
1324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS /*{*/
1344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	int Rounding;
1354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
1364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	Rounding = Flt_Rounds;
1374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else /*}{*/
1384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	Rounding = 1;
1394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	switch(fegetround()) {
1404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	  case FE_TOWARDZERO:	Rounding = 0; break;
1414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	  case FE_UPWARD:	Rounding = 2; break;
1424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	  case FE_DOWNWARD:	Rounding = 3;
1434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	  }
1444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif /*}}*/
1454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif /*}*/
1464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
1474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef MULTIPLE_THREADS
1484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (dtoa_result) {
1494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		freedtoa(dtoa_result);
1504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		dtoa_result = 0;
1514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
1524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	d.d = d0;
1544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (word0(&d) & Sign_bit) {
1554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		/* set sign for everything, including 0's and NaNs */
1564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		*sign = 1;
1574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		word0(&d) &= ~Sign_bit;	/* clear sign bit */
1584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
1594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	else
1604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		*sign = 0;
1614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
1624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#if defined(IEEE_Arith) + defined(VAX)
1634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IEEE_Arith
1644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if ((word0(&d) & Exp_mask) == Exp_mask)
1654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
1664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (word0(&d)  == 0x8000)
1674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		{
1694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		/* Infinity or NaN */
1704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		*decpt = 9999;
1714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IEEE_Arith
1724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (!word1(&d) && !(word0(&d) & 0xfffff))
1734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			return nrv_alloc("Infinity", rve, 8);
1744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		return nrv_alloc("NaN", rve, 3);
1764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
1774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IBM
1794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	dval(&d) += 0; /* normalize */
1804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (!dval(&d)) {
1824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		*decpt = 1;
1834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		return nrv_alloc("0", rve, 1);
1844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
1854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
1864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT
1874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	try_quick = oldinexact = get_inexact();
1884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	inexact = 1;
1894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
1914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (Rounding >= 2) {
1924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (*sign)
1934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			Rounding = Rounding == 2 ? 0 : 2;
1944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		else
1954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (Rounding != 2)
1964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				Rounding = 0;
1974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
1984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
1994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
2004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	b = d2b(dval(&d), &be, &bbits);
2014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (b == NULL)
2024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		return (NULL);
2034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Sudden_Underflow
2044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
2054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
2064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {
2074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
2084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		dval(&d2) = dval(&d);
2094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		word0(&d2) &= Frac_mask1;
2104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		word0(&d2) |= Exp_11;
2114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IBM
2124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0)
2134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&d2) /= 1 << j;
2144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
2154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
2164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		/* log(x)	~=~ log(1.5) + (x-1.5)/1.5
2174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * log10(x)	 =  log(x) / log(10)
2184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
2194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2)
2204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 *
2214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * This suggests computing an approximation k to log10(&d) by
2224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 *
2234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * k = (i - Bias)*0.301029995663981
2244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
2254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 *
2264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * We want k to be too large rather than too small.
2274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * The error in the first-order Taylor series approximation
2284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * is in our favor, so we just round up the constant enough
2294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * to compensate for any error in the multiplication of
2304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
2314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
2324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * adding 1e-13 to the constant term more than suffices.
2334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * Hence we adjust the constant term to 0.1760912590558.
2344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * (We could get a more accurate k by invoking log10,
2354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 *  but this is probably not worthwhile.)
2364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 */
2374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
2384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i -= Bias;
2394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IBM
2404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i <<= 2;
2414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i += j;
2424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
2434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef Sudden_Underflow
2444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		denorm = 0;
2454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
2464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	else {
2474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		/* d is denormalized */
2484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
2494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i = bbits + be + (Bias + (P-1) - 1);
2504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		x = i > 32  ? word0(&d) << (64 - i) | word1(&d) >> (i - 32)
2514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			    : word1(&d) << (32 - i);
2524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		dval(&d2) = x;
2534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
2544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i -= (Bias + (P-1) - 1) + 1;
2554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		denorm = 1;
2564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
2574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
2584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
2594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	k = (int)ds;
2604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (ds < 0. && ds != k)
2614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		k--;	/* want k = floor(ds) */
2624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	k_check = 1;
2634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (k >= 0 && k <= Ten_pmax) {
2644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (dval(&d) < tens[k])
2654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			k--;
2664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		k_check = 0;
2674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
2684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	j = bbits - i - 1;
2694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (j >= 0) {
2704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b2 = 0;
2714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s2 = j;
2724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
2734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	else {
2744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b2 = -j;
2754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s2 = 0;
2764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
2774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (k >= 0) {
2784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b5 = 0;
2794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s5 = k;
2804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s2 += k;
2814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
2824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	else {
2834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b2 -= k;
2844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b5 = -k;
2854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s5 = 0;
2864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
2874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (mode < 0 || mode > 9)
2884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		mode = 0;
2894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
2904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef SET_INEXACT
2914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Check_FLT_ROUNDS
2924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	try_quick = Rounding == 1;
2934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
2944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	try_quick = 1;
2954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
2964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif /*SET_INEXACT*/
2974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
2984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (mode > 5) {
2994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		mode -= 4;
3004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		try_quick = 0;
3014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
3024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	leftright = 1;
3034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	ilim = ilim1 = -1;	/* Values for cases 0 and 1; done here to */
3044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				/* silence erroneous "gcc -Wall" warning. */
3054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	switch(mode) {
3064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		case 0:
3074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		case 1:
3084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			i = 18;
3094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ndigits = 0;
3104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			break;
3114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		case 2:
3124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			leftright = 0;
3134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			/* no break */
3144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		case 4:
3154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (ndigits <= 0)
3164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				ndigits = 1;
3174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ilim = ilim1 = i = ndigits;
3184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			break;
3194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		case 3:
3204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			leftright = 0;
3214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			/* no break */
3224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		case 5:
3234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			i = ndigits + k + 1;
3244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ilim = i;
3254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ilim1 = i - 1;
3264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (i <= 0)
3274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				i = 1;
3284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
3294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	s = s0 = rv_alloc(i);
3304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (s == NULL)
3314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		return (NULL);
3324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
3334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
3344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (mode > 1 && Rounding != 1)
3354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		leftright = 0;
3364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
3374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
3384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
3394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
3404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		/* Try to get by with floating-point arithmetic. */
3414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
3424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i = 0;
3434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		dval(&d2) = dval(&d);
3444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		k0 = k;
3454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		ilim0 = ilim;
3464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		ieps = 2; /* conservative */
3474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (k > 0) {
3484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ds = tens[k&0xf];
3494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			j = k >> 4;
3504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (j & Bletch) {
3514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				/* prevent overflows */
3524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				j &= Bletch - 1;
3534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				dval(&d) /= bigtens[n_bigtens-1];
3544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				ieps++;
3554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
3564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			for(; j; j >>= 1, i++)
3574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (j & 1) {
3584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					ieps++;
3594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					ds *= bigtens[i];
3604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					}
3614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&d) /= ds;
3624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
3634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		else if (( j1 = -k )!=0) {
3644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&d) *= tens[j1 & 0xf];
3654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			for(j = j1 >> 4; j; j >>= 1, i++)
3664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (j & 1) {
3674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					ieps++;
3684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					dval(&d) *= bigtens[i];
3694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					}
3704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
3714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (k_check && dval(&d) < 1. && ilim > 0) {
3724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (ilim1 <= 0)
3734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto fast_failed;
3744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ilim = ilim1;
3754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			k--;
3764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&d) *= 10.;
3774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ieps++;
3784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
3794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		dval(&eps) = ieps*dval(&d) + 7.;
3804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		word0(&eps) -= (P-1)*Exp_msk1;
3814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (ilim == 0) {
3824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			S = mhi = 0;
3834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&d) -= 5.;
3844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (dval(&d) > dval(&eps))
3854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto one_digit;
3864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (dval(&d) < -dval(&eps))
3874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto no_digits;
3884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			goto fast_failed;
3894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
3904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef No_leftright
3914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (leftright) {
3924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			/* Use Steele & White method of only
3934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			 * generating digits needed.
3944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			 */
3954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
3964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			for(i = 0;;) {
3974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				L = dval(&d);
3984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				dval(&d) -= L;
3994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				*s++ = '0' + (int)L;
4004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (dval(&d) < dval(&eps))
4014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					goto ret1;
4024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (1. - dval(&d) < dval(&eps))
4034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					goto bump_up;
4044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (++i >= ilim)
4054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					break;
4064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				dval(&eps) *= 10.;
4074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				dval(&d) *= 10.;
4084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
4094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
4104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		else {
4114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
4124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			/* Generate ilim digits, then fix them up. */
4134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&eps) *= tens[ilim-1];
4144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			for(i = 1;; i++, dval(&d) *= 10.) {
4154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				L = (Long)(dval(&d));
4164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (!(dval(&d) -= L))
4174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					ilim = i;
4184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				*s++ = '0' + (int)L;
4194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (i == ilim) {
4204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					if (dval(&d) > 0.5 + dval(&eps))
4214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes						goto bump_up;
4224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					else if (dval(&d) < 0.5 - dval(&eps)) {
4234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes						while(*--s == '0');
4244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes						s++;
4254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes						goto ret1;
4264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes						}
4274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					break;
4284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					}
4294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
4304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef No_leftright
4314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
4324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
4334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes fast_failed:
4344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s = s0;
4354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		dval(&d) = dval(&d2);
4364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		k = k0;
4374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		ilim = ilim0;
4384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
4394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
4404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	/* Do we have a "small" integer? */
4414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
4424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (be >= 0 && k <= Int_max) {
4434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		/* Yes. */
4444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		ds = tens[k];
4454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (ndigits < 0 && ilim <= 0) {
4464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			S = mhi = 0;
4474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (ilim < 0 || dval(&d) <= 5*ds)
4484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto no_digits;
4494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			goto one_digit;
4504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
4514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		for(i = 1;; i++, dval(&d) *= 10.) {
4524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			L = (Long)(dval(&d) / ds);
4534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&d) -= L*ds;
4544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Check_FLT_ROUNDS
4554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			/* If FLT_ROUNDS == 2, L will usually be high by 1 */
4564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (dval(&d) < 0) {
4574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				L--;
4584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				dval(&d) += ds;
4594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
4604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
4614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			*s++ = '0' + (int)L;
4624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (!dval(&d)) {
4634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT
4644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				inexact = 0;
4654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
4664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				break;
4674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
4684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (i == ilim) {
4694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
4704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (mode > 1)
4714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				switch(Rounding) {
4724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				  case 0: goto ret1;
4734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				  case 2: goto bump_up;
4744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				  }
4754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
4764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				dval(&d) += dval(&d);
4774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef ROUND_BIASED
4784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (dval(&d) >= ds)
4794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
4804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (dval(&d) > ds || (dval(&d) == ds && L & 1))
4814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
4824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					{
4834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes bump_up:
4844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					while(*--s == '9')
4854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes						if (s == s0) {
4864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes							k++;
4874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes							*s = '0';
4884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes							break;
4894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes							}
4904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					++*s++;
4914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					}
4924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				break;
4934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
4944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
4954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		goto ret1;
4964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
4974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
4984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	m2 = b2;
4994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	m5 = b5;
5004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	mhi = mlo = 0;
5014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (leftright) {
5024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i =
5034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef Sudden_Underflow
5044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			denorm ? be + (Bias + (P-1) - 1 + 1) :
5054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
5064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef IBM
5074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
5084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
5094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			1 + P - bbits;
5104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
5114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b2 += i;
5124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s2 += i;
5134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		mhi = i2b(1);
5144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (mhi == NULL)
5154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			return (NULL);
5164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
5174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (m2 > 0 && s2 > 0) {
5184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i = m2 < s2 ? m2 : s2;
5194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b2 -= i;
5204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		m2 -= i;
5214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s2 -= i;
5224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
5234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (b5 > 0) {
5244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (leftright) {
5254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (m5 > 0) {
5264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				mhi = pow5mult(mhi, m5);
5274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (mhi == NULL)
5284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					return (NULL);
5294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				b1 = mult(mhi, b);
5304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (b1 == NULL)
5314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					return (NULL);
5324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				Bfree(b);
5334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				b = b1;
5344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
5354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (( j = b5 - m5 )!=0) {
5364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				b = pow5mult(b, j);
5374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (b == NULL)
5384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					return (NULL);
5394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
5404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
5414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		else {
5424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			b = pow5mult(b, b5);
5434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (b == NULL)
5444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				return (NULL);
5454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
5464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
5474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	S = i2b(1);
5484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (S == NULL)
5494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		return (NULL);
5504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (s5 > 0) {
5514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		S = pow5mult(S, s5);
5524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (S == NULL)
5534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			return (NULL);
5544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
5554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
5564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	/* Check for special case that d is a normalized power of 2. */
5574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
5584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	spec_case = 0;
5594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if ((mode < 2 || leftright)
5604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
5614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			&& Rounding == 1
5624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
5634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				) {
5644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (!word1(&d) && !(word0(&d) & Bndry_mask)
5654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef Sudden_Underflow
5664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 && word0(&d) & (Exp_mask & ~Exp_msk1)
5674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
5684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				) {
5694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			/* The special case */
5704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			b2 += Log2P;
5714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			s2 += Log2P;
5724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			spec_case = 1;
5734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
5744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
5754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
5764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	/* Arrange for convenient computation of quotients:
5774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	 * shift left if necessary so divisor has 4 leading 0 bits.
5784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	 *
5794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	 * Perhaps we should just compute leading 28 bits of S once
5804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	 * and for all and pass them and a shift to quorem, so it
5814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	 * can do shifts and ors to compute the numerator for q.
5824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	 */
5834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Pack_32
5844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)
5854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i = 32 - i;
5864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
5874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)
5884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i = 16 - i;
5894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
5904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (i > 4) {
5914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i -= 4;
5924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b2 += i;
5934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		m2 += i;
5944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s2 += i;
5954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
5964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	else if (i < 4) {
5974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		i += 28;
5984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b2 += i;
5994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		m2 += i;
6004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s2 += i;
6014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
6024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (b2 > 0) {
6034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		b = lshift(b, b2);
6044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (b == NULL)
6054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			return (NULL);
6064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
6074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (s2 > 0) {
6084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		S = lshift(S, s2);
6094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (S == NULL)
6104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			return (NULL);
6114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
6124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (k_check) {
6134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (cmp(b,S) < 0) {
6144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			k--;
6154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			b = multadd(b, 10, 0);	/* we botched the k estimate */
6164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (b == NULL)
6174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				return (NULL);
6184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (leftright) {
6194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				mhi = multadd(mhi, 10, 0);
6204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (mhi == NULL)
6214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					return (NULL);
6224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
6234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			ilim = ilim1;
6244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
6254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
6264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (ilim <= 0 && (mode == 3 || mode == 5)) {
6274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		S = multadd(S,5,0);
6284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (S == NULL)
6294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			return (NULL);
6304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (ilim < 0 || cmp(b,S) <= 0) {
6314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			/* no digits, fcvt style */
6324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes no_digits:
6334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			k = -1 - ndigits;
6344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			goto ret;
6354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
6364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes one_digit:
6374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		*s++ = '1';
6384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		k++;
6394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		goto ret;
6404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
6414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (leftright) {
6424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (m2 > 0) {
6434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			mhi = lshift(mhi, m2);
6444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (mhi == NULL)
6454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				return (NULL);
6464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
6474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
6484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		/* Compute mlo -- check for special case
6494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 * that d is a normalized power of 2.
6504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		 */
6514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
6524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		mlo = mhi;
6534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (spec_case) {
6544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			mhi = Balloc(mhi->k);
6554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (mhi == NULL)
6564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				return (NULL);
6574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			Bcopy(mhi, mlo);
6584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			mhi = lshift(mhi, Log2P);
6594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (mhi == NULL)
6604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				return (NULL);
6614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
6624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
6634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		for(i = 1;;i++) {
6644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dig = quorem(b,S) + '0';
6654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			/* Do we yet have the shortest decimal string
6664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			 * that will round to d?
6674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			 */
6684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			j = cmp(b, mlo);
6694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			delta = diff(S, mhi);
6704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (delta == NULL)
6714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				return (NULL);
6724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			j1 = delta->sign ? 1 : cmp(b, delta);
6734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			Bfree(delta);
6744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef ROUND_BIASED
6754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (j1 == 0 && mode != 1 && !(word1(&d) & 1)
6764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
6774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				&& Rounding >= 1
6784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
6794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes								   ) {
6804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (dig == '9')
6814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					goto round_9_up;
6824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (j > 0)
6834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					dig++;
6844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT
6854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				else if (!b->x[0] && b->wds <= 1)
6864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					inexact = 0;
6874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
6884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				*s++ = dig;
6894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto ret;
6904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
6914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
6924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (j < 0 || (j == 0 && mode != 1
6934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifndef ROUND_BIASED
6944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes							&& !(word1(&d) & 1)
6954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
6964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					)) {
6974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (!b->x[0] && b->wds <= 1) {
6984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT
6994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					inexact = 0;
7004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
7014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					goto accept_dig;
7024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					}
7034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
7044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (mode > 1)
7054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				 switch(Rounding) {
7064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				  case 0: goto accept_dig;
7074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				  case 2: goto keep_dig;
7084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				  }
7094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif /*Honor_FLT_ROUNDS*/
7104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (j1 > 0) {
7114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					b = lshift(b, 1);
7124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					if (b == NULL)
7134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes						return (NULL);
7144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					j1 = cmp(b, S);
7154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef ROUND_BIASED
7164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					if (j1 >= 0 /*)*/
7174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
7184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					if ((j1 > 0 || (j1 == 0 && dig & 1))
7194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
7204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					&& dig++ == '9')
7214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes						goto round_9_up;
7224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					}
7234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes accept_dig:
7244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				*s++ = dig;
7254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto ret;
7264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
7274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (j1 > 0) {
7284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
7294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (!Rounding)
7304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					goto accept_dig;
7314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
7324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (dig == '9') { /* possible if i == 1 */
7334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes round_9_up:
7344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					*s++ = '9';
7354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					goto roundoff;
7364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					}
7374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				*s++ = dig + 1;
7384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto ret;
7394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
7404bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
7414bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes keep_dig:
7424bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
7434bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			*s++ = dig;
7444bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (i == ilim)
7454bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				break;
7464bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			b = multadd(b, 10, 0);
7474bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (b == NULL)
7484bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				return (NULL);
7494bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (mlo == mhi) {
7504bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				mlo = mhi = multadd(mhi, 10, 0);
7514bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (mlo == NULL)
7524bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					return (NULL);
7534bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
7544bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			else {
7554bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				mlo = multadd(mlo, 10, 0);
7564bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (mlo == NULL)
7574bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					return (NULL);
7584bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				mhi = multadd(mhi, 10, 0);
7594bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				if (mhi == NULL)
7604bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes					return (NULL);
7614bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
7624bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
7634bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
7644bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	else
7654bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		for(i = 1;; i++) {
7664bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			*s++ = dig = quorem(b,S) + '0';
7674bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (!b->x[0] && b->wds <= 1) {
7684bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT
7694bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				inexact = 0;
7704bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
7714bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto ret;
7724bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
7734bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (i >= ilim)
7744bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				break;
7754bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			b = multadd(b, 10, 0);
7764bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (b == NULL)
7774bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				return (NULL);
7784bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
7794bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
7804bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	/* Round off last digit */
7814bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes
7824bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
7834bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	switch(Rounding) {
7844bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	  case 0: goto trimzeros;
7854bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	  case 2: goto roundoff;
7864bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	  }
7874bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
7884bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	b = lshift(b, 1);
7894bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (b == NULL)
7904bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		return (NULL);
7914bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	j = cmp(b, S);
7924bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef ROUND_BIASED
7934bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (j >= 0)
7944bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#else
7954bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (j > 0 || (j == 0 && dig & 1))
7964bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
7974bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		{
7984bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes roundoff:
7994bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		while(*--s == '9')
8004bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			if (s == s0) {
8014bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				k++;
8024bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				*s++ = '1';
8034bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				goto ret;
8044bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes				}
8054bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		++*s++;
8064bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
8074bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	else {
8084bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef Honor_FLT_ROUNDS
8094bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes trimzeros:
8104bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
8114bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		while(*--s == '0');
8124bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		s++;
8134bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
8144bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ret:
8154bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	Bfree(S);
8164bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (mhi) {
8174bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (mlo && mlo != mhi)
8184bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			Bfree(mlo);
8194bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		Bfree(mhi);
8204bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
8214bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes ret1:
8224bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#ifdef SET_INEXACT
8234bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (inexact) {
8244bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		if (!oldinexact) {
8254bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			word0(&d) = Exp_1 + (70 << Exp_shift);
8264bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			word1(&d) = 0;
8274bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			dval(&d) += 1.;
8284bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes			}
8294bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		}
8304bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	else if (!oldinexact)
8314bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		clear_inexact();
8324bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes#endif
8334bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	Bfree(b);
8344bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	*s = 0;
8354bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	*decpt = k + 1;
8364bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	if (rve)
8374bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes		*rve = s;
8384bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	return s0;
8394bd97cee28dd815fff54fc97560be60d566c1fa5Elliott Hughes	}
840