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