xref: /netbsd-src/lib/libc/gdtoa/strtod.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /* $NetBSD: strtod.c,v 1.4 2006/06/02 19:46:56 mrg Exp $ */
2 
3 /****************************************************************
4 
5 The author of this software is David M. Gay.
6 
7 Copyright (C) 1998-2001 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 #ifndef NO_FENV_H
36 #include <fenv.h>
37 #endif
38 
39 #ifdef USE_LOCALE
40 #include "locale.h"
41 #endif
42 
43 #ifdef IEEE_Arith
44 #ifndef NO_IEEE_Scale
45 #define Avoid_Underflow
46 #undef tinytens
47 /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
48 /* flag unnecessarily.  It leads to a song and dance at the end of strtod. */
49 static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
50 		9007199254740992.e-256
51 		};
52 #endif
53 #endif
54 
55 #ifdef Honor_FLT_ROUNDS
56 #define Rounding rounding
57 #undef Check_FLT_ROUNDS
58 #define Check_FLT_ROUNDS
59 #else
60 #define Rounding Flt_Rounds
61 #endif
62 
63 #ifndef __HAVE_LONG_DOUBLE
64 __strong_alias(_strtold, strtod)
65 __weak_alias(strtold, _strtold)
66 #endif
67 
68  double
69 strtod
70 #ifdef KR_headers
71 	(s00, se) CONST char *s00; char **se;
72 #else
73 	(CONST char *s00, char **se)
74 #endif
75 {
76 #ifdef Avoid_Underflow
77 	int scale;
78 #endif
79 	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
80 		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
81 	CONST char *s, *s0, *s1;
82 	double aadj, aadj1, adj, rv, rv0;
83 	Long L;
84 	ULong y, z;
85 	Bigint *bb = NULL, *bb1, *bd0;
86 	Bigint *bd = NULL, *bs = NULL, *delta = NULL; /* pacify gcc */
87 #ifdef SET_INEXACT
88 	int inexact, oldinexact;
89 #endif
90 #ifdef Honor_FLT_ROUNDS
91 	int rounding;
92 #endif
93 
94 	sign = nz0 = nz = decpt = 0;
95 	dval(rv) = 0.;
96 	for(s = s00;;s++) switch(*s) {
97 		case '-':
98 			sign = 1;
99 			/* FALLTHROUGH */
100 		case '+':
101 			if (*++s)
102 				goto break2;
103 			/* FALLTHROUGH */
104 		case 0:
105 			goto ret0;
106 		case '\t':
107 		case '\n':
108 		case '\v':
109 		case '\f':
110 		case '\r':
111 		case ' ':
112 			continue;
113 		default:
114 			goto break2;
115 		}
116  break2:
117 	if (*s == '0') {
118 #ifndef NO_HEX_FP
119 		{
120 		static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
121 		Long expt;
122 		ULong bits[2];
123 		switch(s[1]) {
124 		  case 'x':
125 		  case 'X':
126 			{
127 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
128 			FPI fpi1 = fpi;
129 			switch(fegetround()) {
130 			  case FE_TOWARDZERO:	fpi1.rounding = 0; break;
131 			  case FE_UPWARD:	fpi1.rounding = 2; break;
132 			  case FE_DOWNWARD:	fpi1.rounding = 3;
133 			  }
134 #else
135 #define fpi1 fpi
136 #endif
137 			switch((i = gethex(&s, &fpi1, &expt, &bb, sign)) & STRTOG_Retmask) {
138 			  case STRTOG_NoNumber:
139 				s = s00;
140 				sign = 0;
141 				/* FALLTHROUGH */
142 			  case STRTOG_Zero:
143 				break;
144 			  default:
145 				if (bb) {
146 					copybits(bits, fpi.nbits, bb);
147 					Bfree(bb);
148 					}
149 				ULtod((/* LINTED */(U*)&rv)->L, bits, expt, i);
150 			  }}
151 			goto ret;
152 		  }
153 		}
154 #endif
155 		nz0 = 1;
156 		while(*++s == '0') ;
157 		if (!*s)
158 			goto ret;
159 		}
160 	s0 = s;
161 	y = z = 0;
162 	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
163 		if (nd < 9)
164 			y = 10*y + c - '0';
165 		else if (nd < 16)
166 			z = 10*z + c - '0';
167 	nd0 = nd;
168 #ifdef USE_LOCALE
169 	if (c == *localeconv()->decimal_point)
170 #else
171 	if (c == '.')
172 #endif
173 		{
174 		decpt = 1;
175 		c = *++s;
176 		if (!nd) {
177 			for(; c == '0'; c = *++s)
178 				nz++;
179 			if (c > '0' && c <= '9') {
180 				s0 = s;
181 				nf += nz;
182 				nz = 0;
183 				goto have_dig;
184 				}
185 			goto dig_done;
186 			}
187 		for(; c >= '0' && c <= '9'; c = *++s) {
188  have_dig:
189 			nz++;
190 			if (c -= '0') {
191 				nf += nz;
192 				for(i = 1; i < nz; i++)
193 					if (nd++ < 9)
194 						y *= 10;
195 					else if (nd <= DBL_DIG + 1)
196 						z *= 10;
197 				if (nd++ < 9)
198 					y = 10*y + c;
199 				else if (nd <= DBL_DIG + 1)
200 					z = 10*z + c;
201 				nz = 0;
202 				}
203 			}
204 		}
205  dig_done:
206 	e = 0;
207 	if (c == 'e' || c == 'E') {
208 		if (!nd && !nz && !nz0) {
209 			goto ret0;
210 			}
211 		s00 = s;
212 		esign = 0;
213 		switch(c = *++s) {
214 			case '-':
215 				esign = 1;
216 				/* FALLTHROUGH */
217 			case '+':
218 				c = *++s;
219 			}
220 		if (c >= '0' && c <= '9') {
221 			while(c == '0')
222 				c = *++s;
223 			if (c > '0' && c <= '9') {
224 				L = c - '0';
225 				s1 = s;
226 				while((c = *++s) >= '0' && c <= '9')
227 					L = 10*L + c - '0';
228 				if (s - s1 > 8 || L > 19999)
229 					/* Avoid confusion from exponents
230 					 * so large that e might overflow.
231 					 */
232 					e = 19999; /* safe for 16 bit ints */
233 				else
234 					e = (int)L;
235 				if (esign)
236 					e = -e;
237 				}
238 			else
239 				e = 0;
240 			}
241 		else
242 			s = s00;
243 		}
244 	if (!nd) {
245 		if (!nz && !nz0) {
246 #ifdef INFNAN_CHECK
247 			/* Check for Nan and Infinity */
248 			ULong bits[2];
249 			static FPI fpinan =	/* only 52 explicit bits */
250 				{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
251 			if (!decpt)
252 			 switch(c) {
253 			  case 'i':
254 			  case 'I':
255 				if (match(&s,"nf")) {
256 					--s;
257 					if (!match(&s,"inity"))
258 						++s;
259 					word0(rv) = 0x7ff00000;
260 					word1(rv) = 0;
261 					goto ret;
262 					}
263 				break;
264 			  case 'n':
265 			  case 'N':
266 				if (match(&s, "an")) {
267 #ifndef No_Hex_NaN
268 					if (*s == '(' /*)*/
269 					 && hexnan(&s, &fpinan, bits)
270 							== STRTOG_NaNbits) {
271 						word0(rv) = 0x7ff00000 | bits[1];
272 						word1(rv) = bits[0];
273 						}
274 					else {
275 #endif
276 						word0(rv) = NAN_WORD0;
277 						word1(rv) = NAN_WORD1;
278 #ifndef No_Hex_NaN
279 						}
280 #endif
281 					goto ret;
282 					}
283 			  }
284 #endif /* INFNAN_CHECK */
285  ret0:
286 			s = s00;
287 			sign = 0;
288 			}
289 		goto ret;
290 		}
291 	e1 = e -= nf;
292 
293 	/* Now we have nd0 digits, starting at s0, followed by a
294 	 * decimal point, followed by nd-nd0 digits.  The number we're
295 	 * after is the integer represented by those digits times
296 	 * 10**e */
297 
298 	if (!nd0)
299 		nd0 = nd;
300 	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
301 	dval(rv) = y;
302 	if (k > 9) {
303 #ifdef SET_INEXACT
304 		if (k > DBL_DIG)
305 			oldinexact = get_inexact();
306 #endif
307 		dval(rv) = tens[k - 9] * dval(rv) + z;
308 		}
309 	bd0 = 0;
310 	if (nd <= DBL_DIG
311 #ifndef RND_PRODQUOT
312 #ifndef Honor_FLT_ROUNDS
313 		&& Flt_Rounds == 1
314 #endif
315 #endif
316 			) {
317 		if (!e)
318 			goto ret;
319 		if (e > 0) {
320 			if (e <= Ten_pmax) {
321 #ifdef VAX
322 				goto vax_ovfl_check;
323 #else
324 #ifdef Honor_FLT_ROUNDS
325 				/* round correctly FLT_ROUNDS = 2 or 3 */
326 				if (sign) {
327 					rv = -rv;
328 					sign = 0;
329 					}
330 #endif
331 				/* rv = */ rounded_product(dval(rv), tens[e]);
332 				goto ret;
333 #endif
334 				}
335 			i = DBL_DIG - nd;
336 			if (e <= Ten_pmax + i) {
337 				/* A fancier test would sometimes let us do
338 				 * this for larger i values.
339 				 */
340 #ifdef Honor_FLT_ROUNDS
341 				/* round correctly FLT_ROUNDS = 2 or 3 */
342 				if (sign) {
343 					rv = -rv;
344 					sign = 0;
345 					}
346 #endif
347 				e -= i;
348 				dval(rv) *= tens[i];
349 #ifdef VAX
350 				/* VAX exponent range is so narrow we must
351 				 * worry about overflow here...
352 				 */
353  vax_ovfl_check:
354 				word0(rv) -= P*Exp_msk1;
355 				/* rv = */ rounded_product(dval(rv), tens[e]);
356 				if ((word0(rv) & Exp_mask)
357 				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
358 					goto ovfl;
359 				word0(rv) += P*Exp_msk1;
360 #else
361 				/* rv = */ rounded_product(dval(rv), tens[e]);
362 #endif
363 				goto ret;
364 				}
365 			}
366 #ifndef Inaccurate_Divide
367 		else if (e >= -Ten_pmax) {
368 #ifdef Honor_FLT_ROUNDS
369 			/* round correctly FLT_ROUNDS = 2 or 3 */
370 			if (sign) {
371 				rv = -rv;
372 				sign = 0;
373 				}
374 #endif
375 			/* rv = */ rounded_quotient(dval(rv), tens[-e]);
376 			goto ret;
377 			}
378 #endif
379 		}
380 	e1 += nd - k;
381 
382 #ifdef IEEE_Arith
383 #ifdef SET_INEXACT
384 	inexact = 1;
385 	if (k <= DBL_DIG)
386 		oldinexact = get_inexact();
387 #endif
388 #ifdef Avoid_Underflow
389 	scale = 0;
390 #endif
391 #ifdef Honor_FLT_ROUNDS
392 	if ((rounding = Flt_Rounds) >= 2) {
393 		if (sign)
394 			rounding = rounding == 2 ? 0 : 2;
395 		else
396 			if (rounding != 2)
397 				rounding = 0;
398 		}
399 #endif
400 #endif /*IEEE_Arith*/
401 
402 	/* Get starting approximation = rv * 10**e1 */
403 
404 	if (e1 > 0) {
405 		if ( (i = e1 & 15) !=0)
406 			dval(rv) *= tens[i];
407 		if (e1 &= ~15) {
408 			if (e1 > DBL_MAX_10_EXP) {
409  ovfl:
410 #ifndef NO_ERRNO
411 				errno = ERANGE;
412 #endif
413 				/* Can't trust HUGE_VAL */
414 #ifdef IEEE_Arith
415 #ifdef Honor_FLT_ROUNDS
416 				switch(rounding) {
417 				  case 0: /* toward 0 */
418 				  case 3: /* toward -infinity */
419 					word0(rv) = Big0;
420 					word1(rv) = Big1;
421 					break;
422 				  default:
423 					word0(rv) = Exp_mask;
424 					word1(rv) = 0;
425 				  }
426 #else /*Honor_FLT_ROUNDS*/
427 				word0(rv) = Exp_mask;
428 				word1(rv) = 0;
429 #endif /*Honor_FLT_ROUNDS*/
430 #ifdef SET_INEXACT
431 				/* set overflow bit */
432 				dval(rv0) = 1e300;
433 				dval(rv0) *= dval(rv0);
434 #endif
435 #else /*IEEE_Arith*/
436 				word0(rv) = Big0;
437 				word1(rv) = Big1;
438 #endif /*IEEE_Arith*/
439 				if (bd0)
440 					goto retfree;
441 				goto ret;
442 				}
443 			e1 = (unsigned int)e1 >> 4;
444 			for(j = 0; e1 > 1; j++, e1 = (unsigned int)e1 >> 1)
445 				if (e1 & 1)
446 					dval(rv) *= bigtens[j];
447 		/* The last multiplication could overflow. */
448 			word0(rv) -= P*Exp_msk1;
449 			dval(rv) *= bigtens[j];
450 			if ((z = word0(rv) & Exp_mask)
451 			 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
452 				goto ovfl;
453 			if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
454 				/* set to largest number */
455 				/* (Can't trust DBL_MAX) */
456 				word0(rv) = Big0;
457 				word1(rv) = Big1;
458 				}
459 			else
460 				word0(rv) += P*Exp_msk1;
461 			}
462 		}
463 	else if (e1 < 0) {
464 		e1 = -e1;
465 		if ( (i = e1 & 15) !=0)
466 			dval(rv) /= tens[i];
467 		if (e1 >>= 4) {
468 			if (e1 >= 1 << n_bigtens)
469 				goto undfl;
470 #ifdef Avoid_Underflow
471 			if (e1 & Scale_Bit)
472 				scale = 2*P;
473 			for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
474 				if (e1 & 1)
475 					dval(rv) *= tinytens[j];
476 			if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
477 						>> Exp_shift)) > 0) {
478 				/* scaled rv is denormal; zap j low bits */
479 				if (j >= 32) {
480 					word1(rv) = 0;
481 					if (j >= 53)
482 					 word0(rv) = (P+2)*Exp_msk1;
483 					else
484 					 word0(rv) &= 0xffffffff << (j-32);
485 					}
486 				else
487 					word1(rv) &= 0xffffffff << j;
488 				}
489 #else
490 			for(j = 0; e1 > 1; j++, e1 >>= 1)
491 				if (e1 & 1)
492 					dval(rv) *= tinytens[j];
493 			/* The last multiplication could underflow. */
494 			dval(rv0) = dval(rv);
495 			dval(rv) *= tinytens[j];
496 			if (!dval(rv)) {
497 				dval(rv) = 2.*dval(rv0);
498 				dval(rv) *= tinytens[j];
499 #endif
500 				if (!dval(rv)) {
501  undfl:
502 					dval(rv) = 0.;
503 #ifndef NO_ERRNO
504 					errno = ERANGE;
505 #endif
506 					if (bd0)
507 						goto retfree;
508 					goto ret;
509 					}
510 #ifndef Avoid_Underflow
511 				word0(rv) = Tiny0;
512 				word1(rv) = Tiny1;
513 				/* The refinement below will clean
514 				 * this approximation up.
515 				 */
516 				}
517 #endif
518 			}
519 		}
520 
521 	/* Now the hard part -- adjusting rv to the correct value.*/
522 
523 	/* Put digits into bd: true value = bd * 10^e */
524 
525 	bd0 = s2b(s0, nd0, nd, y);
526 
527 	for(;;) {
528 		bd = Balloc(bd0->k);
529 		Bcopy(bd, bd0);
530 		bb = d2b(dval(rv), &bbe, &bbbits);	/* rv = bb * 2^bbe */
531 		bs = i2b(1);
532 
533 		if (e >= 0) {
534 			bb2 = bb5 = 0;
535 			bd2 = bd5 = e;
536 			}
537 		else {
538 			bb2 = bb5 = -e;
539 			bd2 = bd5 = 0;
540 			}
541 		if (bbe >= 0)
542 			bb2 += bbe;
543 		else
544 			bd2 -= bbe;
545 		bs2 = bb2;
546 #ifdef Honor_FLT_ROUNDS
547 		if (rounding != 1)
548 			bs2++;
549 #endif
550 #ifdef Avoid_Underflow
551 		j = bbe - scale;
552 		i = j + bbbits - 1;	/* logb(rv) */
553 		if (i < Emin)	/* denormal */
554 			j += P - Emin;
555 		else
556 			j = P + 1 - bbbits;
557 #else /*Avoid_Underflow*/
558 #ifdef Sudden_Underflow
559 #ifdef IBM
560 		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
561 #else
562 		j = P + 1 - bbbits;
563 #endif
564 #else /*Sudden_Underflow*/
565 		j = bbe;
566 		i = j + bbbits - 1;	/* logb(rv) */
567 		if (i < Emin)	/* denormal */
568 			j += P - Emin;
569 		else
570 			j = P + 1 - bbbits;
571 #endif /*Sudden_Underflow*/
572 #endif /*Avoid_Underflow*/
573 		bb2 += j;
574 		bd2 += j;
575 #ifdef Avoid_Underflow
576 		bd2 += scale;
577 #endif
578 		i = bb2 < bd2 ? bb2 : bd2;
579 		if (i > bs2)
580 			i = bs2;
581 		if (i > 0) {
582 			bb2 -= i;
583 			bd2 -= i;
584 			bs2 -= i;
585 			}
586 		if (bb5 > 0) {
587 			bs = pow5mult(bs, bb5);
588 			bb1 = mult(bs, bb);
589 			Bfree(bb);
590 			bb = bb1;
591 			}
592 		if (bb2 > 0)
593 			bb = lshift(bb, bb2);
594 		if (bd5 > 0)
595 			bd = pow5mult(bd, bd5);
596 		if (bd2 > 0)
597 			bd = lshift(bd, bd2);
598 		if (bs2 > 0)
599 			bs = lshift(bs, bs2);
600 		delta = diff(bb, bd);
601 		dsign = delta->sign;
602 		delta->sign = 0;
603 		i = cmp(delta, bs);
604 #ifdef Honor_FLT_ROUNDS
605 		if (rounding != 1) {
606 			if (i < 0) {
607 				/* Error is less than an ulp */
608 				if (!delta->x[0] && delta->wds <= 1) {
609 					/* exact */
610 #ifdef SET_INEXACT
611 					inexact = 0;
612 #endif
613 					break;
614 					}
615 				if (rounding) {
616 					if (dsign) {
617 						adj = 1.;
618 						goto apply_adj;
619 						}
620 					}
621 				else if (!dsign) {
622 					adj = -1.;
623 					if (!word1(rv)
624 					 && !(word0(rv) & Frac_mask)) {
625 						y = word0(rv) & Exp_mask;
626 #ifdef Avoid_Underflow
627 						if (!scale || y > 2*P*Exp_msk1)
628 #else
629 						if (y)
630 #endif
631 						  {
632 						  delta = lshift(delta,Log2P);
633 						  if (cmp(delta, bs) <= 0)
634 							adj = -0.5;
635 						  }
636 						}
637  apply_adj:
638 #ifdef Avoid_Underflow
639 					if (scale && (y = word0(rv) & Exp_mask)
640 						<= 2*P*Exp_msk1)
641 					  word0(adj) += (2*P+1)*Exp_msk1 - y;
642 #else
643 #ifdef Sudden_Underflow
644 					if ((word0(rv) & Exp_mask) <=
645 							P*Exp_msk1) {
646 						word0(rv) += P*Exp_msk1;
647 						dval(rv) += adj*ulp(dval(rv));
648 						word0(rv) -= P*Exp_msk1;
649 						}
650 					else
651 #endif /*Sudden_Underflow*/
652 #endif /*Avoid_Underflow*/
653 					dval(rv) += adj*ulp(dval(rv));
654 					}
655 				break;
656 				}
657 			adj = ratio(delta, bs);
658 			if (adj < 1.)
659 				adj = 1.;
660 			if (adj <= 0x7ffffffe) {
661 				/* adj = rounding ? ceil(adj) : floor(adj); */
662 				y = adj;
663 				if (y != adj) {
664 					if (!((rounding>>1) ^ dsign))
665 						y++;
666 					adj = y;
667 					}
668 				}
669 #ifdef Avoid_Underflow
670 			if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
671 				word0(adj) += (2*P+1)*Exp_msk1 - y;
672 #else
673 #ifdef Sudden_Underflow
674 			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
675 				word0(rv) += P*Exp_msk1;
676 				adj *= ulp(dval(rv));
677 				if (dsign)
678 					dval(rv) += adj;
679 				else
680 					dval(rv) -= adj;
681 				word0(rv) -= P*Exp_msk1;
682 				goto cont;
683 				}
684 #endif /*Sudden_Underflow*/
685 #endif /*Avoid_Underflow*/
686 			adj *= ulp(dval(rv));
687 			if (dsign)
688 				dval(rv) += adj;
689 			else
690 				dval(rv) -= adj;
691 			goto cont;
692 			}
693 #endif /*Honor_FLT_ROUNDS*/
694 
695 		if (i < 0) {
696 			/* Error is less than half an ulp -- check for
697 			 * special case of mantissa a power of two.
698 			 */
699 			if (dsign || word1(rv) || word0(rv) & Bndry_mask
700 #ifdef IEEE_Arith
701 #ifdef Avoid_Underflow
702 			 || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
703 #else
704 			 || (word0(rv) & Exp_mask) <= Exp_msk1
705 #endif
706 #endif
707 				) {
708 #ifdef SET_INEXACT
709 				if (!delta->x[0] && delta->wds <= 1)
710 					inexact = 0;
711 #endif
712 				break;
713 				}
714 			if (!delta->x[0] && delta->wds <= 1) {
715 				/* exact result */
716 #ifdef SET_INEXACT
717 				inexact = 0;
718 #endif
719 				break;
720 				}
721 			delta = lshift(delta,Log2P);
722 			if (cmp(delta, bs) > 0)
723 				goto drop_down;
724 			break;
725 			}
726 		if (i == 0) {
727 			/* exactly half-way between */
728 			if (dsign) {
729 				if ((word0(rv) & Bndry_mask1) == Bndry_mask1
730 				 &&  word1(rv) == (
731 #ifdef Avoid_Underflow
732 			(scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
733 		? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
734 #endif
735 						   0xffffffff)) {
736 					/*boundary case -- increment exponent*/
737 					word0(rv) = (word0(rv) & Exp_mask)
738 						+ Exp_msk1
739 #ifdef IBM
740 						| Exp_msk1 >> 4
741 #endif
742 						;
743 					word1(rv) = 0;
744 #ifdef Avoid_Underflow
745 					dsign = 0;
746 #endif
747 					break;
748 					}
749 				}
750 			else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
751  drop_down:
752 				/* boundary case -- decrement exponent */
753 #ifdef Sudden_Underflow /*{{*/
754 				L = word0(rv) & Exp_mask;
755 #ifdef IBM
756 				if (L <  Exp_msk1)
757 #else
758 #ifdef Avoid_Underflow
759 				if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
760 #else
761 				if (L <= Exp_msk1)
762 #endif /*Avoid_Underflow*/
763 #endif /*IBM*/
764 					goto undfl;
765 				L -= Exp_msk1;
766 #else /*Sudden_Underflow}{*/
767 #ifdef Avoid_Underflow
768 				if (scale) {
769 					L = word0(rv) & Exp_mask;
770 					if (L <= (2*P+1)*Exp_msk1) {
771 						if (L > (P+2)*Exp_msk1)
772 							/* round even ==> */
773 							/* accept rv */
774 							break;
775 						/* rv = smallest denormal */
776 						goto undfl;
777 						}
778 					}
779 #endif /*Avoid_Underflow*/
780 				L = (word0(rv) & Exp_mask) - Exp_msk1;
781 #endif /*Sudden_Underflow}*/
782 				word0(rv) = L | Bndry_mask1;
783 				word1(rv) = 0xffffffff;
784 #ifdef IBM
785 				goto cont;
786 #else
787 				break;
788 #endif
789 				}
790 #ifndef ROUND_BIASED
791 			if (!(word1(rv) & LSB))
792 				break;
793 #endif
794 			if (dsign)
795 				dval(rv) += ulp(dval(rv));
796 #ifndef ROUND_BIASED
797 			else {
798 				dval(rv) -= ulp(dval(rv));
799 #ifndef Sudden_Underflow
800 				if (!dval(rv))
801 					goto undfl;
802 #endif
803 				}
804 #ifdef Avoid_Underflow
805 			dsign = 1 - dsign;
806 #endif
807 #endif
808 			break;
809 			}
810 		if ((aadj = ratio(delta, bs)) <= 2.) {
811 			if (dsign)
812 				aadj = aadj1 = 1.;
813 			else if (word1(rv) || word0(rv) & Bndry_mask) {
814 #ifndef Sudden_Underflow
815 				if (word1(rv) == Tiny1 && !word0(rv))
816 					goto undfl;
817 #endif
818 				aadj = 1.;
819 				aadj1 = -1.;
820 				}
821 			else {
822 				/* special case -- power of FLT_RADIX to be */
823 				/* rounded down... */
824 
825 				if (aadj < 2./FLT_RADIX)
826 					aadj = 1./FLT_RADIX;
827 				else
828 					aadj *= 0.5;
829 				aadj1 = -aadj;
830 				}
831 			}
832 		else {
833 			aadj *= 0.5;
834 			aadj1 = dsign ? aadj : -aadj;
835 #ifdef Check_FLT_ROUNDS
836 			switch(Rounding) {
837 				case 2: /* towards +infinity */
838 					aadj1 -= 0.5;
839 					break;
840 				case 0: /* towards 0 */
841 				case 3: /* towards -infinity */
842 					aadj1 += 0.5;
843 				}
844 #else
845 			if (Flt_Rounds == 0)
846 				aadj1 += 0.5;
847 #endif /*Check_FLT_ROUNDS*/
848 			}
849 		y = word0(rv) & Exp_mask;
850 
851 		/* Check for overflow */
852 
853 		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
854 			dval(rv0) = dval(rv);
855 			word0(rv) -= P*Exp_msk1;
856 			adj = aadj1 * ulp(dval(rv));
857 			dval(rv) += adj;
858 			if ((word0(rv) & Exp_mask) >=
859 					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
860 				if (word0(rv0) == Big0 && word1(rv0) == Big1)
861 					goto ovfl;
862 				word0(rv) = Big0;
863 				word1(rv) = Big1;
864 				goto cont;
865 				}
866 			else
867 				word0(rv) += P*Exp_msk1;
868 			}
869 		else {
870 #ifdef Avoid_Underflow
871 			if (scale && y <= 2*P*Exp_msk1) {
872 				if (aadj <= 0x7fffffff) {
873 					if ((z = aadj) == 0)
874 						z = 1;
875 					aadj = z;
876 					aadj1 = dsign ? aadj : -aadj;
877 					}
878 				word0(aadj1) += (2*P+1)*Exp_msk1 - y;
879 				}
880 			adj = aadj1 * ulp(dval(rv));
881 			dval(rv) += adj;
882 #else
883 #ifdef Sudden_Underflow
884 			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
885 				dval(rv0) = dval(rv);
886 				word0(rv) += P*Exp_msk1;
887 				adj = aadj1 * ulp(dval(rv));
888 				dval(rv) += adj;
889 #ifdef IBM
890 				if ((word0(rv) & Exp_mask) <  P*Exp_msk1)
891 #else
892 				if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
893 #endif
894 					{
895 					if (word0(rv0) == Tiny0
896 					 && word1(rv0) == Tiny1)
897 						goto undfl;
898 					word0(rv) = Tiny0;
899 					word1(rv) = Tiny1;
900 					goto cont;
901 					}
902 				else
903 					word0(rv) -= P*Exp_msk1;
904 				}
905 			else {
906 				adj = aadj1 * ulp(dval(rv));
907 				dval(rv) += adj;
908 				}
909 #else /*Sudden_Underflow*/
910 			/* Compute adj so that the IEEE rounding rules will
911 			 * correctly round rv + adj in some half-way cases.
912 			 * If rv * ulp(rv) is denormalized (i.e.,
913 			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
914 			 * trouble from bits lost to denormalization;
915 			 * example: 1.2e-307 .
916 			 */
917 			if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
918 				aadj1 = (double)(int)(aadj + 0.5);
919 				if (!dsign)
920 					aadj1 = -aadj1;
921 				}
922 			adj = aadj1 * ulp(dval(rv));
923 			dval(rv) += adj;
924 #endif /*Sudden_Underflow*/
925 #endif /*Avoid_Underflow*/
926 			}
927 		z = word0(rv) & Exp_mask;
928 #ifndef SET_INEXACT
929 #ifdef Avoid_Underflow
930 		if (!scale)
931 #endif
932 		if (y == z) {
933 			/* Can we stop now? */
934 			L = (Long)aadj;
935 			aadj -= L;
936 			/* The tolerances below are conservative. */
937 			if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
938 				if (aadj < .4999999 || aadj > .5000001)
939 					break;
940 				}
941 			else if (aadj < .4999999/FLT_RADIX)
942 				break;
943 			}
944 #endif
945  cont:
946 		Bfree(bb);
947 		Bfree(bd);
948 		Bfree(bs);
949 		Bfree(delta);
950 		}
951 #ifdef SET_INEXACT
952 	if (inexact) {
953 		if (!oldinexact) {
954 			word0(rv0) = Exp_1 + (70 << Exp_shift);
955 			word1(rv0) = 0;
956 			dval(rv0) += 1.;
957 			}
958 		}
959 	else if (!oldinexact)
960 		clear_inexact();
961 #endif
962 #ifdef Avoid_Underflow
963 	if (scale) {
964 		word0(rv0) = Exp_1 - 2*P*Exp_msk1;
965 		word1(rv0) = 0;
966 		dval(rv) *= dval(rv0);
967 #ifndef NO_ERRNO
968 		/* try to avoid the bug of testing an 8087 register value */
969 		if (word0(rv) == 0 && word1(rv) == 0)
970 			errno = ERANGE;
971 #endif
972 		}
973 #endif /* Avoid_Underflow */
974 #ifdef SET_INEXACT
975 	if (inexact && !(word0(rv) & Exp_mask)) {
976 		/* set underflow bit */
977 		dval(rv0) = 1e-300;
978 		dval(rv0) *= dval(rv0);
979 		}
980 #endif
981  retfree:
982 	Bfree(bb);
983 	Bfree(bd);
984 	Bfree(bs);
985 	Bfree(bd0);
986 	Bfree(delta);
987  ret:
988 	if (se)
989 		*se = __UNCONST(s);
990 	return sign ? -dval(rv) : dval(rv);
991 	}
992 
993