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