Home | History | Annotate | Download | only in gdtoa
      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 	if (b == NULL)
    202 		return (NULL);
    203 #ifdef Sudden_Underflow
    204 	i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
    205 #else
    206 	if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {
    207 #endif
    208 		dval(&d2) = dval(&d);
    209 		word0(&d2) &= Frac_mask1;
    210 		word0(&d2) |= Exp_11;
    211 #ifdef IBM
    212 		if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0)
    213 			dval(&d2) /= 1 << j;
    214 #endif
    215 
    216 		/* log(x)	~=~ log(1.5) + (x-1.5)/1.5
    217 		 * log10(x)	 =  log(x) / log(10)
    218 		 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
    219 		 * log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2)
    220 		 *
    221 		 * This suggests computing an approximation k to log10(&d) by
    222 		 *
    223 		 * k = (i - Bias)*0.301029995663981
    224 		 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
    225 		 *
    226 		 * We want k to be too large rather than too small.
    227 		 * The error in the first-order Taylor series approximation
    228 		 * is in our favor, so we just round up the constant enough
    229 		 * to compensate for any error in the multiplication of
    230 		 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
    231 		 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
    232 		 * adding 1e-13 to the constant term more than suffices.
    233 		 * Hence we adjust the constant term to 0.1760912590558.
    234 		 * (We could get a more accurate k by invoking log10,
    235 		 *  but this is probably not worthwhile.)
    236 		 */
    237 
    238 		i -= Bias;
    239 #ifdef IBM
    240 		i <<= 2;
    241 		i += j;
    242 #endif
    243 #ifndef Sudden_Underflow
    244 		denorm = 0;
    245 		}
    246 	else {
    247 		/* d is denormalized */
    248 
    249 		i = bbits + be + (Bias + (P-1) - 1);
    250 		x = i > 32  ? word0(&d) << (64 - i) | word1(&d) >> (i - 32)
    251 			    : word1(&d) << (32 - i);
    252 		dval(&d2) = x;
    253 		word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
    254 		i -= (Bias + (P-1) - 1) + 1;
    255 		denorm = 1;
    256 		}
    257 #endif
    258 	ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
    259 	k = (int)ds;
    260 	if (ds < 0. && ds != k)
    261 		k--;	/* want k = floor(ds) */
    262 	k_check = 1;
    263 	if (k >= 0 && k <= Ten_pmax) {
    264 		if (dval(&d) < tens[k])
    265 			k--;
    266 		k_check = 0;
    267 		}
    268 	j = bbits - i - 1;
    269 	if (j >= 0) {
    270 		b2 = 0;
    271 		s2 = j;
    272 		}
    273 	else {
    274 		b2 = -j;
    275 		s2 = 0;
    276 		}
    277 	if (k >= 0) {
    278 		b5 = 0;
    279 		s5 = k;
    280 		s2 += k;
    281 		}
    282 	else {
    283 		b2 -= k;
    284 		b5 = -k;
    285 		s5 = 0;
    286 		}
    287 	if (mode < 0 || mode > 9)
    288 		mode = 0;
    289 
    290 #ifndef SET_INEXACT
    291 #ifdef Check_FLT_ROUNDS
    292 	try_quick = Rounding == 1;
    293 #else
    294 	try_quick = 1;
    295 #endif
    296 #endif /*SET_INEXACT*/
    297 
    298 	if (mode > 5) {
    299 		mode -= 4;
    300 		try_quick = 0;
    301 		}
    302 	leftright = 1;
    303 	ilim = ilim1 = -1;	/* Values for cases 0 and 1; done here to */
    304 				/* silence erroneous "gcc -Wall" warning. */
    305 	switch(mode) {
    306 		case 0:
    307 		case 1:
    308 			i = 18;
    309 			ndigits = 0;
    310 			break;
    311 		case 2:
    312 			leftright = 0;
    313 			/* no break */
    314 		case 4:
    315 			if (ndigits <= 0)
    316 				ndigits = 1;
    317 			ilim = ilim1 = i = ndigits;
    318 			break;
    319 		case 3:
    320 			leftright = 0;
    321 			/* no break */
    322 		case 5:
    323 			i = ndigits + k + 1;
    324 			ilim = i;
    325 			ilim1 = i - 1;
    326 			if (i <= 0)
    327 				i = 1;
    328 		}
    329 	s = s0 = rv_alloc(i);
    330 	if (s == NULL)
    331 		return (NULL);
    332 
    333 #ifdef Honor_FLT_ROUNDS
    334 	if (mode > 1 && Rounding != 1)
    335 		leftright = 0;
    336 #endif
    337 
    338 	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
    339 
    340 		/* Try to get by with floating-point arithmetic. */
    341 
    342 		i = 0;
    343 		dval(&d2) = dval(&d);
    344 		k0 = k;
    345 		ilim0 = ilim;
    346 		ieps = 2; /* conservative */
    347 		if (k > 0) {
    348 			ds = tens[k&0xf];
    349 			j = k >> 4;
    350 			if (j & Bletch) {
    351 				/* prevent overflows */
    352 				j &= Bletch - 1;
    353 				dval(&d) /= bigtens[n_bigtens-1];
    354 				ieps++;
    355 				}
    356 			for(; j; j >>= 1, i++)
    357 				if (j & 1) {
    358 					ieps++;
    359 					ds *= bigtens[i];
    360 					}
    361 			dval(&d) /= ds;
    362 			}
    363 		else if (( j1 = -k )!=0) {
    364 			dval(&d) *= tens[j1 & 0xf];
    365 			for(j = j1 >> 4; j; j >>= 1, i++)
    366 				if (j & 1) {
    367 					ieps++;
    368 					dval(&d) *= bigtens[i];
    369 					}
    370 			}
    371 		if (k_check && dval(&d) < 1. && ilim > 0) {
    372 			if (ilim1 <= 0)
    373 				goto fast_failed;
    374 			ilim = ilim1;
    375 			k--;
    376 			dval(&d) *= 10.;
    377 			ieps++;
    378 			}
    379 		dval(&eps) = ieps*dval(&d) + 7.;
    380 		word0(&eps) -= (P-1)*Exp_msk1;
    381 		if (ilim == 0) {
    382 			S = mhi = 0;
    383 			dval(&d) -= 5.;
    384 			if (dval(&d) > dval(&eps))
    385 				goto one_digit;
    386 			if (dval(&d) < -dval(&eps))
    387 				goto no_digits;
    388 			goto fast_failed;
    389 			}
    390 #ifndef No_leftright
    391 		if (leftright) {
    392 			/* Use Steele & White method of only
    393 			 * generating digits needed.
    394 			 */
    395 			dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
    396 			for(i = 0;;) {
    397 				L = dval(&d);
    398 				dval(&d) -= L;
    399 				*s++ = '0' + (int)L;
    400 				if (dval(&d) < dval(&eps))
    401 					goto ret1;
    402 				if (1. - dval(&d) < dval(&eps))
    403 					goto bump_up;
    404 				if (++i >= ilim)
    405 					break;
    406 				dval(&eps) *= 10.;
    407 				dval(&d) *= 10.;
    408 				}
    409 			}
    410 		else {
    411 #endif
    412 			/* Generate ilim digits, then fix them up. */
    413 			dval(&eps) *= tens[ilim-1];
    414 			for(i = 1;; i++, dval(&d) *= 10.) {
    415 				L = (Long)(dval(&d));
    416 				if (!(dval(&d) -= L))
    417 					ilim = i;
    418 				*s++ = '0' + (int)L;
    419 				if (i == ilim) {
    420 					if (dval(&d) > 0.5 + dval(&eps))
    421 						goto bump_up;
    422 					else if (dval(&d) < 0.5 - dval(&eps)) {
    423 						while(*--s == '0');
    424 						s++;
    425 						goto ret1;
    426 						}
    427 					break;
    428 					}
    429 				}
    430 #ifndef No_leftright
    431 			}
    432 #endif
    433  fast_failed:
    434 		s = s0;
    435 		dval(&d) = dval(&d2);
    436 		k = k0;
    437 		ilim = ilim0;
    438 		}
    439 
    440 	/* Do we have a "small" integer? */
    441 
    442 	if (be >= 0 && k <= Int_max) {
    443 		/* Yes. */
    444 		ds = tens[k];
    445 		if (ndigits < 0 && ilim <= 0) {
    446 			S = mhi = 0;
    447 			if (ilim < 0 || dval(&d) <= 5*ds)
    448 				goto no_digits;
    449 			goto one_digit;
    450 			}
    451 		for(i = 1;; i++, dval(&d) *= 10.) {
    452 			L = (Long)(dval(&d) / ds);
    453 			dval(&d) -= L*ds;
    454 #ifdef Check_FLT_ROUNDS
    455 			/* If FLT_ROUNDS == 2, L will usually be high by 1 */
    456 			if (dval(&d) < 0) {
    457 				L--;
    458 				dval(&d) += ds;
    459 				}
    460 #endif
    461 			*s++ = '0' + (int)L;
    462 			if (!dval(&d)) {
    463 #ifdef SET_INEXACT
    464 				inexact = 0;
    465 #endif
    466 				break;
    467 				}
    468 			if (i == ilim) {
    469 #ifdef Honor_FLT_ROUNDS
    470 				if (mode > 1)
    471 				switch(Rounding) {
    472 				  case 0: goto ret1;
    473 				  case 2: goto bump_up;
    474 				  }
    475 #endif
    476 				dval(&d) += dval(&d);
    477 #ifdef ROUND_BIASED
    478 				if (dval(&d) >= ds)
    479 #else
    480 				if (dval(&d) > ds || (dval(&d) == ds && L & 1))
    481 #endif
    482 					{
    483  bump_up:
    484 					while(*--s == '9')
    485 						if (s == s0) {
    486 							k++;
    487 							*s = '0';
    488 							break;
    489 							}
    490 					++*s++;
    491 					}
    492 				break;
    493 				}
    494 			}
    495 		goto ret1;
    496 		}
    497 
    498 	m2 = b2;
    499 	m5 = b5;
    500 	mhi = mlo = 0;
    501 	if (leftright) {
    502 		i =
    503 #ifndef Sudden_Underflow
    504 			denorm ? be + (Bias + (P-1) - 1 + 1) :
    505 #endif
    506 #ifdef IBM
    507 			1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
    508 #else
    509 			1 + P - bbits;
    510 #endif
    511 		b2 += i;
    512 		s2 += i;
    513 		mhi = i2b(1);
    514 		if (mhi == NULL)
    515 			return (NULL);
    516 		}
    517 	if (m2 > 0 && s2 > 0) {
    518 		i = m2 < s2 ? m2 : s2;
    519 		b2 -= i;
    520 		m2 -= i;
    521 		s2 -= i;
    522 		}
    523 	if (b5 > 0) {
    524 		if (leftright) {
    525 			if (m5 > 0) {
    526 				mhi = pow5mult(mhi, m5);
    527 				if (mhi == NULL)
    528 					return (NULL);
    529 				b1 = mult(mhi, b);
    530 				if (b1 == NULL)
    531 					return (NULL);
    532 				Bfree(b);
    533 				b = b1;
    534 				}
    535 			if (( j = b5 - m5 )!=0) {
    536 				b = pow5mult(b, j);
    537 				if (b == NULL)
    538 					return (NULL);
    539 				}
    540 			}
    541 		else {
    542 			b = pow5mult(b, b5);
    543 			if (b == NULL)
    544 				return (NULL);
    545 			}
    546 		}
    547 	S = i2b(1);
    548 	if (S == NULL)
    549 		return (NULL);
    550 	if (s5 > 0) {
    551 		S = pow5mult(S, s5);
    552 		if (S == NULL)
    553 			return (NULL);
    554 		}
    555 
    556 	/* Check for special case that d is a normalized power of 2. */
    557 
    558 	spec_case = 0;
    559 	if ((mode < 2 || leftright)
    560 #ifdef Honor_FLT_ROUNDS
    561 			&& Rounding == 1
    562 #endif
    563 				) {
    564 		if (!word1(&d) && !(word0(&d) & Bndry_mask)
    565 #ifndef Sudden_Underflow
    566 		 && word0(&d) & (Exp_mask & ~Exp_msk1)
    567 #endif
    568 				) {
    569 			/* The special case */
    570 			b2 += Log2P;
    571 			s2 += Log2P;
    572 			spec_case = 1;
    573 			}
    574 		}
    575 
    576 	/* Arrange for convenient computation of quotients:
    577 	 * shift left if necessary so divisor has 4 leading 0 bits.
    578 	 *
    579 	 * Perhaps we should just compute leading 28 bits of S once
    580 	 * and for all and pass them and a shift to quorem, so it
    581 	 * can do shifts and ors to compute the numerator for q.
    582 	 */
    583 #ifdef Pack_32
    584 	if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)
    585 		i = 32 - i;
    586 #else
    587 	if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)
    588 		i = 16 - i;
    589 #endif
    590 	if (i > 4) {
    591 		i -= 4;
    592 		b2 += i;
    593 		m2 += i;
    594 		s2 += i;
    595 		}
    596 	else if (i < 4) {
    597 		i += 28;
    598 		b2 += i;
    599 		m2 += i;
    600 		s2 += i;
    601 		}
    602 	if (b2 > 0) {
    603 		b = lshift(b, b2);
    604 		if (b == NULL)
    605 			return (NULL);
    606 		}
    607 	if (s2 > 0) {
    608 		S = lshift(S, s2);
    609 		if (S == NULL)
    610 			return (NULL);
    611 		}
    612 	if (k_check) {
    613 		if (cmp(b,S) < 0) {
    614 			k--;
    615 			b = multadd(b, 10, 0);	/* we botched the k estimate */
    616 			if (b == NULL)
    617 				return (NULL);
    618 			if (leftright) {
    619 				mhi = multadd(mhi, 10, 0);
    620 				if (mhi == NULL)
    621 					return (NULL);
    622 				}
    623 			ilim = ilim1;
    624 			}
    625 		}
    626 	if (ilim <= 0 && (mode == 3 || mode == 5)) {
    627 		S = multadd(S,5,0);
    628 		if (S == NULL)
    629 			return (NULL);
    630 		if (ilim < 0 || cmp(b,S) <= 0) {
    631 			/* no digits, fcvt style */
    632  no_digits:
    633 			k = -1 - ndigits;
    634 			goto ret;
    635 			}
    636  one_digit:
    637 		*s++ = '1';
    638 		k++;
    639 		goto ret;
    640 		}
    641 	if (leftright) {
    642 		if (m2 > 0) {
    643 			mhi = lshift(mhi, m2);
    644 			if (mhi == NULL)
    645 				return (NULL);
    646 			}
    647 
    648 		/* Compute mlo -- check for special case
    649 		 * that d is a normalized power of 2.
    650 		 */
    651 
    652 		mlo = mhi;
    653 		if (spec_case) {
    654 			mhi = Balloc(mhi->k);
    655 			if (mhi == NULL)
    656 				return (NULL);
    657 			Bcopy(mhi, mlo);
    658 			mhi = lshift(mhi, Log2P);
    659 			if (mhi == NULL)
    660 				return (NULL);
    661 			}
    662 
    663 		for(i = 1;;i++) {
    664 			dig = quorem(b,S) + '0';
    665 			/* Do we yet have the shortest decimal string
    666 			 * that will round to d?
    667 			 */
    668 			j = cmp(b, mlo);
    669 			delta = diff(S, mhi);
    670 			if (delta == NULL)
    671 				return (NULL);
    672 			j1 = delta->sign ? 1 : cmp(b, delta);
    673 			Bfree(delta);
    674 #ifndef ROUND_BIASED
    675 			if (j1 == 0 && mode != 1 && !(word1(&d) & 1)
    676 #ifdef Honor_FLT_ROUNDS
    677 				&& Rounding >= 1
    678 #endif
    679 								   ) {
    680 				if (dig == '9')
    681 					goto round_9_up;
    682 				if (j > 0)
    683 					dig++;
    684 #ifdef SET_INEXACT
    685 				else if (!b->x[0] && b->wds <= 1)
    686 					inexact = 0;
    687 #endif
    688 				*s++ = dig;
    689 				goto ret;
    690 				}
    691 #endif
    692 			if (j < 0 || (j == 0 && mode != 1
    693 #ifndef ROUND_BIASED
    694 							&& !(word1(&d) & 1)
    695 #endif
    696 					)) {
    697 				if (!b->x[0] && b->wds <= 1) {
    698 #ifdef SET_INEXACT
    699 					inexact = 0;
    700 #endif
    701 					goto accept_dig;
    702 					}
    703 #ifdef Honor_FLT_ROUNDS
    704 				if (mode > 1)
    705 				 switch(Rounding) {
    706 				  case 0: goto accept_dig;
    707 				  case 2: goto keep_dig;
    708 				  }
    709 #endif /*Honor_FLT_ROUNDS*/
    710 				if (j1 > 0) {
    711 					b = lshift(b, 1);
    712 					if (b == NULL)
    713 						return (NULL);
    714 					j1 = cmp(b, S);
    715 #ifdef ROUND_BIASED
    716 					if (j1 >= 0 /*)*/
    717 #else
    718 					if ((j1 > 0 || (j1 == 0 && dig & 1))
    719 #endif
    720 					&& dig++ == '9')
    721 						goto round_9_up;
    722 					}
    723  accept_dig:
    724 				*s++ = dig;
    725 				goto ret;
    726 				}
    727 			if (j1 > 0) {
    728 #ifdef Honor_FLT_ROUNDS
    729 				if (!Rounding)
    730 					goto accept_dig;
    731 #endif
    732 				if (dig == '9') { /* possible if i == 1 */
    733  round_9_up:
    734 					*s++ = '9';
    735 					goto roundoff;
    736 					}
    737 				*s++ = dig + 1;
    738 				goto ret;
    739 				}
    740 #ifdef Honor_FLT_ROUNDS
    741  keep_dig:
    742 #endif
    743 			*s++ = dig;
    744 			if (i == ilim)
    745 				break;
    746 			b = multadd(b, 10, 0);
    747 			if (b == NULL)
    748 				return (NULL);
    749 			if (mlo == mhi) {
    750 				mlo = mhi = multadd(mhi, 10, 0);
    751 				if (mlo == NULL)
    752 					return (NULL);
    753 				}
    754 			else {
    755 				mlo = multadd(mlo, 10, 0);
    756 				if (mlo == NULL)
    757 					return (NULL);
    758 				mhi = multadd(mhi, 10, 0);
    759 				if (mhi == NULL)
    760 					return (NULL);
    761 				}
    762 			}
    763 		}
    764 	else
    765 		for(i = 1;; i++) {
    766 			*s++ = dig = quorem(b,S) + '0';
    767 			if (!b->x[0] && b->wds <= 1) {
    768 #ifdef SET_INEXACT
    769 				inexact = 0;
    770 #endif
    771 				goto ret;
    772 				}
    773 			if (i >= ilim)
    774 				break;
    775 			b = multadd(b, 10, 0);
    776 			if (b == NULL)
    777 				return (NULL);
    778 			}
    779 
    780 	/* Round off last digit */
    781 
    782 #ifdef Honor_FLT_ROUNDS
    783 	switch(Rounding) {
    784 	  case 0: goto trimzeros;
    785 	  case 2: goto roundoff;
    786 	  }
    787 #endif
    788 	b = lshift(b, 1);
    789 	if (b == NULL)
    790 		return (NULL);
    791 	j = cmp(b, S);
    792 #ifdef ROUND_BIASED
    793 	if (j >= 0)
    794 #else
    795 	if (j > 0 || (j == 0 && dig & 1))
    796 #endif
    797 		{
    798  roundoff:
    799 		while(*--s == '9')
    800 			if (s == s0) {
    801 				k++;
    802 				*s++ = '1';
    803 				goto ret;
    804 				}
    805 		++*s++;
    806 		}
    807 	else {
    808 #ifdef Honor_FLT_ROUNDS
    809  trimzeros:
    810 #endif
    811 		while(*--s == '0');
    812 		s++;
    813 		}
    814  ret:
    815 	Bfree(S);
    816 	if (mhi) {
    817 		if (mlo && mlo != mhi)
    818 			Bfree(mlo);
    819 		Bfree(mhi);
    820 		}
    821  ret1:
    822 #ifdef SET_INEXACT
    823 	if (inexact) {
    824 		if (!oldinexact) {
    825 			word0(&d) = Exp_1 + (70 << Exp_shift);
    826 			word1(&d) = 0;
    827 			dval(&d) += 1.;
    828 			}
    829 		}
    830 	else if (!oldinexact)
    831 		clear_inexact();
    832 #endif
    833 	Bfree(b);
    834 	*s = 0;
    835 	*decpt = k + 1;
    836 	if (rve)
    837 		*rve = s;
    838 	return s0;
    839 	}
    840 DEF_STRONG(dtoa);
    841