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