xref: /openbsd-src/lib/libc/gdtoa/strtod.c (revision 5b44245bdef731678c5654e8568ec9e08bd990f6)
17b36286aSmartynas /****************************************************************
27b36286aSmartynas 
37b36286aSmartynas The author of this software is David M. Gay.
47b36286aSmartynas 
57b36286aSmartynas Copyright (C) 1998-2001 by Lucent Technologies
67b36286aSmartynas All Rights Reserved
77b36286aSmartynas 
87b36286aSmartynas Permission to use, copy, modify, and distribute this software and
97b36286aSmartynas its documentation for any purpose and without fee is hereby
107b36286aSmartynas granted, provided that the above copyright notice appear in all
117b36286aSmartynas copies and that both that the copyright notice and this
127b36286aSmartynas permission notice and warranty disclaimer appear in supporting
137b36286aSmartynas documentation, and that the name of Lucent or any of its entities
147b36286aSmartynas not be used in advertising or publicity pertaining to
157b36286aSmartynas distribution of the software without specific, written prior
167b36286aSmartynas permission.
177b36286aSmartynas 
187b36286aSmartynas LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
197b36286aSmartynas INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
207b36286aSmartynas IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
217b36286aSmartynas SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
227b36286aSmartynas WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
237b36286aSmartynas IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
247b36286aSmartynas ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
257b36286aSmartynas THIS SOFTWARE.
267b36286aSmartynas 
277b36286aSmartynas ****************************************************************/
287b36286aSmartynas 
297b36286aSmartynas /* Please send bug reports to David M. Gay (dmg at acm dot org,
307b36286aSmartynas  * with " at " changed at "@" and " dot " changed to ".").	*/
317b36286aSmartynas 
327b36286aSmartynas #include "gdtoaimp.h"
337b36286aSmartynas #ifndef NO_FENV_H
347b36286aSmartynas #include <fenv.h>
357b36286aSmartynas #endif
367b36286aSmartynas 
377b36286aSmartynas #ifdef USE_LOCALE
387b36286aSmartynas #include "locale.h"
397b36286aSmartynas #endif
407b36286aSmartynas 
417b36286aSmartynas #ifdef IEEE_Arith
427b36286aSmartynas #ifndef NO_IEEE_Scale
437b36286aSmartynas #define Avoid_Underflow
447b36286aSmartynas #undef tinytens
45aad11945Smartynas /* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */
467b36286aSmartynas /* flag unnecessarily.  It leads to a song and dance at the end of strtod. */
477b36286aSmartynas static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
48aad11945Smartynas 		9007199254740992.*9007199254740992.e-256
497b36286aSmartynas 		};
507b36286aSmartynas #endif
517b36286aSmartynas #endif
527b36286aSmartynas 
537b36286aSmartynas #ifdef Honor_FLT_ROUNDS
547b36286aSmartynas #undef Check_FLT_ROUNDS
557b36286aSmartynas #define Check_FLT_ROUNDS
567b36286aSmartynas #else
577b36286aSmartynas #define Rounding Flt_Rounds
587b36286aSmartynas #endif
597b36286aSmartynas 
601a653cbcSmartynas #ifdef Avoid_Underflow /*{*/
611a653cbcSmartynas  static double
sulp(x,scale)621a653cbcSmartynas sulp
631a653cbcSmartynas #ifdef KR_headers
641a653cbcSmartynas 	(x, scale) U *x; int scale;
651a653cbcSmartynas #else
661a653cbcSmartynas 	(U *x, int scale)
671a653cbcSmartynas #endif
681a653cbcSmartynas {
691a653cbcSmartynas 	U u;
701a653cbcSmartynas 	double rv;
711a653cbcSmartynas 	int i;
721a653cbcSmartynas 
731a653cbcSmartynas 	rv = ulp(x);
741a653cbcSmartynas 	if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0)
751a653cbcSmartynas 		return rv; /* Is there an example where i <= 0 ? */
761a653cbcSmartynas 	word0(&u) = Exp_1 + (i << Exp_shift);
771a653cbcSmartynas 	word1(&u) = 0;
781a653cbcSmartynas 	return rv * u.d;
791a653cbcSmartynas 	}
801a653cbcSmartynas #endif /*}*/
811a653cbcSmartynas 
827b36286aSmartynas  double
strtod(s00,se)837b36286aSmartynas strtod
847b36286aSmartynas #ifdef KR_headers
857b36286aSmartynas 	(s00, se) CONST char *s00; char **se;
867b36286aSmartynas #else
877b36286aSmartynas 	(CONST char *s00, char **se)
887b36286aSmartynas #endif
897b36286aSmartynas {
907b36286aSmartynas #ifdef Avoid_Underflow
917b36286aSmartynas 	int scale;
927b36286aSmartynas #endif
937b36286aSmartynas 	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
947b36286aSmartynas 		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
957b36286aSmartynas 	CONST char *s, *s0, *s1;
961a653cbcSmartynas 	double aadj;
977b36286aSmartynas 	Long L;
981a653cbcSmartynas 	U adj, aadj1, rv, rv0;
997b36286aSmartynas 	ULong y, z;
1001a653cbcSmartynas 	Bigint *bb = NULL, *bb1, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL;
1011a653cbcSmartynas #ifdef Avoid_Underflow
1021a653cbcSmartynas 	ULong Lsb, Lsb1;
1031a653cbcSmartynas #endif
1047b36286aSmartynas #ifdef SET_INEXACT
1057b36286aSmartynas 	int inexact, oldinexact;
1067b36286aSmartynas #endif
1071a653cbcSmartynas #ifdef USE_LOCALE /*{{*/
108aad11945Smartynas #ifdef NO_LOCALE_CACHE
109aad11945Smartynas 	char *decimalpoint = localeconv()->decimal_point;
1101a653cbcSmartynas 	int dplen = strlen(decimalpoint);
111aad11945Smartynas #else
112aad11945Smartynas 	char *decimalpoint;
113aad11945Smartynas 	static char *decimalpoint_cache;
1141a653cbcSmartynas 	static int dplen;
115aad11945Smartynas 	if (!(s0 = decimalpoint_cache)) {
116aad11945Smartynas 		s0 = localeconv()->decimal_point;
117*5b44245bSderaadt 		decimalpoint_cache = strdup(s0);
1181a653cbcSmartynas 		dplen = strlen(s0);
119aad11945Smartynas 		}
120aad11945Smartynas 	decimalpoint = (char*)s0;
1211a653cbcSmartynas #endif /*NO_LOCALE_CACHE*/
1221a653cbcSmartynas #else  /*USE_LOCALE}{*/
1231a653cbcSmartynas #define dplen 1
1241a653cbcSmartynas #endif /*USE_LOCALE}}*/
1251a653cbcSmartynas 
126aad11945Smartynas #ifdef Honor_FLT_ROUNDS /*{*/
127aad11945Smartynas 	int Rounding;
128aad11945Smartynas #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
129aad11945Smartynas 	Rounding = Flt_Rounds;
130aad11945Smartynas #else /*}{*/
131aad11945Smartynas 	Rounding = 1;
132aad11945Smartynas 	switch(fegetround()) {
133aad11945Smartynas 	  case FE_TOWARDZERO:	Rounding = 0; break;
134aad11945Smartynas 	  case FE_UPWARD:	Rounding = 2; break;
135aad11945Smartynas 	  case FE_DOWNWARD:	Rounding = 3;
136aad11945Smartynas 	  }
137aad11945Smartynas #endif /*}}*/
138aad11945Smartynas #endif /*}*/
1397b36286aSmartynas 
1407b36286aSmartynas 	sign = nz0 = nz = decpt = 0;
1411a653cbcSmartynas 	dval(&rv) = 0.;
1427b36286aSmartynas 	for(s = s00;;s++) switch(*s) {
1437b36286aSmartynas 		case '-':
1447b36286aSmartynas 			sign = 1;
1457b36286aSmartynas 			/* no break */
1467b36286aSmartynas 		case '+':
1477b36286aSmartynas 			if (*++s)
1487b36286aSmartynas 				goto break2;
1497b36286aSmartynas 			/* no break */
1507b36286aSmartynas 		case 0:
1517b36286aSmartynas 			goto ret0;
1527b36286aSmartynas 		case '\t':
1537b36286aSmartynas 		case '\n':
1547b36286aSmartynas 		case '\v':
1557b36286aSmartynas 		case '\f':
1567b36286aSmartynas 		case '\r':
1577b36286aSmartynas 		case ' ':
1587b36286aSmartynas 			continue;
1597b36286aSmartynas 		default:
1607b36286aSmartynas 			goto break2;
1617b36286aSmartynas 		}
1627b36286aSmartynas  break2:
1637b36286aSmartynas 	if (*s == '0') {
1641a653cbcSmartynas #ifndef NO_HEX_FP /*{*/
1657b36286aSmartynas 		{
1667b36286aSmartynas 		static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
1677b36286aSmartynas 		Long exp;
1687b36286aSmartynas 		ULong bits[2];
1697b36286aSmartynas 		switch(s[1]) {
1707b36286aSmartynas 		  case 'x':
1717b36286aSmartynas 		  case 'X':
1727b36286aSmartynas 			{
1731a653cbcSmartynas #ifdef Honor_FLT_ROUNDS
1747b36286aSmartynas 			FPI fpi1 = fpi;
175aad11945Smartynas 			fpi1.rounding = Rounding;
1761a653cbcSmartynas #else
1777b36286aSmartynas #define fpi1 fpi
1781a653cbcSmartynas #endif
1797b36286aSmartynas 			switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
1801a653cbcSmartynas 			  case STRTOG_NoMemory:
1811a653cbcSmartynas 				goto ovfl;
1827b36286aSmartynas 			  case STRTOG_NoNumber:
1837b36286aSmartynas 				s = s00;
1847b36286aSmartynas 				sign = 0;
1857b36286aSmartynas 			  case STRTOG_Zero:
1867b36286aSmartynas 				break;
1877b36286aSmartynas 			  default:
1887b36286aSmartynas 				if (bb) {
1897b36286aSmartynas 					copybits(bits, fpi.nbits, bb);
1907b36286aSmartynas 					Bfree(bb);
1917b36286aSmartynas 					}
1927b36286aSmartynas 				ULtod(((U*)&rv)->L, bits, exp, i);
1937b36286aSmartynas 			  }}
1947b36286aSmartynas 			goto ret;
1957b36286aSmartynas 		  }
1967b36286aSmartynas 		}
1971a653cbcSmartynas #endif /*}*/
1987b36286aSmartynas 		nz0 = 1;
1997b36286aSmartynas 		while(*++s == '0') ;
2007b36286aSmartynas 		if (!*s)
2017b36286aSmartynas 			goto ret;
2027b36286aSmartynas 		}
2037b36286aSmartynas 	s0 = s;
2047b36286aSmartynas 	y = z = 0;
2057b36286aSmartynas 	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
2067b36286aSmartynas 		if (nd < 9)
2077b36286aSmartynas 			y = 10*y + c - '0';
2087b36286aSmartynas 		else if (nd < 16)
2097b36286aSmartynas 			z = 10*z + c - '0';
2107b36286aSmartynas 	nd0 = nd;
2117b36286aSmartynas #ifdef USE_LOCALE
212aad11945Smartynas 	if (c == *decimalpoint) {
213aad11945Smartynas 		for(i = 1; decimalpoint[i]; ++i)
214aad11945Smartynas 			if (s[i] != decimalpoint[i])
215aad11945Smartynas 				goto dig_done;
216aad11945Smartynas 		s += i;
217aad11945Smartynas 		c = *s;
2187b36286aSmartynas #else
219aad11945Smartynas 	if (c == '.') {
2207b36286aSmartynas 		c = *++s;
221aad11945Smartynas #endif
222aad11945Smartynas 		decpt = 1;
2237b36286aSmartynas 		if (!nd) {
2247b36286aSmartynas 			for(; c == '0'; c = *++s)
2257b36286aSmartynas 				nz++;
2267b36286aSmartynas 			if (c > '0' && c <= '9') {
2277b36286aSmartynas 				s0 = s;
2287b36286aSmartynas 				nf += nz;
2297b36286aSmartynas 				nz = 0;
2307b36286aSmartynas 				goto have_dig;
2317b36286aSmartynas 				}
2327b36286aSmartynas 			goto dig_done;
2337b36286aSmartynas 			}
2347b36286aSmartynas 		for(; c >= '0' && c <= '9'; c = *++s) {
2357b36286aSmartynas  have_dig:
2367b36286aSmartynas 			nz++;
2377b36286aSmartynas 			if (c -= '0') {
2387b36286aSmartynas 				nf += nz;
2397b36286aSmartynas 				for(i = 1; i < nz; i++)
2407b36286aSmartynas 					if (nd++ < 9)
2417b36286aSmartynas 						y *= 10;
2427b36286aSmartynas 					else if (nd <= DBL_DIG + 1)
2437b36286aSmartynas 						z *= 10;
2447b36286aSmartynas 				if (nd++ < 9)
2457b36286aSmartynas 					y = 10*y + c;
2467b36286aSmartynas 				else if (nd <= DBL_DIG + 1)
2477b36286aSmartynas 					z = 10*z + c;
2487b36286aSmartynas 				nz = 0;
2497b36286aSmartynas 				}
2507b36286aSmartynas 			}
251aad11945Smartynas 		}/*}*/
2527b36286aSmartynas  dig_done:
2537b36286aSmartynas 	e = 0;
2547b36286aSmartynas 	if (c == 'e' || c == 'E') {
2557b36286aSmartynas 		if (!nd && !nz && !nz0) {
2567b36286aSmartynas 			goto ret0;
2577b36286aSmartynas 			}
2587b36286aSmartynas 		s00 = s;
2597b36286aSmartynas 		esign = 0;
2607b36286aSmartynas 		switch(c = *++s) {
2617b36286aSmartynas 			case '-':
2627b36286aSmartynas 				esign = 1;
2637b36286aSmartynas 			case '+':
2647b36286aSmartynas 				c = *++s;
2657b36286aSmartynas 			}
2667b36286aSmartynas 		if (c >= '0' && c <= '9') {
2677b36286aSmartynas 			while(c == '0')
2687b36286aSmartynas 				c = *++s;
2697b36286aSmartynas 			if (c > '0' && c <= '9') {
2707b36286aSmartynas 				L = c - '0';
2717b36286aSmartynas 				s1 = s;
2727b36286aSmartynas 				while((c = *++s) >= '0' && c <= '9')
2737b36286aSmartynas 					L = 10*L + c - '0';
2747b36286aSmartynas 				if (s - s1 > 8 || L > 19999)
2757b36286aSmartynas 					/* Avoid confusion from exponents
2767b36286aSmartynas 					 * so large that e might overflow.
2777b36286aSmartynas 					 */
2787b36286aSmartynas 					e = 19999; /* safe for 16 bit ints */
2797b36286aSmartynas 				else
2807b36286aSmartynas 					e = (int)L;
2817b36286aSmartynas 				if (esign)
2827b36286aSmartynas 					e = -e;
2837b36286aSmartynas 				}
2847b36286aSmartynas 			else
2857b36286aSmartynas 				e = 0;
2867b36286aSmartynas 			}
2877b36286aSmartynas 		else
2887b36286aSmartynas 			s = s00;
2897b36286aSmartynas 		}
2907b36286aSmartynas 	if (!nd) {
2917b36286aSmartynas 		if (!nz && !nz0) {
2927b36286aSmartynas #ifdef INFNAN_CHECK
2937b36286aSmartynas 			/* Check for Nan and Infinity */
2947b36286aSmartynas 			ULong bits[2];
2957b36286aSmartynas 			static FPI fpinan =	/* only 52 explicit bits */
2967b36286aSmartynas 				{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
2977b36286aSmartynas 			if (!decpt)
2987b36286aSmartynas 			 switch(c) {
2997b36286aSmartynas 			  case 'i':
3007b36286aSmartynas 			  case 'I':
3017b36286aSmartynas 				if (match(&s,"nf")) {
3027b36286aSmartynas 					--s;
3037b36286aSmartynas 					if (!match(&s,"inity"))
3047b36286aSmartynas 						++s;
3051a653cbcSmartynas 					word0(&rv) = 0x7ff00000;
3061a653cbcSmartynas 					word1(&rv) = 0;
3077b36286aSmartynas 					goto ret;
3087b36286aSmartynas 					}
3097b36286aSmartynas 				break;
3107b36286aSmartynas 			  case 'n':
3117b36286aSmartynas 			  case 'N':
3127b36286aSmartynas 				if (match(&s, "an")) {
3137b36286aSmartynas #ifndef No_Hex_NaN
3147b36286aSmartynas 					if (*s == '(' /*)*/
3157b36286aSmartynas 					 && hexnan(&s, &fpinan, bits)
3167b36286aSmartynas 							== STRTOG_NaNbits) {
3171a653cbcSmartynas 						word0(&rv) = 0x7ff00000 | bits[1];
3181a653cbcSmartynas 						word1(&rv) = bits[0];
3197b36286aSmartynas 						}
3207b36286aSmartynas 					else {
3217b36286aSmartynas #endif
3221a653cbcSmartynas 						word0(&rv) = NAN_WORD0;
3231a653cbcSmartynas 						word1(&rv) = NAN_WORD1;
3247b36286aSmartynas #ifndef No_Hex_NaN
3257b36286aSmartynas 						}
3267b36286aSmartynas #endif
3277b36286aSmartynas 					goto ret;
3287b36286aSmartynas 					}
3297b36286aSmartynas 			  }
3307b36286aSmartynas #endif /* INFNAN_CHECK */
3317b36286aSmartynas  ret0:
3327b36286aSmartynas 			s = s00;
3337b36286aSmartynas 			sign = 0;
3347b36286aSmartynas 			}
3357b36286aSmartynas 		goto ret;
3367b36286aSmartynas 		}
3377b36286aSmartynas 	e1 = e -= nf;
3387b36286aSmartynas 
3397b36286aSmartynas 	/* Now we have nd0 digits, starting at s0, followed by a
3407b36286aSmartynas 	 * decimal point, followed by nd-nd0 digits.  The number we're
3417b36286aSmartynas 	 * after is the integer represented by those digits times
3427b36286aSmartynas 	 * 10**e */
3437b36286aSmartynas 
3447b36286aSmartynas 	if (!nd0)
3457b36286aSmartynas 		nd0 = nd;
3467b36286aSmartynas 	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
3471a653cbcSmartynas 	dval(&rv) = y;
3487b36286aSmartynas 	if (k > 9) {
3497b36286aSmartynas #ifdef SET_INEXACT
3507b36286aSmartynas 		if (k > DBL_DIG)
3517b36286aSmartynas 			oldinexact = get_inexact();
3527b36286aSmartynas #endif
3531a653cbcSmartynas 		dval(&rv) = tens[k - 9] * dval(&rv) + z;
3547b36286aSmartynas 		}
3557b36286aSmartynas 	if (nd <= DBL_DIG
3567b36286aSmartynas #ifndef RND_PRODQUOT
3577b36286aSmartynas #ifndef Honor_FLT_ROUNDS
3587b36286aSmartynas 		&& Flt_Rounds == 1
3597b36286aSmartynas #endif
3607b36286aSmartynas #endif
3617b36286aSmartynas 			) {
3627b36286aSmartynas 		if (!e)
3637b36286aSmartynas 			goto ret;
3641a653cbcSmartynas #ifndef ROUND_BIASED_without_Round_Up
3657b36286aSmartynas 		if (e > 0) {
3667b36286aSmartynas 			if (e <= Ten_pmax) {
3677b36286aSmartynas #ifdef VAX
3687b36286aSmartynas 				goto vax_ovfl_check;
3697b36286aSmartynas #else
3707b36286aSmartynas #ifdef Honor_FLT_ROUNDS
3717b36286aSmartynas 				/* round correctly FLT_ROUNDS = 2 or 3 */
3727b36286aSmartynas 				if (sign) {
3731a653cbcSmartynas 					rv.d = -rv.d;
3747b36286aSmartynas 					sign = 0;
3757b36286aSmartynas 					}
3767b36286aSmartynas #endif
3771a653cbcSmartynas 				/* rv = */ rounded_product(dval(&rv), tens[e]);
3787b36286aSmartynas 				goto ret;
3797b36286aSmartynas #endif
3807b36286aSmartynas 				}
3817b36286aSmartynas 			i = DBL_DIG - nd;
3827b36286aSmartynas 			if (e <= Ten_pmax + i) {
3837b36286aSmartynas 				/* A fancier test would sometimes let us do
3847b36286aSmartynas 				 * this for larger i values.
3857b36286aSmartynas 				 */
3867b36286aSmartynas #ifdef Honor_FLT_ROUNDS
3877b36286aSmartynas 				/* round correctly FLT_ROUNDS = 2 or 3 */
3887b36286aSmartynas 				if (sign) {
3891a653cbcSmartynas 					rv.d = -rv.d;
3907b36286aSmartynas 					sign = 0;
3917b36286aSmartynas 					}
3927b36286aSmartynas #endif
3937b36286aSmartynas 				e -= i;
3941a653cbcSmartynas 				dval(&rv) *= tens[i];
3957b36286aSmartynas #ifdef VAX
3967b36286aSmartynas 				/* VAX exponent range is so narrow we must
3977b36286aSmartynas 				 * worry about overflow here...
3987b36286aSmartynas 				 */
3997b36286aSmartynas  vax_ovfl_check:
4001a653cbcSmartynas 				word0(&rv) -= P*Exp_msk1;
4011a653cbcSmartynas 				/* rv = */ rounded_product(dval(&rv), tens[e]);
4021a653cbcSmartynas 				if ((word0(&rv) & Exp_mask)
4037b36286aSmartynas 				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
4047b36286aSmartynas 					goto ovfl;
4051a653cbcSmartynas 				word0(&rv) += P*Exp_msk1;
4067b36286aSmartynas #else
4071a653cbcSmartynas 				/* rv = */ rounded_product(dval(&rv), tens[e]);
4087b36286aSmartynas #endif
4097b36286aSmartynas 				goto ret;
4107b36286aSmartynas 				}
4117b36286aSmartynas 			}
4127b36286aSmartynas #ifndef Inaccurate_Divide
4137b36286aSmartynas 		else if (e >= -Ten_pmax) {
4147b36286aSmartynas #ifdef Honor_FLT_ROUNDS
4157b36286aSmartynas 			/* round correctly FLT_ROUNDS = 2 or 3 */
4167b36286aSmartynas 			if (sign) {
4171a653cbcSmartynas 				rv.d = -rv.d;
4187b36286aSmartynas 				sign = 0;
4197b36286aSmartynas 				}
4207b36286aSmartynas #endif
4211a653cbcSmartynas 			/* rv = */ rounded_quotient(dval(&rv), tens[-e]);
4227b36286aSmartynas 			goto ret;
4237b36286aSmartynas 			}
4247b36286aSmartynas #endif
4251a653cbcSmartynas #endif /* ROUND_BIASED_without_Round_Up */
4267b36286aSmartynas 		}
4277b36286aSmartynas 	e1 += nd - k;
4287b36286aSmartynas 
4297b36286aSmartynas #ifdef IEEE_Arith
4307b36286aSmartynas #ifdef SET_INEXACT
4317b36286aSmartynas 	inexact = 1;
4327b36286aSmartynas 	if (k <= DBL_DIG)
4337b36286aSmartynas 		oldinexact = get_inexact();
4347b36286aSmartynas #endif
4357b36286aSmartynas #ifdef Avoid_Underflow
4367b36286aSmartynas 	scale = 0;
4377b36286aSmartynas #endif
4387b36286aSmartynas #ifdef Honor_FLT_ROUNDS
439aad11945Smartynas 	if (Rounding >= 2) {
4407b36286aSmartynas 		if (sign)
441aad11945Smartynas 			Rounding = Rounding == 2 ? 0 : 2;
4427b36286aSmartynas 		else
443aad11945Smartynas 			if (Rounding != 2)
444aad11945Smartynas 				Rounding = 0;
4457b36286aSmartynas 		}
4467b36286aSmartynas #endif
4477b36286aSmartynas #endif /*IEEE_Arith*/
4487b36286aSmartynas 
4497b36286aSmartynas 	/* Get starting approximation = rv * 10**e1 */
4507b36286aSmartynas 
4517b36286aSmartynas 	if (e1 > 0) {
4527b36286aSmartynas 		if ( (i = e1 & 15) !=0)
4531a653cbcSmartynas 			dval(&rv) *= tens[i];
4547b36286aSmartynas 		if (e1 &= ~15) {
4557b36286aSmartynas 			if (e1 > DBL_MAX_10_EXP) {
4567b36286aSmartynas  ovfl:
4577b36286aSmartynas 				/* Can't trust HUGE_VAL */
4587b36286aSmartynas #ifdef IEEE_Arith
4597b36286aSmartynas #ifdef Honor_FLT_ROUNDS
460aad11945Smartynas 				switch(Rounding) {
4617b36286aSmartynas 				  case 0: /* toward 0 */
4627b36286aSmartynas 				  case 3: /* toward -infinity */
4631a653cbcSmartynas 					word0(&rv) = Big0;
4641a653cbcSmartynas 					word1(&rv) = Big1;
4657b36286aSmartynas 					break;
4667b36286aSmartynas 				  default:
4671a653cbcSmartynas 					word0(&rv) = Exp_mask;
4681a653cbcSmartynas 					word1(&rv) = 0;
4697b36286aSmartynas 				  }
4707b36286aSmartynas #else /*Honor_FLT_ROUNDS*/
4711a653cbcSmartynas 				word0(&rv) = Exp_mask;
4721a653cbcSmartynas 				word1(&rv) = 0;
4737b36286aSmartynas #endif /*Honor_FLT_ROUNDS*/
4747b36286aSmartynas #ifdef SET_INEXACT
4757b36286aSmartynas 				/* set overflow bit */
4761a653cbcSmartynas 				dval(&rv0) = 1e300;
4771a653cbcSmartynas 				dval(&rv0) *= dval(&rv0);
4787b36286aSmartynas #endif
4797b36286aSmartynas #else /*IEEE_Arith*/
4801a653cbcSmartynas 				word0(&rv) = Big0;
4811a653cbcSmartynas 				word1(&rv) = Big1;
4827b36286aSmartynas #endif /*IEEE_Arith*/
4831a653cbcSmartynas  range_err:
4841a653cbcSmartynas 				if (bd0) {
4851a653cbcSmartynas 					Bfree(bb);
4861a653cbcSmartynas 					Bfree(bd);
4871a653cbcSmartynas 					Bfree(bs);
4881a653cbcSmartynas 					Bfree(bd0);
4891a653cbcSmartynas 					Bfree(delta);
4901a653cbcSmartynas 					}
4911a653cbcSmartynas #ifndef NO_ERRNO
4921a653cbcSmartynas 				errno = ERANGE;
4931a653cbcSmartynas #endif
4947b36286aSmartynas 				goto ret;
4957b36286aSmartynas 				}
4967b36286aSmartynas 			e1 >>= 4;
4977b36286aSmartynas 			for(j = 0; e1 > 1; j++, e1 >>= 1)
4987b36286aSmartynas 				if (e1 & 1)
4991a653cbcSmartynas 					dval(&rv) *= bigtens[j];
5007b36286aSmartynas 		/* The last multiplication could overflow. */
5011a653cbcSmartynas 			word0(&rv) -= P*Exp_msk1;
5021a653cbcSmartynas 			dval(&rv) *= bigtens[j];
5031a653cbcSmartynas 			if ((z = word0(&rv) & Exp_mask)
5047b36286aSmartynas 			 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
5057b36286aSmartynas 				goto ovfl;
5067b36286aSmartynas 			if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
5077b36286aSmartynas 				/* set to largest number */
5087b36286aSmartynas 				/* (Can't trust DBL_MAX) */
5091a653cbcSmartynas 				word0(&rv) = Big0;
5101a653cbcSmartynas 				word1(&rv) = Big1;
5117b36286aSmartynas 				}
5127b36286aSmartynas 			else
5131a653cbcSmartynas 				word0(&rv) += P*Exp_msk1;
5147b36286aSmartynas 			}
5157b36286aSmartynas 		}
5167b36286aSmartynas 	else if (e1 < 0) {
5177b36286aSmartynas 		e1 = -e1;
5187b36286aSmartynas 		if ( (i = e1 & 15) !=0)
5191a653cbcSmartynas 			dval(&rv) /= tens[i];
5207b36286aSmartynas 		if (e1 >>= 4) {
5217b36286aSmartynas 			if (e1 >= 1 << n_bigtens)
5227b36286aSmartynas 				goto undfl;
5237b36286aSmartynas #ifdef Avoid_Underflow
5247b36286aSmartynas 			if (e1 & Scale_Bit)
5257b36286aSmartynas 				scale = 2*P;
5267b36286aSmartynas 			for(j = 0; e1 > 0; j++, e1 >>= 1)
5277b36286aSmartynas 				if (e1 & 1)
5281a653cbcSmartynas 					dval(&rv) *= tinytens[j];
5291a653cbcSmartynas 			if (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
5307b36286aSmartynas 						>> Exp_shift)) > 0) {
5317b36286aSmartynas 				/* scaled rv is denormal; zap j low bits */
5327b36286aSmartynas 				if (j >= 32) {
5331a653cbcSmartynas 					word1(&rv) = 0;
5347b36286aSmartynas 					if (j >= 53)
5351a653cbcSmartynas 					 word0(&rv) = (P+2)*Exp_msk1;
5367b36286aSmartynas 					else
5371a653cbcSmartynas 					 word0(&rv) &= 0xffffffff << (j-32);
5387b36286aSmartynas 					}
5397b36286aSmartynas 				else
5401a653cbcSmartynas 					word1(&rv) &= 0xffffffff << j;
5417b36286aSmartynas 				}
5427b36286aSmartynas #else
5437b36286aSmartynas 			for(j = 0; e1 > 1; j++, e1 >>= 1)
5447b36286aSmartynas 				if (e1 & 1)
5451a653cbcSmartynas 					dval(&rv) *= tinytens[j];
5467b36286aSmartynas 			/* The last multiplication could underflow. */
5471a653cbcSmartynas 			dval(&rv0) = dval(&rv);
5481a653cbcSmartynas 			dval(&rv) *= tinytens[j];
5491a653cbcSmartynas 			if (!dval(&rv)) {
5501a653cbcSmartynas 				dval(&rv) = 2.*dval(&rv0);
5511a653cbcSmartynas 				dval(&rv) *= tinytens[j];
5527b36286aSmartynas #endif
5531a653cbcSmartynas 				if (!dval(&rv)) {
5547b36286aSmartynas  undfl:
5551a653cbcSmartynas 					dval(&rv) = 0.;
5561a653cbcSmartynas 					goto range_err;
5577b36286aSmartynas 					}
5587b36286aSmartynas #ifndef Avoid_Underflow
5591a653cbcSmartynas 				word0(&rv) = Tiny0;
5601a653cbcSmartynas 				word1(&rv) = Tiny1;
5617b36286aSmartynas 				/* The refinement below will clean
5627b36286aSmartynas 				 * this approximation up.
5637b36286aSmartynas 				 */
5647b36286aSmartynas 				}
5657b36286aSmartynas #endif
5667b36286aSmartynas 			}
5677b36286aSmartynas 		}
5687b36286aSmartynas 
5697b36286aSmartynas 	/* Now the hard part -- adjusting rv to the correct value.*/
5707b36286aSmartynas 
5717b36286aSmartynas 	/* Put digits into bd: true value = bd * 10^e */
5727b36286aSmartynas 
5731a653cbcSmartynas 	bd0 = s2b(s0, nd0, nd, y, dplen);
574384cfdc1Smartynas 	if (bd0 == NULL)
575384cfdc1Smartynas 		goto ovfl;
5767b36286aSmartynas 
5777b36286aSmartynas 	for(;;) {
5787b36286aSmartynas 		bd = Balloc(bd0->k);
579384cfdc1Smartynas 		if (bd == NULL)
580384cfdc1Smartynas 			goto ovfl;
5817b36286aSmartynas 		Bcopy(bd, bd0);
5821a653cbcSmartynas 		bb = d2b(dval(&rv), &bbe, &bbbits);	/* rv = bb * 2^bbe */
583384cfdc1Smartynas 		if (bb == NULL)
584384cfdc1Smartynas 			goto ovfl;
5857b36286aSmartynas 		bs = i2b(1);
586384cfdc1Smartynas 		if (bs == NULL)
587384cfdc1Smartynas 			goto ovfl;
5887b36286aSmartynas 
5897b36286aSmartynas 		if (e >= 0) {
5907b36286aSmartynas 			bb2 = bb5 = 0;
5917b36286aSmartynas 			bd2 = bd5 = e;
5927b36286aSmartynas 			}
5937b36286aSmartynas 		else {
5947b36286aSmartynas 			bb2 = bb5 = -e;
5957b36286aSmartynas 			bd2 = bd5 = 0;
5967b36286aSmartynas 			}
5977b36286aSmartynas 		if (bbe >= 0)
5987b36286aSmartynas 			bb2 += bbe;
5997b36286aSmartynas 		else
6007b36286aSmartynas 			bd2 -= bbe;
6017b36286aSmartynas 		bs2 = bb2;
6027b36286aSmartynas #ifdef Honor_FLT_ROUNDS
603aad11945Smartynas 		if (Rounding != 1)
6047b36286aSmartynas 			bs2++;
6057b36286aSmartynas #endif
6067b36286aSmartynas #ifdef Avoid_Underflow
6071a653cbcSmartynas 		Lsb = LSB;
6081a653cbcSmartynas 		Lsb1 = 0;
6097b36286aSmartynas 		j = bbe - scale;
6107b36286aSmartynas 		i = j + bbbits - 1;	/* logb(rv) */
6117b36286aSmartynas 		j = P + 1 - bbbits;
6121a653cbcSmartynas 		if (i < Emin) {	/* denormal */
6131a653cbcSmartynas 			i = Emin - i;
6141a653cbcSmartynas 			j -= i;
6151a653cbcSmartynas 			if (i < 32)
6161a653cbcSmartynas 				Lsb <<= i;
6171a653cbcSmartynas 			else
6181a653cbcSmartynas 				Lsb1 = Lsb << (i-32);
6191a653cbcSmartynas 			}
6207b36286aSmartynas #else /*Avoid_Underflow*/
6217b36286aSmartynas #ifdef Sudden_Underflow
6227b36286aSmartynas #ifdef IBM
6237b36286aSmartynas 		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
6247b36286aSmartynas #else
6257b36286aSmartynas 		j = P + 1 - bbbits;
6267b36286aSmartynas #endif
6277b36286aSmartynas #else /*Sudden_Underflow*/
6287b36286aSmartynas 		j = bbe;
6291a653cbcSmartynas 		i = j + bbbits - 1;	/* logb(&rv) */
6307b36286aSmartynas 		if (i < Emin)	/* denormal */
6317b36286aSmartynas 			j += P - Emin;
6327b36286aSmartynas 		else
6337b36286aSmartynas 			j = P + 1 - bbbits;
6347b36286aSmartynas #endif /*Sudden_Underflow*/
6357b36286aSmartynas #endif /*Avoid_Underflow*/
6367b36286aSmartynas 		bb2 += j;
6377b36286aSmartynas 		bd2 += j;
6387b36286aSmartynas #ifdef Avoid_Underflow
6397b36286aSmartynas 		bd2 += scale;
6407b36286aSmartynas #endif
6417b36286aSmartynas 		i = bb2 < bd2 ? bb2 : bd2;
6427b36286aSmartynas 		if (i > bs2)
6437b36286aSmartynas 			i = bs2;
6447b36286aSmartynas 		if (i > 0) {
6457b36286aSmartynas 			bb2 -= i;
6467b36286aSmartynas 			bd2 -= i;
6477b36286aSmartynas 			bs2 -= i;
6487b36286aSmartynas 			}
6497b36286aSmartynas 		if (bb5 > 0) {
6507b36286aSmartynas 			bs = pow5mult(bs, bb5);
651384cfdc1Smartynas 			if (bs == NULL)
652384cfdc1Smartynas 				goto ovfl;
6537b36286aSmartynas 			bb1 = mult(bs, bb);
654384cfdc1Smartynas 			if (bb1 == NULL)
655384cfdc1Smartynas 				goto ovfl;
6567b36286aSmartynas 			Bfree(bb);
6577b36286aSmartynas 			bb = bb1;
6587b36286aSmartynas 			}
659384cfdc1Smartynas 		if (bb2 > 0) {
6607b36286aSmartynas 			bb = lshift(bb, bb2);
661384cfdc1Smartynas 			if (bb == NULL)
662384cfdc1Smartynas 				goto ovfl;
663384cfdc1Smartynas 			}
664384cfdc1Smartynas 		if (bd5 > 0) {
6657b36286aSmartynas 			bd = pow5mult(bd, bd5);
666384cfdc1Smartynas 			if (bd == NULL)
667384cfdc1Smartynas 				goto ovfl;
668384cfdc1Smartynas 			}
669384cfdc1Smartynas 		if (bd2 > 0) {
6707b36286aSmartynas 			bd = lshift(bd, bd2);
671384cfdc1Smartynas 			if (bd == NULL)
672384cfdc1Smartynas 				goto ovfl;
673384cfdc1Smartynas 			}
674384cfdc1Smartynas 		if (bs2 > 0) {
6757b36286aSmartynas 			bs = lshift(bs, bs2);
676384cfdc1Smartynas 			if (bs == NULL)
677384cfdc1Smartynas 				goto ovfl;
678384cfdc1Smartynas 			}
6797b36286aSmartynas 		delta = diff(bb, bd);
680384cfdc1Smartynas 		if (delta == NULL)
681384cfdc1Smartynas 			goto ovfl;
6827b36286aSmartynas 		dsign = delta->sign;
6837b36286aSmartynas 		delta->sign = 0;
6847b36286aSmartynas 		i = cmp(delta, bs);
6857b36286aSmartynas #ifdef Honor_FLT_ROUNDS
686aad11945Smartynas 		if (Rounding != 1) {
6877b36286aSmartynas 			if (i < 0) {
6887b36286aSmartynas 				/* Error is less than an ulp */
6897b36286aSmartynas 				if (!delta->x[0] && delta->wds <= 1) {
6907b36286aSmartynas 					/* exact */
6917b36286aSmartynas #ifdef SET_INEXACT
6927b36286aSmartynas 					inexact = 0;
6937b36286aSmartynas #endif
6947b36286aSmartynas 					break;
6957b36286aSmartynas 					}
696aad11945Smartynas 				if (Rounding) {
6977b36286aSmartynas 					if (dsign) {
6981a653cbcSmartynas 						dval(&adj) = 1.;
6997b36286aSmartynas 						goto apply_adj;
7007b36286aSmartynas 						}
7017b36286aSmartynas 					}
7027b36286aSmartynas 				else if (!dsign) {
7031a653cbcSmartynas 					dval(&adj) = -1.;
7041a653cbcSmartynas 					if (!word1(&rv)
7051a653cbcSmartynas 					 && !(word0(&rv) & Frac_mask)) {
7061a653cbcSmartynas 						y = word0(&rv) & Exp_mask;
7077b36286aSmartynas #ifdef Avoid_Underflow
7087b36286aSmartynas 						if (!scale || y > 2*P*Exp_msk1)
7097b36286aSmartynas #else
7107b36286aSmartynas 						if (y)
7117b36286aSmartynas #endif
7127b36286aSmartynas 						  {
7137b36286aSmartynas 						  delta = lshift(delta,Log2P);
714384cfdc1Smartynas 						  if (delta == NULL)
715384cfdc1Smartynas 							goto ovfl;
7167b36286aSmartynas 						  if (cmp(delta, bs) <= 0)
7171a653cbcSmartynas 							dval(&adj) = -0.5;
7187b36286aSmartynas 						  }
7197b36286aSmartynas 						}
7207b36286aSmartynas  apply_adj:
7217b36286aSmartynas #ifdef Avoid_Underflow
7221a653cbcSmartynas 					if (scale && (y = word0(&rv) & Exp_mask)
7237b36286aSmartynas 						<= 2*P*Exp_msk1)
7241a653cbcSmartynas 					  word0(&adj) += (2*P+1)*Exp_msk1 - y;
7257b36286aSmartynas #else
7267b36286aSmartynas #ifdef Sudden_Underflow
7271a653cbcSmartynas 					if ((word0(&rv) & Exp_mask) <=
7287b36286aSmartynas 							P*Exp_msk1) {
7291a653cbcSmartynas 						word0(&rv) += P*Exp_msk1;
7301a653cbcSmartynas 						dval(&rv) += adj*ulp(&rv);
7311a653cbcSmartynas 						word0(&rv) -= P*Exp_msk1;
7327b36286aSmartynas 						}
7337b36286aSmartynas 					else
7347b36286aSmartynas #endif /*Sudden_Underflow*/
7357b36286aSmartynas #endif /*Avoid_Underflow*/
7361a653cbcSmartynas 					dval(&rv) += adj.d*ulp(&rv);
7377b36286aSmartynas 					}
7387b36286aSmartynas 				break;
7397b36286aSmartynas 				}
7401a653cbcSmartynas 			dval(&adj) = ratio(delta, bs);
7411a653cbcSmartynas 			if (adj.d < 1.)
7421a653cbcSmartynas 				dval(&adj) = 1.;
7431a653cbcSmartynas 			if (adj.d <= 0x7ffffffe) {
7441a653cbcSmartynas 				/* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */
7451a653cbcSmartynas 				y = adj.d;
7461a653cbcSmartynas 				if (y != adj.d) {
747aad11945Smartynas 					if (!((Rounding>>1) ^ dsign))
7487b36286aSmartynas 						y++;
7491a653cbcSmartynas 					dval(&adj) = y;
7507b36286aSmartynas 					}
7517b36286aSmartynas 				}
7527b36286aSmartynas #ifdef Avoid_Underflow
7531a653cbcSmartynas 			if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
7541a653cbcSmartynas 				word0(&adj) += (2*P+1)*Exp_msk1 - y;
7557b36286aSmartynas #else
7567b36286aSmartynas #ifdef Sudden_Underflow
7571a653cbcSmartynas 			if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
7581a653cbcSmartynas 				word0(&rv) += P*Exp_msk1;
7591a653cbcSmartynas 				dval(&adj) *= ulp(&rv);
7607b36286aSmartynas 				if (dsign)
7611a653cbcSmartynas 					dval(&rv) += adj;
7627b36286aSmartynas 				else
7631a653cbcSmartynas 					dval(&rv) -= adj;
7641a653cbcSmartynas 				word0(&rv) -= P*Exp_msk1;
7657b36286aSmartynas 				goto cont;
7667b36286aSmartynas 				}
7677b36286aSmartynas #endif /*Sudden_Underflow*/
7687b36286aSmartynas #endif /*Avoid_Underflow*/
7691a653cbcSmartynas 			dval(&adj) *= ulp(&rv);
770aad11945Smartynas 			if (dsign) {
7711a653cbcSmartynas 				if (word0(&rv) == Big0 && word1(&rv) == Big1)
772aad11945Smartynas 					goto ovfl;
7731a653cbcSmartynas 				dval(&rv) += adj.d;
774aad11945Smartynas 				}
7757b36286aSmartynas 			else
7761a653cbcSmartynas 				dval(&rv) -= adj.d;
7777b36286aSmartynas 			goto cont;
7787b36286aSmartynas 			}
7797b36286aSmartynas #endif /*Honor_FLT_ROUNDS*/
7807b36286aSmartynas 
7817b36286aSmartynas 		if (i < 0) {
7827b36286aSmartynas 			/* Error is less than half an ulp -- check for
7837b36286aSmartynas 			 * special case of mantissa a power of two.
7847b36286aSmartynas 			 */
7851a653cbcSmartynas 			if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
7867b36286aSmartynas #ifdef IEEE_Arith
7877b36286aSmartynas #ifdef Avoid_Underflow
7881a653cbcSmartynas 			 || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
7897b36286aSmartynas #else
7901a653cbcSmartynas 			 || (word0(&rv) & Exp_mask) <= Exp_msk1
7917b36286aSmartynas #endif
7927b36286aSmartynas #endif
7937b36286aSmartynas 				) {
7947b36286aSmartynas #ifdef SET_INEXACT
7957b36286aSmartynas 				if (!delta->x[0] && delta->wds <= 1)
7967b36286aSmartynas 					inexact = 0;
7977b36286aSmartynas #endif
7987b36286aSmartynas 				break;
7997b36286aSmartynas 				}
8007b36286aSmartynas 			if (!delta->x[0] && delta->wds <= 1) {
8017b36286aSmartynas 				/* exact result */
8027b36286aSmartynas #ifdef SET_INEXACT
8037b36286aSmartynas 				inexact = 0;
8047b36286aSmartynas #endif
8057b36286aSmartynas 				break;
8067b36286aSmartynas 				}
8077b36286aSmartynas 			delta = lshift(delta,Log2P);
808384cfdc1Smartynas 			if (delta == NULL)
809384cfdc1Smartynas 				goto ovfl;
8107b36286aSmartynas 			if (cmp(delta, bs) > 0)
8117b36286aSmartynas 				goto drop_down;
8127b36286aSmartynas 			break;
8137b36286aSmartynas 			}
8147b36286aSmartynas 		if (i == 0) {
8157b36286aSmartynas 			/* exactly half-way between */
8167b36286aSmartynas 			if (dsign) {
8171a653cbcSmartynas 				if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
8181a653cbcSmartynas 				 &&  word1(&rv) == (
8197b36286aSmartynas #ifdef Avoid_Underflow
8201a653cbcSmartynas 			(scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
8217b36286aSmartynas 		? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
8227b36286aSmartynas #endif
8237b36286aSmartynas 						   0xffffffff)) {
8247b36286aSmartynas 					/*boundary case -- increment exponent*/
8251a653cbcSmartynas 					if (word0(&rv) == Big0 && word1(&rv) == Big1)
8261a653cbcSmartynas 						goto ovfl;
8271a653cbcSmartynas 					word0(&rv) = (word0(&rv) & Exp_mask)
8287b36286aSmartynas 						+ Exp_msk1
8297b36286aSmartynas #ifdef IBM
8307b36286aSmartynas 						| Exp_msk1 >> 4
8317b36286aSmartynas #endif
8327b36286aSmartynas 						;
8331a653cbcSmartynas 					word1(&rv) = 0;
8347b36286aSmartynas #ifdef Avoid_Underflow
8357b36286aSmartynas 					dsign = 0;
8367b36286aSmartynas #endif
8377b36286aSmartynas 					break;
8387b36286aSmartynas 					}
8397b36286aSmartynas 				}
8401a653cbcSmartynas 			else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
8417b36286aSmartynas  drop_down:
8427b36286aSmartynas 				/* boundary case -- decrement exponent */
8437b36286aSmartynas #ifdef Sudden_Underflow /*{{*/
8441a653cbcSmartynas 				L = word0(&rv) & Exp_mask;
8457b36286aSmartynas #ifdef IBM
8467b36286aSmartynas 				if (L <  Exp_msk1)
8477b36286aSmartynas #else
8487b36286aSmartynas #ifdef Avoid_Underflow
8497b36286aSmartynas 				if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
8507b36286aSmartynas #else
8517b36286aSmartynas 				if (L <= Exp_msk1)
8527b36286aSmartynas #endif /*Avoid_Underflow*/
8537b36286aSmartynas #endif /*IBM*/
8547b36286aSmartynas 					goto undfl;
8557b36286aSmartynas 				L -= Exp_msk1;
8567b36286aSmartynas #else /*Sudden_Underflow}{*/
8577b36286aSmartynas #ifdef Avoid_Underflow
8587b36286aSmartynas 				if (scale) {
8591a653cbcSmartynas 					L = word0(&rv) & Exp_mask;
8607b36286aSmartynas 					if (L <= (2*P+1)*Exp_msk1) {
8617b36286aSmartynas 						if (L > (P+2)*Exp_msk1)
8627b36286aSmartynas 							/* round even ==> */
8637b36286aSmartynas 							/* accept rv */
8647b36286aSmartynas 							break;
8657b36286aSmartynas 						/* rv = smallest denormal */
8667b36286aSmartynas 						goto undfl;
8677b36286aSmartynas 						}
8687b36286aSmartynas 					}
8697b36286aSmartynas #endif /*Avoid_Underflow*/
8701a653cbcSmartynas 				L = (word0(&rv) & Exp_mask) - Exp_msk1;
871aad11945Smartynas #endif /*Sudden_Underflow}}*/
8721a653cbcSmartynas 				word0(&rv) = L | Bndry_mask1;
8731a653cbcSmartynas 				word1(&rv) = 0xffffffff;
8747b36286aSmartynas #ifdef IBM
8757b36286aSmartynas 				goto cont;
8767b36286aSmartynas #else
8777b36286aSmartynas 				break;
8787b36286aSmartynas #endif
8797b36286aSmartynas 				}
8807b36286aSmartynas #ifndef ROUND_BIASED
8811a653cbcSmartynas #ifdef Avoid_Underflow
8821a653cbcSmartynas 			if (Lsb1) {
8831a653cbcSmartynas 				if (!(word0(&rv) & Lsb1))
8841a653cbcSmartynas 					break;
8851a653cbcSmartynas 				}
8861a653cbcSmartynas 			else if (!(word1(&rv) & Lsb))
8871a653cbcSmartynas 				break;
8881a653cbcSmartynas #else
8891a653cbcSmartynas 			if (!(word1(&rv) & LSB))
8907b36286aSmartynas 				break;
8917b36286aSmartynas #endif
8921a653cbcSmartynas #endif
8937b36286aSmartynas 			if (dsign)
8941a653cbcSmartynas #ifdef Avoid_Underflow
8951a653cbcSmartynas 				dval(&rv) += sulp(&rv, scale);
8961a653cbcSmartynas #else
8971a653cbcSmartynas 				dval(&rv) += ulp(&rv);
8981a653cbcSmartynas #endif
8997b36286aSmartynas #ifndef ROUND_BIASED
9007b36286aSmartynas 			else {
9011a653cbcSmartynas #ifdef Avoid_Underflow
9021a653cbcSmartynas 				dval(&rv) -= sulp(&rv, scale);
9031a653cbcSmartynas #else
9041a653cbcSmartynas 				dval(&rv) -= ulp(&rv);
9051a653cbcSmartynas #endif
9067b36286aSmartynas #ifndef Sudden_Underflow
9071a653cbcSmartynas 				if (!dval(&rv))
9087b36286aSmartynas 					goto undfl;
9097b36286aSmartynas #endif
9107b36286aSmartynas 				}
9117b36286aSmartynas #ifdef Avoid_Underflow
9127b36286aSmartynas 			dsign = 1 - dsign;
9137b36286aSmartynas #endif
9147b36286aSmartynas #endif
9157b36286aSmartynas 			break;
9167b36286aSmartynas 			}
9177b36286aSmartynas 		if ((aadj = ratio(delta, bs)) <= 2.) {
9187b36286aSmartynas 			if (dsign)
9191a653cbcSmartynas 				aadj = dval(&aadj1) = 1.;
9201a653cbcSmartynas 			else if (word1(&rv) || word0(&rv) & Bndry_mask) {
9217b36286aSmartynas #ifndef Sudden_Underflow
9221a653cbcSmartynas 				if (word1(&rv) == Tiny1 && !word0(&rv))
9237b36286aSmartynas 					goto undfl;
9247b36286aSmartynas #endif
9257b36286aSmartynas 				aadj = 1.;
9261a653cbcSmartynas 				dval(&aadj1) = -1.;
9277b36286aSmartynas 				}
9287b36286aSmartynas 			else {
9297b36286aSmartynas 				/* special case -- power of FLT_RADIX to be */
9307b36286aSmartynas 				/* rounded down... */
9317b36286aSmartynas 
9327b36286aSmartynas 				if (aadj < 2./FLT_RADIX)
9337b36286aSmartynas 					aadj = 1./FLT_RADIX;
9347b36286aSmartynas 				else
9357b36286aSmartynas 					aadj *= 0.5;
9361a653cbcSmartynas 				dval(&aadj1) = -aadj;
9377b36286aSmartynas 				}
9387b36286aSmartynas 			}
9397b36286aSmartynas 		else {
9407b36286aSmartynas 			aadj *= 0.5;
9411a653cbcSmartynas 			dval(&aadj1) = dsign ? aadj : -aadj;
9427b36286aSmartynas #ifdef Check_FLT_ROUNDS
9437b36286aSmartynas 			switch(Rounding) {
9447b36286aSmartynas 				case 2: /* towards +infinity */
9451a653cbcSmartynas 					dval(&aadj1) -= 0.5;
9467b36286aSmartynas 					break;
9477b36286aSmartynas 				case 0: /* towards 0 */
9487b36286aSmartynas 				case 3: /* towards -infinity */
9491a653cbcSmartynas 					dval(&aadj1) += 0.5;
9507b36286aSmartynas 				}
9517b36286aSmartynas #else
9527b36286aSmartynas 			if (Flt_Rounds == 0)
9531a653cbcSmartynas 				dval(&aadj1) += 0.5;
9547b36286aSmartynas #endif /*Check_FLT_ROUNDS*/
9557b36286aSmartynas 			}
9561a653cbcSmartynas 		y = word0(&rv) & Exp_mask;
9577b36286aSmartynas 
9587b36286aSmartynas 		/* Check for overflow */
9597b36286aSmartynas 
9607b36286aSmartynas 		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
9611a653cbcSmartynas 			dval(&rv0) = dval(&rv);
9621a653cbcSmartynas 			word0(&rv) -= P*Exp_msk1;
9631a653cbcSmartynas 			dval(&adj) = dval(&aadj1) * ulp(&rv);
9641a653cbcSmartynas 			dval(&rv) += dval(&adj);
9651a653cbcSmartynas 			if ((word0(&rv) & Exp_mask) >=
9667b36286aSmartynas 					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
9671a653cbcSmartynas 				if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
9687b36286aSmartynas 					goto ovfl;
9691a653cbcSmartynas 				word0(&rv) = Big0;
9701a653cbcSmartynas 				word1(&rv) = Big1;
9717b36286aSmartynas 				goto cont;
9727b36286aSmartynas 				}
9737b36286aSmartynas 			else
9741a653cbcSmartynas 				word0(&rv) += P*Exp_msk1;
9757b36286aSmartynas 			}
9767b36286aSmartynas 		else {
9777b36286aSmartynas #ifdef Avoid_Underflow
9787b36286aSmartynas 			if (scale && y <= 2*P*Exp_msk1) {
9797b36286aSmartynas 				if (aadj <= 0x7fffffff) {
9807b36286aSmartynas 					if ((z = aadj) <= 0)
9817b36286aSmartynas 						z = 1;
9827b36286aSmartynas 					aadj = z;
9831a653cbcSmartynas 					dval(&aadj1) = dsign ? aadj : -aadj;
9847b36286aSmartynas 					}
9851a653cbcSmartynas 				word0(&aadj1) += (2*P+1)*Exp_msk1 - y;
9867b36286aSmartynas 				}
9871a653cbcSmartynas 			dval(&adj) = dval(&aadj1) * ulp(&rv);
9881a653cbcSmartynas 			dval(&rv) += dval(&adj);
9897b36286aSmartynas #else
9907b36286aSmartynas #ifdef Sudden_Underflow
9911a653cbcSmartynas 			if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
9921a653cbcSmartynas 				dval(&rv0) = dval(&rv);
9931a653cbcSmartynas 				word0(&rv) += P*Exp_msk1;
9941a653cbcSmartynas 				dval(&adj) = dval(&aadj1) * ulp(&rv);
9951a653cbcSmartynas 				dval(&rv) += dval(&adj);
9967b36286aSmartynas #ifdef IBM
9971a653cbcSmartynas 				if ((word0(&rv) & Exp_mask) <  P*Exp_msk1)
9987b36286aSmartynas #else
9991a653cbcSmartynas 				if ((word0(&rv) & Exp_mask) <= P*Exp_msk1)
10007b36286aSmartynas #endif
10017b36286aSmartynas 					{
10021a653cbcSmartynas 					if (word0(&rv0) == Tiny0
10031a653cbcSmartynas 					 && word1(&rv0) == Tiny1)
10047b36286aSmartynas 						goto undfl;
10051a653cbcSmartynas 					word0(&rv) = Tiny0;
10061a653cbcSmartynas 					word1(&rv) = Tiny1;
10077b36286aSmartynas 					goto cont;
10087b36286aSmartynas 					}
10097b36286aSmartynas 				else
10101a653cbcSmartynas 					word0(&rv) -= P*Exp_msk1;
10117b36286aSmartynas 				}
10127b36286aSmartynas 			else {
10131a653cbcSmartynas 				dval(&adj) = dval(&aadj1) * ulp(&rv);
10141a653cbcSmartynas 				dval(&rv) += dval(&adj);
10157b36286aSmartynas 				}
10167b36286aSmartynas #else /*Sudden_Underflow*/
10171a653cbcSmartynas 			/* Compute dval(&adj) so that the IEEE rounding rules will
10181a653cbcSmartynas 			 * correctly round rv + dval(&adj) in some half-way cases.
10191a653cbcSmartynas 			 * If rv * ulp(&rv) is denormalized (i.e.,
10207b36286aSmartynas 			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
10217b36286aSmartynas 			 * trouble from bits lost to denormalization;
10227b36286aSmartynas 			 * example: 1.2e-307 .
10237b36286aSmartynas 			 */
10247b36286aSmartynas 			if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
10251a653cbcSmartynas 				dval(&aadj1) = (double)(int)(aadj + 0.5);
10267b36286aSmartynas 				if (!dsign)
10271a653cbcSmartynas 					dval(&aadj1) = -dval(&aadj1);
10287b36286aSmartynas 				}
10291a653cbcSmartynas 			dval(&adj) = dval(&aadj1) * ulp(&rv);
10301a653cbcSmartynas 			dval(&rv) += adj;
10317b36286aSmartynas #endif /*Sudden_Underflow*/
10327b36286aSmartynas #endif /*Avoid_Underflow*/
10337b36286aSmartynas 			}
10341a653cbcSmartynas 		z = word0(&rv) & Exp_mask;
10357b36286aSmartynas #ifndef SET_INEXACT
10367b36286aSmartynas #ifdef Avoid_Underflow
10377b36286aSmartynas 		if (!scale)
10387b36286aSmartynas #endif
10397b36286aSmartynas 		if (y == z) {
10407b36286aSmartynas 			/* Can we stop now? */
10417b36286aSmartynas 			L = (Long)aadj;
10427b36286aSmartynas 			aadj -= L;
10437b36286aSmartynas 			/* The tolerances below are conservative. */
10441a653cbcSmartynas 			if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
10457b36286aSmartynas 				if (aadj < .4999999 || aadj > .5000001)
10467b36286aSmartynas 					break;
10477b36286aSmartynas 				}
10487b36286aSmartynas 			else if (aadj < .4999999/FLT_RADIX)
10497b36286aSmartynas 				break;
10507b36286aSmartynas 			}
10517b36286aSmartynas #endif
10527b36286aSmartynas  cont:
10537b36286aSmartynas 		Bfree(bb);
10547b36286aSmartynas 		Bfree(bd);
10557b36286aSmartynas 		Bfree(bs);
10567b36286aSmartynas 		Bfree(delta);
10577b36286aSmartynas 		}
10581a653cbcSmartynas 	Bfree(bb);
10591a653cbcSmartynas 	Bfree(bd);
10601a653cbcSmartynas 	Bfree(bs);
10611a653cbcSmartynas 	Bfree(bd0);
10621a653cbcSmartynas 	Bfree(delta);
10637b36286aSmartynas #ifdef SET_INEXACT
10647b36286aSmartynas 	if (inexact) {
10657b36286aSmartynas 		if (!oldinexact) {
10661a653cbcSmartynas 			word0(&rv0) = Exp_1 + (70 << Exp_shift);
10671a653cbcSmartynas 			word1(&rv0) = 0;
10681a653cbcSmartynas 			dval(&rv0) += 1.;
10697b36286aSmartynas 			}
10707b36286aSmartynas 		}
10717b36286aSmartynas 	else if (!oldinexact)
10727b36286aSmartynas 		clear_inexact();
10737b36286aSmartynas #endif
10747b36286aSmartynas #ifdef Avoid_Underflow
10757b36286aSmartynas 	if (scale) {
10761a653cbcSmartynas 		word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
10771a653cbcSmartynas 		word1(&rv0) = 0;
10781a653cbcSmartynas 		dval(&rv) *= dval(&rv0);
10797b36286aSmartynas #ifndef NO_ERRNO
10807b36286aSmartynas 		/* try to avoid the bug of testing an 8087 register value */
1081aad11945Smartynas #ifdef IEEE_Arith
10821a653cbcSmartynas 		if (!(word0(&rv) & Exp_mask))
1083aad11945Smartynas #else
10841a653cbcSmartynas 		if (word0(&rv) == 0 && word1(&rv) == 0)
1085aad11945Smartynas #endif
10867b36286aSmartynas 			errno = ERANGE;
10877b36286aSmartynas #endif
10887b36286aSmartynas 		}
10897b36286aSmartynas #endif /* Avoid_Underflow */
10907b36286aSmartynas #ifdef SET_INEXACT
10911a653cbcSmartynas 	if (inexact && !(word0(&rv) & Exp_mask)) {
10927b36286aSmartynas 		/* set underflow bit */
10931a653cbcSmartynas 		dval(&rv0) = 1e-300;
10941a653cbcSmartynas 		dval(&rv0) *= dval(&rv0);
10957b36286aSmartynas 		}
10967b36286aSmartynas #endif
10977b36286aSmartynas  ret:
10987b36286aSmartynas 	if (se)
10997b36286aSmartynas 		*se = (char *)s;
11001a653cbcSmartynas 	return sign ? -dval(&rv) : dval(&rv);
11017b36286aSmartynas 	}
11020d943ef0Sguenther DEF_STRONG(strtod);
1103