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