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