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