xref: /freebsd/contrib/gdtoa/gdtoa.c (revision 50dad48bb740a8e56d185d9e8c165e0758f46e25)
1cc36ccd1SDavid Schultz /****************************************************************
2cc36ccd1SDavid Schultz 
3cc36ccd1SDavid Schultz The author of this software is David M. Gay.
4cc36ccd1SDavid Schultz 
5cc36ccd1SDavid Schultz Copyright (C) 1998, 1999 by Lucent Technologies
6cc36ccd1SDavid Schultz All Rights Reserved
7cc36ccd1SDavid Schultz 
8cc36ccd1SDavid Schultz Permission to use, copy, modify, and distribute this software and
9cc36ccd1SDavid Schultz its documentation for any purpose and without fee is hereby
10cc36ccd1SDavid Schultz granted, provided that the above copyright notice appear in all
11cc36ccd1SDavid Schultz copies and that both that the copyright notice and this
12cc36ccd1SDavid Schultz permission notice and warranty disclaimer appear in supporting
13cc36ccd1SDavid Schultz documentation, and that the name of Lucent or any of its entities
14cc36ccd1SDavid Schultz not be used in advertising or publicity pertaining to
15cc36ccd1SDavid Schultz distribution of the software without specific, written prior
16cc36ccd1SDavid Schultz permission.
17cc36ccd1SDavid Schultz 
18cc36ccd1SDavid Schultz LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19cc36ccd1SDavid Schultz INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20cc36ccd1SDavid Schultz IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21cc36ccd1SDavid Schultz SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22cc36ccd1SDavid Schultz WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23cc36ccd1SDavid Schultz IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24cc36ccd1SDavid Schultz ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25cc36ccd1SDavid Schultz THIS SOFTWARE.
26cc36ccd1SDavid Schultz 
27cc36ccd1SDavid Schultz ****************************************************************/
28cc36ccd1SDavid Schultz 
29c88250a5SDavid Schultz /* Please send bug reports to David M. Gay (dmg at acm dot org,
30c88250a5SDavid Schultz  * with " at " changed at "@" and " dot " changed to ".").	*/
31cc36ccd1SDavid Schultz 
32cc36ccd1SDavid Schultz #include "gdtoaimp.h"
33cc36ccd1SDavid Schultz 
34cc36ccd1SDavid Schultz  static Bigint *
35cc36ccd1SDavid Schultz #ifdef KR_headers
bitstob(bits,nbits,bbits)36cc36ccd1SDavid Schultz bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits;
37cc36ccd1SDavid Schultz #else
38cc36ccd1SDavid Schultz bitstob(ULong *bits, int nbits, int *bbits)
39cc36ccd1SDavid Schultz #endif
40cc36ccd1SDavid Schultz {
41cc36ccd1SDavid Schultz 	int i, k;
42cc36ccd1SDavid Schultz 	Bigint *b;
43cc36ccd1SDavid Schultz 	ULong *be, *x, *x0;
44cc36ccd1SDavid Schultz 
45cc36ccd1SDavid Schultz 	i = ULbits;
46cc36ccd1SDavid Schultz 	k = 0;
47cc36ccd1SDavid Schultz 	while(i < nbits) {
48cc36ccd1SDavid Schultz 		i <<= 1;
49cc36ccd1SDavid Schultz 		k++;
50cc36ccd1SDavid Schultz 		}
51cc36ccd1SDavid Schultz #ifndef Pack_32
52cc36ccd1SDavid Schultz 	if (!k)
53cc36ccd1SDavid Schultz 		k = 1;
54cc36ccd1SDavid Schultz #endif
55cc36ccd1SDavid Schultz 	b = Balloc(k);
56cc36ccd1SDavid Schultz 	be = bits + ((nbits - 1) >> kshift);
57cc36ccd1SDavid Schultz 	x = x0 = b->x;
58cc36ccd1SDavid Schultz 	do {
59cc36ccd1SDavid Schultz 		*x++ = *bits & ALL_ON;
60cc36ccd1SDavid Schultz #ifdef Pack_16
61cc36ccd1SDavid Schultz 		*x++ = (*bits >> 16) & ALL_ON;
62cc36ccd1SDavid Schultz #endif
63cc36ccd1SDavid Schultz 		} while(++bits <= be);
64cc36ccd1SDavid Schultz 	i = x - x0;
65cc36ccd1SDavid Schultz 	while(!x0[--i])
66cc36ccd1SDavid Schultz 		if (!i) {
67cc36ccd1SDavid Schultz 			b->wds = 0;
68cc36ccd1SDavid Schultz 			*bbits = 0;
69cc36ccd1SDavid Schultz 			goto ret;
70cc36ccd1SDavid Schultz 			}
71cc36ccd1SDavid Schultz 	b->wds = i + 1;
72cc36ccd1SDavid Schultz 	*bbits = i*ULbits + 32 - hi0bits(b->x[i]);
73cc36ccd1SDavid Schultz  ret:
74cc36ccd1SDavid Schultz 	return b;
75cc36ccd1SDavid Schultz 	}
76cc36ccd1SDavid Schultz 
77cc36ccd1SDavid Schultz /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
78cc36ccd1SDavid Schultz  *
79cc36ccd1SDavid Schultz  * Inspired by "How to Print Floating-Point Numbers Accurately" by
80c88250a5SDavid Schultz  * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
81cc36ccd1SDavid Schultz  *
82cc36ccd1SDavid Schultz  * Modifications:
83cc36ccd1SDavid Schultz  *	1. Rather than iterating, we use a simple numeric overestimate
84cc36ccd1SDavid Schultz  *	   to determine k = floor(log10(d)).  We scale relevant
85cc36ccd1SDavid Schultz  *	   quantities using O(log2(k)) rather than O(k) multiplications.
86cc36ccd1SDavid Schultz  *	2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
87cc36ccd1SDavid Schultz  *	   try to generate digits strictly left to right.  Instead, we
88cc36ccd1SDavid Schultz  *	   compute with fewer bits and propagate the carry if necessary
89cc36ccd1SDavid Schultz  *	   when rounding the final digit up.  This is often faster.
90cc36ccd1SDavid Schultz  *	3. Under the assumption that input will be rounded nearest,
91cc36ccd1SDavid Schultz  *	   mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
92cc36ccd1SDavid Schultz  *	   That is, we allow equality in stopping tests when the
93cc36ccd1SDavid Schultz  *	   round-nearest rule will give the same floating-point value
94cc36ccd1SDavid Schultz  *	   as would satisfaction of the stopping test with strict
95cc36ccd1SDavid Schultz  *	   inequality.
96cc36ccd1SDavid Schultz  *	4. We remove common factors of powers of 2 from relevant
97cc36ccd1SDavid Schultz  *	   quantities.
98cc36ccd1SDavid Schultz  *	5. When converting floating-point integers less than 1e16,
99cc36ccd1SDavid Schultz  *	   we use floating-point arithmetic rather than resorting
100cc36ccd1SDavid Schultz  *	   to multiple-precision integers.
101cc36ccd1SDavid Schultz  *	6. When asked to produce fewer than 15 digits, we first try
102cc36ccd1SDavid Schultz  *	   to get by with floating-point arithmetic; we resort to
103cc36ccd1SDavid Schultz  *	   multiple-precision integer arithmetic only if we cannot
104cc36ccd1SDavid Schultz  *	   guarantee that the floating-point calculation has given
105cc36ccd1SDavid Schultz  *	   the correctly rounded result.  For k requested digits and
106cc36ccd1SDavid Schultz  *	   "uniformly" distributed input, the probability is
107cc36ccd1SDavid Schultz  *	   something like 10^(k-15) that we must resort to the Long
108cc36ccd1SDavid Schultz  *	   calculation.
109cc36ccd1SDavid Schultz  */
110cc36ccd1SDavid Schultz 
111cc36ccd1SDavid Schultz  char *
gdtoa(fpi,be,bits,kindp,mode,ndigits,decpt,rve)112cc36ccd1SDavid Schultz gdtoa
113cc36ccd1SDavid Schultz #ifdef KR_headers
114cc36ccd1SDavid Schultz 	(fpi, be, bits, kindp, mode, ndigits, decpt, rve)
115cc36ccd1SDavid Schultz 	FPI *fpi; int be; ULong *bits;
116cc36ccd1SDavid Schultz 	int *kindp, mode, ndigits, *decpt; char **rve;
117cc36ccd1SDavid Schultz #else
118cc36ccd1SDavid Schultz 	(FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
119cc36ccd1SDavid Schultz #endif
120cc36ccd1SDavid Schultz {
121cc36ccd1SDavid Schultz  /*	Arguments ndigits and decpt are similar to the second and third
122cc36ccd1SDavid Schultz 	arguments of ecvt and fcvt; trailing zeros are suppressed from
123cc36ccd1SDavid Schultz 	the returned string.  If not null, *rve is set to point
124cc36ccd1SDavid Schultz 	to the end of the return value.  If d is +-Infinity or NaN,
125cc36ccd1SDavid Schultz 	then *decpt is set to 9999.
126*50dad48bSDavid Schultz 	be = exponent: value = (integer represented by bits) * (2 to the power of be).
127cc36ccd1SDavid Schultz 
128cc36ccd1SDavid Schultz 	mode:
129cc36ccd1SDavid Schultz 		0 ==> shortest string that yields d when read in
130cc36ccd1SDavid Schultz 			and rounded to nearest.
131cc36ccd1SDavid Schultz 		1 ==> like 0, but with Steele & White stopping rule;
132cc36ccd1SDavid Schultz 			e.g. with IEEE P754 arithmetic , mode 0 gives
133cc36ccd1SDavid Schultz 			1e23 whereas mode 1 gives 9.999999999999999e22.
134cc36ccd1SDavid Schultz 		2 ==> max(1,ndigits) significant digits.  This gives a
135cc36ccd1SDavid Schultz 			return value similar to that of ecvt, except
136cc36ccd1SDavid Schultz 			that trailing zeros are suppressed.
137cc36ccd1SDavid Schultz 		3 ==> through ndigits past the decimal point.  This
138cc36ccd1SDavid Schultz 			gives a return value similar to that from fcvt,
139cc36ccd1SDavid Schultz 			except that trailing zeros are suppressed, and
140cc36ccd1SDavid Schultz 			ndigits can be negative.
141cc36ccd1SDavid Schultz 		4-9 should give the same return values as 2-3, i.e.,
142cc36ccd1SDavid Schultz 			4 <= mode <= 9 ==> same return as mode
143cc36ccd1SDavid Schultz 			2 + (mode & 1).  These modes are mainly for
144cc36ccd1SDavid Schultz 			debugging; often they run slower but sometimes
145cc36ccd1SDavid Schultz 			faster than modes 2-3.
146cc36ccd1SDavid Schultz 		4,5,8,9 ==> left-to-right digit generation.
147cc36ccd1SDavid Schultz 		6-9 ==> don't try fast floating-point estimate
148cc36ccd1SDavid Schultz 			(if applicable).
149cc36ccd1SDavid Schultz 
150cc36ccd1SDavid Schultz 		Values of mode other than 0-9 are treated as mode 0.
151cc36ccd1SDavid Schultz 
152cc36ccd1SDavid Schultz 		Sufficient space is allocated to the return value
153cc36ccd1SDavid Schultz 		to hold the suppressed trailing zeros.
154cc36ccd1SDavid Schultz 	*/
155cc36ccd1SDavid Schultz 
156cc36ccd1SDavid Schultz 	int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex;
157cc36ccd1SDavid Schultz 	int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits;
158cc36ccd1SDavid Schultz 	int rdir, s2, s5, spec_case, try_quick;
159cc36ccd1SDavid Schultz 	Long L;
160cc36ccd1SDavid Schultz 	Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S;
161*50dad48bSDavid Schultz 	double d2, ds;
162cc36ccd1SDavid Schultz 	char *s, *s0;
163*50dad48bSDavid Schultz 	U d, eps;
164cc36ccd1SDavid Schultz 
165cc36ccd1SDavid Schultz #ifndef MULTIPLE_THREADS
166cc36ccd1SDavid Schultz 	if (dtoa_result) {
167cc36ccd1SDavid Schultz 		freedtoa(dtoa_result);
168cc36ccd1SDavid Schultz 		dtoa_result = 0;
169cc36ccd1SDavid Schultz 		}
170cc36ccd1SDavid Schultz #endif
171cc36ccd1SDavid Schultz 	inex = 0;
172cc36ccd1SDavid Schultz 	kind = *kindp &= ~STRTOG_Inexact;
173cc36ccd1SDavid Schultz 	switch(kind & STRTOG_Retmask) {
174cc36ccd1SDavid Schultz 	  case STRTOG_Zero:
175cc36ccd1SDavid Schultz 		goto ret_zero;
176cc36ccd1SDavid Schultz 	  case STRTOG_Normal:
177cc36ccd1SDavid Schultz 	  case STRTOG_Denormal:
178cc36ccd1SDavid Schultz 		break;
179cc36ccd1SDavid Schultz 	  case STRTOG_Infinite:
180cc36ccd1SDavid Schultz 		*decpt = -32768;
181cc36ccd1SDavid Schultz 		return nrv_alloc("Infinity", rve, 8);
182cc36ccd1SDavid Schultz 	  case STRTOG_NaN:
183cc36ccd1SDavid Schultz 		*decpt = -32768;
184cc36ccd1SDavid Schultz 		return nrv_alloc("NaN", rve, 3);
185cc36ccd1SDavid Schultz 	  default:
186cc36ccd1SDavid Schultz 		return 0;
187cc36ccd1SDavid Schultz 	  }
188cc36ccd1SDavid Schultz 	b = bitstob(bits, nbits = fpi->nbits, &bbits);
189cc36ccd1SDavid Schultz 	be0 = be;
190cc36ccd1SDavid Schultz 	if ( (i = trailz(b)) !=0) {
191cc36ccd1SDavid Schultz 		rshift(b, i);
192cc36ccd1SDavid Schultz 		be += i;
193cc36ccd1SDavid Schultz 		bbits -= i;
194cc36ccd1SDavid Schultz 		}
195cc36ccd1SDavid Schultz 	if (!b->wds) {
196cc36ccd1SDavid Schultz 		Bfree(b);
197cc36ccd1SDavid Schultz  ret_zero:
198cc36ccd1SDavid Schultz 		*decpt = 1;
199cc36ccd1SDavid Schultz 		return nrv_alloc("0", rve, 1);
200cc36ccd1SDavid Schultz 		}
201cc36ccd1SDavid Schultz 
202*50dad48bSDavid Schultz 	dval(&d) = b2d(b, &i);
203cc36ccd1SDavid Schultz 	i = be + bbits - 1;
204*50dad48bSDavid Schultz 	word0(&d) &= Frac_mask1;
205*50dad48bSDavid Schultz 	word0(&d) |= Exp_11;
206cc36ccd1SDavid Schultz #ifdef IBM
207*50dad48bSDavid Schultz 	if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0)
208*50dad48bSDavid Schultz 		dval(&d) /= 1 << j;
209cc36ccd1SDavid Schultz #endif
210cc36ccd1SDavid Schultz 
211cc36ccd1SDavid Schultz 	/* log(x)	~=~ log(1.5) + (x-1.5)/1.5
212cc36ccd1SDavid Schultz 	 * log10(x)	 =  log(x) / log(10)
213cc36ccd1SDavid Schultz 	 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
214*50dad48bSDavid Schultz 	 * log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2)
215cc36ccd1SDavid Schultz 	 *
216*50dad48bSDavid Schultz 	 * This suggests computing an approximation k to log10(&d) by
217cc36ccd1SDavid Schultz 	 *
218cc36ccd1SDavid Schultz 	 * k = (i - Bias)*0.301029995663981
219cc36ccd1SDavid Schultz 	 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
220cc36ccd1SDavid Schultz 	 *
221cc36ccd1SDavid Schultz 	 * We want k to be too large rather than too small.
222cc36ccd1SDavid Schultz 	 * The error in the first-order Taylor series approximation
223cc36ccd1SDavid Schultz 	 * is in our favor, so we just round up the constant enough
224cc36ccd1SDavid Schultz 	 * to compensate for any error in the multiplication of
225cc36ccd1SDavid Schultz 	 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
226cc36ccd1SDavid Schultz 	 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
227cc36ccd1SDavid Schultz 	 * adding 1e-13 to the constant term more than suffices.
228cc36ccd1SDavid Schultz 	 * Hence we adjust the constant term to 0.1760912590558.
229cc36ccd1SDavid Schultz 	 * (We could get a more accurate k by invoking log10,
230cc36ccd1SDavid Schultz 	 *  but this is probably not worthwhile.)
231cc36ccd1SDavid Schultz 	 */
232cc36ccd1SDavid Schultz #ifdef IBM
233cc36ccd1SDavid Schultz 	i <<= 2;
234cc36ccd1SDavid Schultz 	i += j;
235cc36ccd1SDavid Schultz #endif
236*50dad48bSDavid Schultz 	ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
237cc36ccd1SDavid Schultz 
238cc36ccd1SDavid Schultz 	/* correct assumption about exponent range */
239cc36ccd1SDavid Schultz 	if ((j = i) < 0)
240cc36ccd1SDavid Schultz 		j = -j;
241cc36ccd1SDavid Schultz 	if ((j -= 1077) > 0)
242cc36ccd1SDavid Schultz 		ds += j * 7e-17;
243cc36ccd1SDavid Schultz 
244cc36ccd1SDavid Schultz 	k = (int)ds;
245cc36ccd1SDavid Schultz 	if (ds < 0. && ds != k)
246cc36ccd1SDavid Schultz 		k--;	/* want k = floor(ds) */
247cc36ccd1SDavid Schultz 	k_check = 1;
248cc36ccd1SDavid Schultz #ifdef IBM
249cc36ccd1SDavid Schultz 	j = be + bbits - 1;
250cc36ccd1SDavid Schultz 	if ( (j1 = j & 3) !=0)
251*50dad48bSDavid Schultz 		dval(&d) *= 1 << j1;
252*50dad48bSDavid Schultz 	word0(&d) += j << Exp_shift - 2 & Exp_mask;
253cc36ccd1SDavid Schultz #else
254*50dad48bSDavid Schultz 	word0(&d) += (be + bbits - 1) << Exp_shift;
255cc36ccd1SDavid Schultz #endif
256cc36ccd1SDavid Schultz 	if (k >= 0 && k <= Ten_pmax) {
257*50dad48bSDavid Schultz 		if (dval(&d) < tens[k])
258cc36ccd1SDavid Schultz 			k--;
259cc36ccd1SDavid Schultz 		k_check = 0;
260cc36ccd1SDavid Schultz 		}
261cc36ccd1SDavid Schultz 	j = bbits - i - 1;
262cc36ccd1SDavid Schultz 	if (j >= 0) {
263cc36ccd1SDavid Schultz 		b2 = 0;
264cc36ccd1SDavid Schultz 		s2 = j;
265cc36ccd1SDavid Schultz 		}
266cc36ccd1SDavid Schultz 	else {
267cc36ccd1SDavid Schultz 		b2 = -j;
268cc36ccd1SDavid Schultz 		s2 = 0;
269cc36ccd1SDavid Schultz 		}
270cc36ccd1SDavid Schultz 	if (k >= 0) {
271cc36ccd1SDavid Schultz 		b5 = 0;
272cc36ccd1SDavid Schultz 		s5 = k;
273cc36ccd1SDavid Schultz 		s2 += k;
274cc36ccd1SDavid Schultz 		}
275cc36ccd1SDavid Schultz 	else {
276cc36ccd1SDavid Schultz 		b2 -= k;
277cc36ccd1SDavid Schultz 		b5 = -k;
278cc36ccd1SDavid Schultz 		s5 = 0;
279cc36ccd1SDavid Schultz 		}
280cc36ccd1SDavid Schultz 	if (mode < 0 || mode > 9)
281cc36ccd1SDavid Schultz 		mode = 0;
282cc36ccd1SDavid Schultz 	try_quick = 1;
283cc36ccd1SDavid Schultz 	if (mode > 5) {
284cc36ccd1SDavid Schultz 		mode -= 4;
285cc36ccd1SDavid Schultz 		try_quick = 0;
286cc36ccd1SDavid Schultz 		}
287*50dad48bSDavid Schultz 	else if (i >= -4 - Emin || i < Emin)
288*50dad48bSDavid Schultz 		try_quick = 0;
289cc36ccd1SDavid Schultz 	leftright = 1;
290*50dad48bSDavid Schultz 	ilim = ilim1 = -1;	/* Values for cases 0 and 1; done here to */
291*50dad48bSDavid Schultz 				/* silence erroneous "gcc -Wall" warning. */
292cc36ccd1SDavid Schultz 	switch(mode) {
293cc36ccd1SDavid Schultz 		case 0:
294cc36ccd1SDavid Schultz 		case 1:
295cc36ccd1SDavid Schultz 			i = (int)(nbits * .30103) + 3;
296cc36ccd1SDavid Schultz 			ndigits = 0;
297cc36ccd1SDavid Schultz 			break;
298cc36ccd1SDavid Schultz 		case 2:
299cc36ccd1SDavid Schultz 			leftright = 0;
300cc36ccd1SDavid Schultz 			/* no break */
301cc36ccd1SDavid Schultz 		case 4:
302cc36ccd1SDavid Schultz 			if (ndigits <= 0)
303cc36ccd1SDavid Schultz 				ndigits = 1;
304cc36ccd1SDavid Schultz 			ilim = ilim1 = i = ndigits;
305cc36ccd1SDavid Schultz 			break;
306cc36ccd1SDavid Schultz 		case 3:
307cc36ccd1SDavid Schultz 			leftright = 0;
308cc36ccd1SDavid Schultz 			/* no break */
309cc36ccd1SDavid Schultz 		case 5:
310cc36ccd1SDavid Schultz 			i = ndigits + k + 1;
311cc36ccd1SDavid Schultz 			ilim = i;
312cc36ccd1SDavid Schultz 			ilim1 = i - 1;
313cc36ccd1SDavid Schultz 			if (i <= 0)
314cc36ccd1SDavid Schultz 				i = 1;
315cc36ccd1SDavid Schultz 		}
316cc36ccd1SDavid Schultz 	s = s0 = rv_alloc(i);
317cc36ccd1SDavid Schultz 
318cc36ccd1SDavid Schultz 	if ( (rdir = fpi->rounding - 1) !=0) {
319cc36ccd1SDavid Schultz 		if (rdir < 0)
320cc36ccd1SDavid Schultz 			rdir = 2;
321cc36ccd1SDavid Schultz 		if (kind & STRTOG_Neg)
322cc36ccd1SDavid Schultz 			rdir = 3 - rdir;
323cc36ccd1SDavid Schultz 		}
324cc36ccd1SDavid Schultz 
325cc36ccd1SDavid Schultz 	/* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */
326cc36ccd1SDavid Schultz 
327cc36ccd1SDavid Schultz 	if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir
328cc36ccd1SDavid Schultz #ifndef IMPRECISE_INEXACT
329cc36ccd1SDavid Schultz 		&& k == 0
330cc36ccd1SDavid Schultz #endif
331cc36ccd1SDavid Schultz 								) {
332cc36ccd1SDavid Schultz 
333cc36ccd1SDavid Schultz 		/* Try to get by with floating-point arithmetic. */
334cc36ccd1SDavid Schultz 
335cc36ccd1SDavid Schultz 		i = 0;
336*50dad48bSDavid Schultz 		d2 = dval(&d);
337cc36ccd1SDavid Schultz #ifdef IBM
338*50dad48bSDavid Schultz 		if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0)
339*50dad48bSDavid Schultz 			dval(&d) /= 1 << j;
340cc36ccd1SDavid Schultz #endif
341cc36ccd1SDavid Schultz 		k0 = k;
342cc36ccd1SDavid Schultz 		ilim0 = ilim;
343cc36ccd1SDavid Schultz 		ieps = 2; /* conservative */
344cc36ccd1SDavid Schultz 		if (k > 0) {
345cc36ccd1SDavid Schultz 			ds = tens[k&0xf];
346cc36ccd1SDavid Schultz 			j = k >> 4;
347cc36ccd1SDavid Schultz 			if (j & Bletch) {
348cc36ccd1SDavid Schultz 				/* prevent overflows */
349cc36ccd1SDavid Schultz 				j &= Bletch - 1;
350*50dad48bSDavid Schultz 				dval(&d) /= bigtens[n_bigtens-1];
351cc36ccd1SDavid Schultz 				ieps++;
352cc36ccd1SDavid Schultz 				}
353cc36ccd1SDavid Schultz 			for(; j; j >>= 1, i++)
354cc36ccd1SDavid Schultz 				if (j & 1) {
355cc36ccd1SDavid Schultz 					ieps++;
356cc36ccd1SDavid Schultz 					ds *= bigtens[i];
357cc36ccd1SDavid Schultz 					}
358cc36ccd1SDavid Schultz 			}
359cc36ccd1SDavid Schultz 		else  {
360cc36ccd1SDavid Schultz 			ds = 1.;
361cc36ccd1SDavid Schultz 			if ( (j1 = -k) !=0) {
362*50dad48bSDavid Schultz 				dval(&d) *= tens[j1 & 0xf];
363cc36ccd1SDavid Schultz 				for(j = j1 >> 4; j; j >>= 1, i++)
364cc36ccd1SDavid Schultz 					if (j & 1) {
365cc36ccd1SDavid Schultz 						ieps++;
366*50dad48bSDavid Schultz 						dval(&d) *= bigtens[i];
367cc36ccd1SDavid Schultz 						}
368cc36ccd1SDavid Schultz 				}
369cc36ccd1SDavid Schultz 			}
370*50dad48bSDavid Schultz 		if (k_check && dval(&d) < 1. && ilim > 0) {
371cc36ccd1SDavid Schultz 			if (ilim1 <= 0)
372cc36ccd1SDavid Schultz 				goto fast_failed;
373cc36ccd1SDavid Schultz 			ilim = ilim1;
374cc36ccd1SDavid Schultz 			k--;
375*50dad48bSDavid Schultz 			dval(&d) *= 10.;
376cc36ccd1SDavid Schultz 			ieps++;
377cc36ccd1SDavid Schultz 			}
378*50dad48bSDavid Schultz 		dval(&eps) = ieps*dval(&d) + 7.;
379*50dad48bSDavid Schultz 		word0(&eps) -= (P-1)*Exp_msk1;
380cc36ccd1SDavid Schultz 		if (ilim == 0) {
381cc36ccd1SDavid Schultz 			S = mhi = 0;
382*50dad48bSDavid Schultz 			dval(&d) -= 5.;
383*50dad48bSDavid Schultz 			if (dval(&d) > dval(&eps))
384cc36ccd1SDavid Schultz 				goto one_digit;
385*50dad48bSDavid Schultz 			if (dval(&d) < -dval(&eps))
386cc36ccd1SDavid Schultz 				goto no_digits;
387cc36ccd1SDavid Schultz 			goto fast_failed;
388cc36ccd1SDavid Schultz 			}
389cc36ccd1SDavid Schultz #ifndef No_leftright
390cc36ccd1SDavid Schultz 		if (leftright) {
391cc36ccd1SDavid Schultz 			/* Use Steele & White method of only
392cc36ccd1SDavid Schultz 			 * generating digits needed.
393cc36ccd1SDavid Schultz 			 */
394*50dad48bSDavid Schultz 			dval(&eps) = ds*0.5/tens[ilim-1] - dval(&eps);
395cc36ccd1SDavid Schultz 			for(i = 0;;) {
396*50dad48bSDavid Schultz 				L = (Long)(dval(&d)/ds);
397*50dad48bSDavid Schultz 				dval(&d) -= L*ds;
398cc36ccd1SDavid Schultz 				*s++ = '0' + (int)L;
399*50dad48bSDavid Schultz 				if (dval(&d) < dval(&eps)) {
400*50dad48bSDavid Schultz 					if (dval(&d))
401cc36ccd1SDavid Schultz 						inex = STRTOG_Inexlo;
402cc36ccd1SDavid Schultz 					goto ret1;
403cc36ccd1SDavid Schultz 					}
404*50dad48bSDavid Schultz 				if (ds - dval(&d) < dval(&eps))
405cc36ccd1SDavid Schultz 					goto bump_up;
406cc36ccd1SDavid Schultz 				if (++i >= ilim)
407cc36ccd1SDavid Schultz 					break;
408*50dad48bSDavid Schultz 				dval(&eps) *= 10.;
409*50dad48bSDavid Schultz 				dval(&d) *= 10.;
410cc36ccd1SDavid Schultz 				}
411cc36ccd1SDavid Schultz 			}
412cc36ccd1SDavid Schultz 		else {
413cc36ccd1SDavid Schultz #endif
414cc36ccd1SDavid Schultz 			/* Generate ilim digits, then fix them up. */
415*50dad48bSDavid Schultz 			dval(&eps) *= tens[ilim-1];
416*50dad48bSDavid Schultz 			for(i = 1;; i++, dval(&d) *= 10.) {
417*50dad48bSDavid Schultz 				if ( (L = (Long)(dval(&d)/ds)) !=0)
418*50dad48bSDavid Schultz 					dval(&d) -= L*ds;
419cc36ccd1SDavid Schultz 				*s++ = '0' + (int)L;
420cc36ccd1SDavid Schultz 				if (i == ilim) {
421cc36ccd1SDavid Schultz 					ds *= 0.5;
422*50dad48bSDavid Schultz 					if (dval(&d) > ds + dval(&eps))
423cc36ccd1SDavid Schultz 						goto bump_up;
424*50dad48bSDavid Schultz 					else if (dval(&d) < ds - dval(&eps)) {
425*50dad48bSDavid Schultz 						if (dval(&d))
426cc36ccd1SDavid Schultz 							inex = STRTOG_Inexlo;
4274848dd08SDavid Schultz 						goto clear_trailing0;
428cc36ccd1SDavid Schultz 						}
429cc36ccd1SDavid Schultz 					break;
430cc36ccd1SDavid Schultz 					}
431cc36ccd1SDavid Schultz 				}
432cc36ccd1SDavid Schultz #ifndef No_leftright
433cc36ccd1SDavid Schultz 			}
434cc36ccd1SDavid Schultz #endif
435cc36ccd1SDavid Schultz  fast_failed:
436cc36ccd1SDavid Schultz 		s = s0;
437*50dad48bSDavid Schultz 		dval(&d) = d2;
438cc36ccd1SDavid Schultz 		k = k0;
439cc36ccd1SDavid Schultz 		ilim = ilim0;
440cc36ccd1SDavid Schultz 		}
441cc36ccd1SDavid Schultz 
442cc36ccd1SDavid Schultz 	/* Do we have a "small" integer? */
443cc36ccd1SDavid Schultz 
444cc36ccd1SDavid Schultz 	if (be >= 0 && k <= Int_max) {
445cc36ccd1SDavid Schultz 		/* Yes. */
446cc36ccd1SDavid Schultz 		ds = tens[k];
447cc36ccd1SDavid Schultz 		if (ndigits < 0 && ilim <= 0) {
448cc36ccd1SDavid Schultz 			S = mhi = 0;
449*50dad48bSDavid Schultz 			if (ilim < 0 || dval(&d) <= 5*ds)
450cc36ccd1SDavid Schultz 				goto no_digits;
451cc36ccd1SDavid Schultz 			goto one_digit;
452cc36ccd1SDavid Schultz 			}
453*50dad48bSDavid Schultz 		for(i = 1;; i++, dval(&d) *= 10.) {
454*50dad48bSDavid Schultz 			L = dval(&d) / ds;
455*50dad48bSDavid Schultz 			dval(&d) -= L*ds;
456cc36ccd1SDavid Schultz #ifdef Check_FLT_ROUNDS
457cc36ccd1SDavid Schultz 			/* If FLT_ROUNDS == 2, L will usually be high by 1 */
458*50dad48bSDavid Schultz 			if (dval(&d) < 0) {
459cc36ccd1SDavid Schultz 				L--;
460*50dad48bSDavid Schultz 				dval(&d) += ds;
461cc36ccd1SDavid Schultz 				}
462cc36ccd1SDavid Schultz #endif
463cc36ccd1SDavid Schultz 			*s++ = '0' + (int)L;
464*50dad48bSDavid Schultz 			if (dval(&d) == 0.)
465cc36ccd1SDavid Schultz 				break;
466cc36ccd1SDavid Schultz 			if (i == ilim) {
467cc36ccd1SDavid Schultz 				if (rdir) {
468cc36ccd1SDavid Schultz 					if (rdir == 1)
469cc36ccd1SDavid Schultz 						goto bump_up;
470cc36ccd1SDavid Schultz 					inex = STRTOG_Inexlo;
471cc36ccd1SDavid Schultz 					goto ret1;
472cc36ccd1SDavid Schultz 					}
473*50dad48bSDavid Schultz 				dval(&d) += dval(&d);
474*50dad48bSDavid Schultz #ifdef ROUND_BIASED
475*50dad48bSDavid Schultz 				if (dval(&d) >= ds)
476*50dad48bSDavid Schultz #else
477*50dad48bSDavid Schultz 				if (dval(&d) > ds || (dval(&d) == ds && L & 1))
478*50dad48bSDavid Schultz #endif
479*50dad48bSDavid Schultz 					{
480cc36ccd1SDavid Schultz  bump_up:
481cc36ccd1SDavid Schultz 					inex = STRTOG_Inexhi;
482cc36ccd1SDavid Schultz 					while(*--s == '9')
483cc36ccd1SDavid Schultz 						if (s == s0) {
484cc36ccd1SDavid Schultz 							k++;
485cc36ccd1SDavid Schultz 							*s = '0';
486cc36ccd1SDavid Schultz 							break;
487cc36ccd1SDavid Schultz 							}
488cc36ccd1SDavid Schultz 					++*s++;
489cc36ccd1SDavid Schultz 					}
4904848dd08SDavid Schultz 				else {
491cc36ccd1SDavid Schultz 					inex = STRTOG_Inexlo;
4924848dd08SDavid Schultz  clear_trailing0:
4934848dd08SDavid Schultz 					while(*--s == '0'){}
4944848dd08SDavid Schultz 					++s;
4954848dd08SDavid Schultz 					}
496cc36ccd1SDavid Schultz 				break;
497cc36ccd1SDavid Schultz 				}
498cc36ccd1SDavid Schultz 			}
499cc36ccd1SDavid Schultz 		goto ret1;
500cc36ccd1SDavid Schultz 		}
501cc36ccd1SDavid Schultz 
502cc36ccd1SDavid Schultz 	m2 = b2;
503cc36ccd1SDavid Schultz 	m5 = b5;
504cc36ccd1SDavid Schultz 	mhi = mlo = 0;
505cc36ccd1SDavid Schultz 	if (leftright) {
506cc36ccd1SDavid Schultz 		i = nbits - bbits;
507*50dad48bSDavid Schultz 		if (be - i++ < fpi->emin && mode != 3 && mode != 5) {
508cc36ccd1SDavid Schultz 			/* denormal */
509cc36ccd1SDavid Schultz 			i = be - fpi->emin + 1;
510*50dad48bSDavid Schultz 			if (mode >= 2 && ilim > 0 && ilim < i)
511*50dad48bSDavid Schultz 				goto small_ilim;
512cc36ccd1SDavid Schultz 			}
513*50dad48bSDavid Schultz 		else if (mode >= 2) {
514*50dad48bSDavid Schultz  small_ilim:
515cc36ccd1SDavid Schultz 			j = ilim - 1;
516cc36ccd1SDavid Schultz 			if (m5 >= j)
517cc36ccd1SDavid Schultz 				m5 -= j;
518cc36ccd1SDavid Schultz 			else {
519cc36ccd1SDavid Schultz 				s5 += j -= m5;
520cc36ccd1SDavid Schultz 				b5 += j;
521cc36ccd1SDavid Schultz 				m5 = 0;
522cc36ccd1SDavid Schultz 				}
523cc36ccd1SDavid Schultz 			if ((i = ilim) < 0) {
524cc36ccd1SDavid Schultz 				m2 -= i;
525cc36ccd1SDavid Schultz 				i = 0;
526cc36ccd1SDavid Schultz 				}
527cc36ccd1SDavid Schultz 			}
528cc36ccd1SDavid Schultz 		b2 += i;
529cc36ccd1SDavid Schultz 		s2 += i;
530cc36ccd1SDavid Schultz 		mhi = i2b(1);
531cc36ccd1SDavid Schultz 		}
532cc36ccd1SDavid Schultz 	if (m2 > 0 && s2 > 0) {
533cc36ccd1SDavid Schultz 		i = m2 < s2 ? m2 : s2;
534cc36ccd1SDavid Schultz 		b2 -= i;
535cc36ccd1SDavid Schultz 		m2 -= i;
536cc36ccd1SDavid Schultz 		s2 -= i;
537cc36ccd1SDavid Schultz 		}
538cc36ccd1SDavid Schultz 	if (b5 > 0) {
539cc36ccd1SDavid Schultz 		if (leftright) {
540cc36ccd1SDavid Schultz 			if (m5 > 0) {
541cc36ccd1SDavid Schultz 				mhi = pow5mult(mhi, m5);
542cc36ccd1SDavid Schultz 				b1 = mult(mhi, b);
543cc36ccd1SDavid Schultz 				Bfree(b);
544cc36ccd1SDavid Schultz 				b = b1;
545cc36ccd1SDavid Schultz 				}
546cc36ccd1SDavid Schultz 			if ( (j = b5 - m5) !=0)
547cc36ccd1SDavid Schultz 				b = pow5mult(b, j);
548cc36ccd1SDavid Schultz 			}
549cc36ccd1SDavid Schultz 		else
550cc36ccd1SDavid Schultz 			b = pow5mult(b, b5);
551cc36ccd1SDavid Schultz 		}
552cc36ccd1SDavid Schultz 	S = i2b(1);
553cc36ccd1SDavid Schultz 	if (s5 > 0)
554cc36ccd1SDavid Schultz 		S = pow5mult(S, s5);
555cc36ccd1SDavid Schultz 
556cc36ccd1SDavid Schultz 	/* Check for special case that d is a normalized power of 2. */
557cc36ccd1SDavid Schultz 
558cc36ccd1SDavid Schultz 	spec_case = 0;
559cc36ccd1SDavid Schultz 	if (mode < 2) {
560cc36ccd1SDavid Schultz 		if (bbits == 1 && be0 > fpi->emin + 1) {
561cc36ccd1SDavid Schultz 			/* The special case */
562cc36ccd1SDavid Schultz 			b2++;
563cc36ccd1SDavid Schultz 			s2++;
564cc36ccd1SDavid Schultz 			spec_case = 1;
565cc36ccd1SDavid Schultz 			}
566cc36ccd1SDavid Schultz 		}
567cc36ccd1SDavid Schultz 
568cc36ccd1SDavid Schultz 	/* Arrange for convenient computation of quotients:
569cc36ccd1SDavid Schultz 	 * shift left if necessary so divisor has 4 leading 0 bits.
570cc36ccd1SDavid Schultz 	 *
571cc36ccd1SDavid Schultz 	 * Perhaps we should just compute leading 28 bits of S once
572cc36ccd1SDavid Schultz 	 * and for all and pass them and a shift to quorem, so it
573cc36ccd1SDavid Schultz 	 * can do shifts and ors to compute the numerator for q.
574cc36ccd1SDavid Schultz 	 */
575*50dad48bSDavid Schultz 	i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask;
576cc36ccd1SDavid Schultz 	m2 += i;
577*50dad48bSDavid Schultz 	if ((b2 += i) > 0)
578cc36ccd1SDavid Schultz 		b = lshift(b, b2);
579*50dad48bSDavid Schultz 	if ((s2 += i) > 0)
580cc36ccd1SDavid Schultz 		S = lshift(S, s2);
581cc36ccd1SDavid Schultz 	if (k_check) {
582cc36ccd1SDavid Schultz 		if (cmp(b,S) < 0) {
583cc36ccd1SDavid Schultz 			k--;
584cc36ccd1SDavid Schultz 			b = multadd(b, 10, 0);	/* we botched the k estimate */
585cc36ccd1SDavid Schultz 			if (leftright)
586cc36ccd1SDavid Schultz 				mhi = multadd(mhi, 10, 0);
587cc36ccd1SDavid Schultz 			ilim = ilim1;
588cc36ccd1SDavid Schultz 			}
589cc36ccd1SDavid Schultz 		}
590cc36ccd1SDavid Schultz 	if (ilim <= 0 && mode > 2) {
591cc36ccd1SDavid Schultz 		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
592cc36ccd1SDavid Schultz 			/* no digits, fcvt style */
593cc36ccd1SDavid Schultz  no_digits:
594cc36ccd1SDavid Schultz 			k = -1 - ndigits;
595cc36ccd1SDavid Schultz 			inex = STRTOG_Inexlo;
596cc36ccd1SDavid Schultz 			goto ret;
597cc36ccd1SDavid Schultz 			}
598cc36ccd1SDavid Schultz  one_digit:
599cc36ccd1SDavid Schultz 		inex = STRTOG_Inexhi;
600cc36ccd1SDavid Schultz 		*s++ = '1';
601cc36ccd1SDavid Schultz 		k++;
602cc36ccd1SDavid Schultz 		goto ret;
603cc36ccd1SDavid Schultz 		}
604cc36ccd1SDavid Schultz 	if (leftright) {
605cc36ccd1SDavid Schultz 		if (m2 > 0)
606cc36ccd1SDavid Schultz 			mhi = lshift(mhi, m2);
607cc36ccd1SDavid Schultz 
608cc36ccd1SDavid Schultz 		/* Compute mlo -- check for special case
609cc36ccd1SDavid Schultz 		 * that d is a normalized power of 2.
610cc36ccd1SDavid Schultz 		 */
611cc36ccd1SDavid Schultz 
612cc36ccd1SDavid Schultz 		mlo = mhi;
613cc36ccd1SDavid Schultz 		if (spec_case) {
614cc36ccd1SDavid Schultz 			mhi = Balloc(mhi->k);
615cc36ccd1SDavid Schultz 			Bcopy(mhi, mlo);
616cc36ccd1SDavid Schultz 			mhi = lshift(mhi, 1);
617cc36ccd1SDavid Schultz 			}
618cc36ccd1SDavid Schultz 
619cc36ccd1SDavid Schultz 		for(i = 1;;i++) {
620cc36ccd1SDavid Schultz 			dig = quorem(b,S) + '0';
621cc36ccd1SDavid Schultz 			/* Do we yet have the shortest decimal string
622cc36ccd1SDavid Schultz 			 * that will round to d?
623cc36ccd1SDavid Schultz 			 */
624cc36ccd1SDavid Schultz 			j = cmp(b, mlo);
625cc36ccd1SDavid Schultz 			delta = diff(S, mhi);
626cc36ccd1SDavid Schultz 			j1 = delta->sign ? 1 : cmp(b, delta);
627cc36ccd1SDavid Schultz 			Bfree(delta);
628cc36ccd1SDavid Schultz #ifndef ROUND_BIASED
629cc36ccd1SDavid Schultz 			if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) {
630cc36ccd1SDavid Schultz 				if (dig == '9')
631cc36ccd1SDavid Schultz 					goto round_9_up;
632cc36ccd1SDavid Schultz 				if (j <= 0) {
633cc36ccd1SDavid Schultz 					if (b->wds > 1 || b->x[0])
634cc36ccd1SDavid Schultz 						inex = STRTOG_Inexlo;
635cc36ccd1SDavid Schultz 					}
636cc36ccd1SDavid Schultz 				else {
637cc36ccd1SDavid Schultz 					dig++;
638cc36ccd1SDavid Schultz 					inex = STRTOG_Inexhi;
639cc36ccd1SDavid Schultz 					}
640cc36ccd1SDavid Schultz 				*s++ = dig;
641cc36ccd1SDavid Schultz 				goto ret;
642cc36ccd1SDavid Schultz 				}
643cc36ccd1SDavid Schultz #endif
644*50dad48bSDavid Schultz 			if (j < 0 || (j == 0 && !mode
645cc36ccd1SDavid Schultz #ifndef ROUND_BIASED
646cc36ccd1SDavid Schultz 							&& !(bits[0] & 1)
647cc36ccd1SDavid Schultz #endif
648*50dad48bSDavid Schultz 					)) {
649cc36ccd1SDavid Schultz 				if (rdir && (b->wds > 1 || b->x[0])) {
650cc36ccd1SDavid Schultz 					if (rdir == 2) {
651cc36ccd1SDavid Schultz 						inex = STRTOG_Inexlo;
652cc36ccd1SDavid Schultz 						goto accept;
653cc36ccd1SDavid Schultz 						}
654cc36ccd1SDavid Schultz 					while (cmp(S,mhi) > 0) {
655cc36ccd1SDavid Schultz 						*s++ = dig;
656cc36ccd1SDavid Schultz 						mhi1 = multadd(mhi, 10, 0);
657cc36ccd1SDavid Schultz 						if (mlo == mhi)
658cc36ccd1SDavid Schultz 							mlo = mhi1;
659cc36ccd1SDavid Schultz 						mhi = mhi1;
660cc36ccd1SDavid Schultz 						b = multadd(b, 10, 0);
661cc36ccd1SDavid Schultz 						dig = quorem(b,S) + '0';
662cc36ccd1SDavid Schultz 						}
663cc36ccd1SDavid Schultz 					if (dig++ == '9')
664cc36ccd1SDavid Schultz 						goto round_9_up;
665cc36ccd1SDavid Schultz 					inex = STRTOG_Inexhi;
666cc36ccd1SDavid Schultz 					goto accept;
667cc36ccd1SDavid Schultz 					}
668cc36ccd1SDavid Schultz 				if (j1 > 0) {
669cc36ccd1SDavid Schultz 					b = lshift(b, 1);
670cc36ccd1SDavid Schultz 					j1 = cmp(b, S);
671*50dad48bSDavid Schultz #ifdef ROUND_BIASED
672*50dad48bSDavid Schultz 					if (j1 >= 0 /*)*/
673*50dad48bSDavid Schultz #else
674*50dad48bSDavid Schultz 					if ((j1 > 0 || (j1 == 0 && dig & 1))
675*50dad48bSDavid Schultz #endif
676cc36ccd1SDavid Schultz 					&& dig++ == '9')
677cc36ccd1SDavid Schultz 						goto round_9_up;
678cc36ccd1SDavid Schultz 					inex = STRTOG_Inexhi;
679cc36ccd1SDavid Schultz 					}
680cc36ccd1SDavid Schultz 				if (b->wds > 1 || b->x[0])
681cc36ccd1SDavid Schultz 					inex = STRTOG_Inexlo;
682cc36ccd1SDavid Schultz  accept:
683cc36ccd1SDavid Schultz 				*s++ = dig;
684cc36ccd1SDavid Schultz 				goto ret;
685cc36ccd1SDavid Schultz 				}
686cc36ccd1SDavid Schultz 			if (j1 > 0 && rdir != 2) {
687cc36ccd1SDavid Schultz 				if (dig == '9') { /* possible if i == 1 */
688cc36ccd1SDavid Schultz  round_9_up:
689cc36ccd1SDavid Schultz 					*s++ = '9';
690cc36ccd1SDavid Schultz 					inex = STRTOG_Inexhi;
691cc36ccd1SDavid Schultz 					goto roundoff;
692cc36ccd1SDavid Schultz 					}
693cc36ccd1SDavid Schultz 				inex = STRTOG_Inexhi;
694cc36ccd1SDavid Schultz 				*s++ = dig + 1;
695cc36ccd1SDavid Schultz 				goto ret;
696cc36ccd1SDavid Schultz 				}
697cc36ccd1SDavid Schultz 			*s++ = dig;
698cc36ccd1SDavid Schultz 			if (i == ilim)
699cc36ccd1SDavid Schultz 				break;
700cc36ccd1SDavid Schultz 			b = multadd(b, 10, 0);
701cc36ccd1SDavid Schultz 			if (mlo == mhi)
702cc36ccd1SDavid Schultz 				mlo = mhi = multadd(mhi, 10, 0);
703cc36ccd1SDavid Schultz 			else {
704cc36ccd1SDavid Schultz 				mlo = multadd(mlo, 10, 0);
705cc36ccd1SDavid Schultz 				mhi = multadd(mhi, 10, 0);
706cc36ccd1SDavid Schultz 				}
707cc36ccd1SDavid Schultz 			}
708cc36ccd1SDavid Schultz 		}
709cc36ccd1SDavid Schultz 	else
710cc36ccd1SDavid Schultz 		for(i = 1;; i++) {
711cc36ccd1SDavid Schultz 			*s++ = dig = quorem(b,S) + '0';
712cc36ccd1SDavid Schultz 			if (i >= ilim)
713cc36ccd1SDavid Schultz 				break;
714cc36ccd1SDavid Schultz 			b = multadd(b, 10, 0);
715cc36ccd1SDavid Schultz 			}
716cc36ccd1SDavid Schultz 
717cc36ccd1SDavid Schultz 	/* Round off last digit */
718cc36ccd1SDavid Schultz 
719cc36ccd1SDavid Schultz 	if (rdir) {
720*50dad48bSDavid Schultz 		if (rdir == 2 || (b->wds <= 1 && !b->x[0]))
721cc36ccd1SDavid Schultz 			goto chopzeros;
722cc36ccd1SDavid Schultz 		goto roundoff;
723cc36ccd1SDavid Schultz 		}
724cc36ccd1SDavid Schultz 	b = lshift(b, 1);
725cc36ccd1SDavid Schultz 	j = cmp(b, S);
726*50dad48bSDavid Schultz #ifdef ROUND_BIASED
727*50dad48bSDavid Schultz 	if (j >= 0)
728*50dad48bSDavid Schultz #else
729*50dad48bSDavid Schultz 	if (j > 0 || (j == 0 && dig & 1))
730*50dad48bSDavid Schultz #endif
731*50dad48bSDavid Schultz 		{
732cc36ccd1SDavid Schultz  roundoff:
733cc36ccd1SDavid Schultz 		inex = STRTOG_Inexhi;
734cc36ccd1SDavid Schultz 		while(*--s == '9')
735cc36ccd1SDavid Schultz 			if (s == s0) {
736cc36ccd1SDavid Schultz 				k++;
737cc36ccd1SDavid Schultz 				*s++ = '1';
738cc36ccd1SDavid Schultz 				goto ret;
739cc36ccd1SDavid Schultz 				}
740cc36ccd1SDavid Schultz 		++*s++;
741cc36ccd1SDavid Schultz 		}
742cc36ccd1SDavid Schultz 	else {
743cc36ccd1SDavid Schultz  chopzeros:
744cc36ccd1SDavid Schultz 		if (b->wds > 1 || b->x[0])
745cc36ccd1SDavid Schultz 			inex = STRTOG_Inexlo;
746cc36ccd1SDavid Schultz 		while(*--s == '0'){}
7474848dd08SDavid Schultz 		++s;
748cc36ccd1SDavid Schultz 		}
749cc36ccd1SDavid Schultz  ret:
750cc36ccd1SDavid Schultz 	Bfree(S);
751cc36ccd1SDavid Schultz 	if (mhi) {
752cc36ccd1SDavid Schultz 		if (mlo && mlo != mhi)
753cc36ccd1SDavid Schultz 			Bfree(mlo);
754cc36ccd1SDavid Schultz 		Bfree(mhi);
755cc36ccd1SDavid Schultz 		}
756cc36ccd1SDavid Schultz  ret1:
757cc36ccd1SDavid Schultz 	Bfree(b);
758cc36ccd1SDavid Schultz 	*s = 0;
759cc36ccd1SDavid Schultz 	*decpt = k + 1;
760cc36ccd1SDavid Schultz 	if (rve)
761cc36ccd1SDavid Schultz 		*rve = s;
762cc36ccd1SDavid Schultz 	*kindp |= inex;
763cc36ccd1SDavid Schultz 	return s0;
764cc36ccd1SDavid Schultz 	}
765