Contiki 2.6

small_strtod.c

00001 /*
00002 FUNCTON
00003         <<strtod>>, <<strtof>>---string to double or float
00004 
00005 INDEX
00006         strtod
00007 INDEX
00008         _strtod_r
00009 INDEX
00010         strtof
00011 
00012 ANSI_SYNOPSIS
00013         #include <stdlib.h>
00014         double strtod(const char *<[str]>, char **<[tail]>);
00015         float strtof(const char *<[str]>, char **<[tail]>);
00016 
00017         double _strtod_r(void *<[reent]>, 
00018                          const char *<[str]>, char **<[tail]>);
00019 
00020 TRAD_SYNOPSIS
00021         #include <stdlib.h>
00022         double strtod(<[str]>,<[tail]>)
00023         char *<[str]>;
00024         char **<[tail]>;
00025 
00026         float strtof(<[str]>,<[tail]>)
00027         char *<[str]>;
00028         char **<[tail]>;
00029 
00030         double _strtod_r(<[reent]>,<[str]>,<[tail]>)
00031         char *<[reent]>;
00032         char *<[str]>;
00033         char **<[tail]>;
00034 
00035 DESCRIPTION
00036         The function <<strtod>> parses the character string <[str]>,
00037         producing a substring which can be converted to a double
00038         value.  The substring converted is the longest initial
00039         subsequence of <[str]>, beginning with the first
00040         non-whitespace character, that has the format:
00041         .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>] 
00042         The substring contains no characters if <[str]> is empty, consists
00043         entirely of whitespace, or if the first non-whitespace
00044         character is something other than <<+>>, <<->>, <<.>>, or a
00045         digit. If the substring is empty, no conversion is done, and
00046         the value of <[str]> is stored in <<*<[tail]>>>.  Otherwise,
00047         the substring is converted, and a pointer to the final string
00048         (which will contain at least the terminating null character of
00049         <[str]>) is stored in <<*<[tail]>>>.  If you want no
00050         assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>.
00051         <<strtof>> is identical to <<strtod>> except for its return type.
00052 
00053         This implementation returns the nearest machine number to the
00054         input decimal string.  Ties are broken by using the IEEE
00055         round-even rule.
00056 
00057         The alternate function <<_strtod_r>> is a reentrant version.
00058         The extra argument <[reent]> is a pointer to a reentrancy structure.
00059 
00060 RETURNS
00061         <<strtod>> returns the converted substring value, if any.  If
00062         no conversion could be performed, 0 is returned.  If the
00063         correct value is out of the range of representable values,
00064         plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is
00065         stored in errno. If the correct value would cause underflow, 0
00066         is returned and <<ERANGE>> is stored in errno.
00067 
00068 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
00069 <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
00070 */
00071 
00072 /****************************************************************
00073  *
00074  * The author of this software is David M. Gay.
00075  *
00076  * Copyright (c) 1991 by AT&T.
00077  *
00078  * Permission to use, copy, modify, and distribute this software for any
00079  * purpose without fee is hereby granted, provided that this entire notice
00080  * is included in all copies of any software which is or includes a copy
00081  * or modification of this software and in all copies of the supporting
00082  * documentation for such software.
00083  *
00084  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
00085  * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
00086  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
00087  * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
00088  *
00089  ***************************************************************/
00090 
00091 /* Please send bug reports to
00092         David M. Gay
00093         AT&T Bell Laboratories, Room 2C-463
00094         600 Mountain Avenue
00095         Murray Hill, NJ 07974-2070
00096         U.S.A.
00097         dmg@research.att.com or research!dmg
00098  */
00099 
00100 
00101 /* Scanf and printf call both the small_mprec.c file if small_scanf 
00102   * has not been specfied optimizations concerning small_mprec.c and
00103   * call of balloc will be performed anyway for scanf. 
00104   */
00105  
00106 #ifdef _SMALL_PRINTF
00107 #ifndef SMALL_SCANF 
00108 #define SMALL_SCANF 
00109 #endif
00110 #endif
00111 
00112 
00113 #include <_ansi.h>
00114 #include <reent.h>
00115 #include <string.h>
00116 #include "small_mprec.h"
00117 
00118 double
00119 _DEFUN (_strtod_r, (ptr, s00, se),
00120         struct _reent *ptr _AND
00121         _CONST char *s00 _AND
00122         char **se)
00123 {
00124   int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e1, esign, i, j,
00125     k, nd, nd0, nf, nz, nz0, sign;
00126   long e;
00127   _CONST char *s, *s0, *s1;
00128   double aadj, aadj1, adj;
00129   long L;
00130   unsigned long z;
00131   __ULong y;
00132   union double_union rv, rv0;
00133 
00134   _Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
00135   
00136   #ifdef SMALL_SCANF
00137   
00138   /*  
00139    *    For the SMALL_SCANF implementation for floating points numbers :  
00140         *  - To avoid the call of allocator we defined a buffer for each variable : instead of taking the adress 
00141         *  provided by Balloc variables are initialized to the beginning of the array.
00142         *       - For some variables many buffers have been declared, in fact for each call of small_lshift we used a 
00143         *  buffer that has not been used at the moment 
00144    *  - This buffers are used in the call of function declared in small_mprec.h 
00145    *  To have more informations look at small_mprec.c 
00146    */
00147   
00148   
00149   
00150   #define BUF_SIZE 32
00151   #define BUF_LSHIFT_SIZE 40
00152   
00153   _Bigint tab_bb[BUF_LSHIFT_SIZE],tab_bb1[BUF_SIZE],tab_bd[BUF_SIZE],tab_bd0[BUF_SIZE],tab_bs[BUF_LSHIFT_SIZE], tab_delta[BUF_LSHIFT_SIZE];
00154   _Bigint tab_bblshift[BUF_LSHIFT_SIZE],tab_bslshift[BUF_LSHIFT_SIZE], tab_deltalshift[BUF_LSHIFT_SIZE],tab_bdlshift[BUF_LSHIFT_SIZE];
00155   #endif
00156   
00157   sign = nz0 = nz = 0;
00158   rv.d = 0.;
00159   for (s = s00;; s++)
00160     switch (*s)
00161       {
00162       case '-':
00163         sign = 1;
00164         /* no break */
00165       case '+':
00166         if (*++s)
00167           goto break2;
00168         /* no break */
00169       case 0:
00170         s = s00;
00171         goto ret;
00172       case '\t':
00173       case '\n':
00174       case '\v':
00175       case '\f':
00176       case '\r':
00177       case ' ':
00178         continue;
00179       default:
00180         goto break2;
00181       }
00182 break2:
00183   if (*s == '0')
00184     {
00185       nz0 = 1;
00186       while (*++s == '0');
00187       if (!*s)
00188         goto ret;
00189     }
00190   s0 = s;
00191   y = z = 0;
00192   for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
00193     if (nd < 9)
00194       y = 10 * y + c - '0';
00195     else if (nd < 16)
00196       z = 10 * z + c - '0';
00197   nd0 = nd;
00198   if (c == '.')
00199     {
00200       c = *++s;
00201       if (!nd)
00202         {
00203           for (; c == '0'; c = *++s)
00204             nz++;
00205           if (c > '0' && c <= '9')
00206             {
00207               s0 = s;
00208               nf += nz;
00209               nz = 0;
00210               goto have_dig;
00211             }
00212           goto dig_done;
00213         }
00214       for (; c >= '0' && c <= '9'; c = *++s)
00215         {
00216         have_dig:
00217           nz++;
00218           if (c -= '0')
00219             {
00220               nf += nz;
00221               for (i = 1; i < nz; i++)
00222                 if (nd++ < 9)
00223                   y *= 10;
00224                 else if (nd <= DBL_DIG + 1)
00225                   z *= 10;
00226               if (nd++ < 9)
00227                 y = 10 * y + c;
00228               else if (nd <= DBL_DIG + 1)
00229                 z = 10 * z + c;
00230               nz = 0;
00231             }
00232         }
00233     }
00234 dig_done:
00235   e = 0;
00236   if (c == 'e' || c == 'E')
00237     {
00238       if (!nd && !nz && !nz0)
00239         {
00240           s = s00;
00241           goto ret;
00242         }
00243       s00 = s;
00244       esign = 0;
00245       switch (c = *++s)
00246         {
00247         case '-':
00248           esign = 1;
00249         case '+':
00250           c = *++s;
00251         }
00252       if (c >= '0' && c <= '9')
00253         {
00254           while (c == '0')
00255             c = *++s;
00256           if (c > '0' && c <= '9')
00257             {
00258               e = c - '0';
00259               s1 = s;
00260               while ((c = *++s) >= '0' && c <= '9')
00261                 e = 10 * e + c - '0';
00262               if (s - s1 > 8)
00263                 /* Avoid confusion from exponents
00264                  * so large that e might overflow.
00265                  */
00266                 e = 9999999L;
00267               if (esign)
00268                 e = -e;
00269             }
00270           else
00271             e = 0;
00272         }
00273       else
00274         s = s00;
00275     }
00276   if (!nd)
00277     {
00278       if (!nz && !nz0)
00279         s = s00;
00280       goto ret;
00281     }
00282   e1 = e -= nf;
00283 
00284   /* Now we have nd0 digits, starting at s0, followed by a
00285    * decimal point, followed by nd-nd0 digits.  The number we're
00286    * after is the integer represented by those digits times
00287    * 10**e */
00288 
00289   if (!nd0)
00290     nd0 = nd;
00291   k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
00292   rv.d = y;
00293   if (k > 9)
00294     #ifndef SMALL_SCANF
00295     rv.d = tens[k - 9] * rv.d + z;
00296     #else
00297     rv.d = small_tens[k - 9] * rv.d + z;
00298     #endif
00299   bd0 = 0;
00300   if (nd <= DBL_DIG
00301 #ifndef RND_PRODQUOT
00302       && FLT_ROUNDS == 1
00303 #endif
00304     )
00305     {
00306       if (!e)
00307         goto ret;
00308       if (e > 0)
00309         {
00310           if (e <= Ten_pmax)
00311             {
00312 #ifdef VAX
00313               goto vax_ovfl_check;
00314 #else
00315               #ifndef SMALL_SCANF
00316               /* rv.d = */ rounded_product (rv.d, tens[e]);
00317               #else
00318               rounded_product (rv.d, small_tens[e]);
00319               #endif
00320               goto ret;
00321 #endif
00322             }
00323           i = DBL_DIG - nd;
00324           if (e <= Ten_pmax + i)
00325             {
00326               /* A fancier test would sometimes let us do
00327                                  * this for larger i values.
00328                                  */
00329               e -= i;
00330               #ifndef SMALL_SCANF
00331               rv.d *= tens[i];
00332               #else
00333               rv.d *= small_tens[i];
00334               #endif
00335 #ifdef VAX
00336               /* VAX exponent range is so narrow we must
00337                * worry about overflow here...
00338                */
00339             vax_ovfl_check:
00340               word0 (rv) -= P * Exp_msk1;
00341                #ifndef SMALL_SCANF
00342               /* rv.d = */ rounded_product (rv.d, tens[e]);
00343               #else 
00344               /* rv.d = */ rounded_product (rv.d, small_tens[e]);
00345               #endif
00346               if ((word0 (rv) & Exp_mask)
00347                   > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
00348                 goto ovfl;
00349               word0 (rv) += P * Exp_msk1;
00350 #else
00351                #ifndef SMALL_SCANF
00352               /* rv.d = */ rounded_product (rv.d, tens[e]);
00353               #else 
00354               /* rv.d = */ rounded_product (rv.d, small_tens[e]);
00355               #endif
00356 #endif
00357               goto ret;
00358             }
00359         }
00360 #ifndef Inaccurate_Divide
00361       else if (e >= -Ten_pmax)
00362         {
00363           #ifndef SMALL_SCANF
00364           /* rv.d = */ rounded_quotient (rv.d, tens[-e]);
00365           #else
00366           /* rv.d = */ rounded_quotient (rv.d, small_tens[-e]);
00367           #endif
00368           goto ret;
00369         }
00370 #endif
00371     }
00372   e1 += nd - k;
00373 
00374   /* Get starting approximation = rv.d * 10**e1 */
00375 
00376   if (e1 > 0)
00377     {
00378       if ((i = e1 & 15) != 0)
00379    #ifndef SMALL_SCANF   
00380         rv.d *= tens[i];
00381         #else
00382         rv.d *= small_tens[i];
00383         #endif
00384       if (e1 &= ~15)
00385         {
00386           if (e1 > DBL_MAX_10_EXP)
00387             {
00388             ovfl:
00389               ptr->_errno = ERANGE;
00390 #ifdef _HAVE_STDC
00391               rv.d = HUGE_VAL;
00392 #else
00393               /* Can't trust HUGE_VAL */
00394 #ifdef IEEE_Arith
00395               word0 (rv) = Exp_mask;
00396 #ifndef _DOUBLE_IS_32BITS
00397               word1 (rv) = 0;
00398 #endif
00399 #else
00400               word0 (rv) = Big0;
00401 #ifndef _DOUBLE_IS_32BITS
00402               word1 (rv) = Big1;
00403 #endif
00404 #endif
00405 #endif
00406               if (bd0)
00407                 goto retfree;
00408               goto ret;
00409             }
00410           if (e1 >>= 4)
00411             {
00412               for (j = 0; e1 > 1; j++, e1 >>= 1)
00413                 if (e1 & 1)
00414                   #ifndef SMALL_SCANF
00415                   rv.d *= bigtens[j];
00416                   #else
00417                   rv.d *= small_bigtens[j];
00418                   #endif
00419                   
00420               /* The last multiplication could overflow. */
00421               word0 (rv) -= P * Exp_msk1;
00422               #ifndef SMALL_SCANF
00423                   rv.d *= bigtens[j];
00424                   #else
00425                   rv.d *= small_bigtens[j];
00426                   #endif
00427                   
00428               if ((z = word0 (rv) & Exp_mask)
00429                   > Exp_msk1 * (DBL_MAX_EXP + Bias - P))
00430                 goto ovfl;
00431               if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
00432                 {
00433                   /* set to largest number */
00434                   /* (Can't trust DBL_MAX) */
00435                   word0 (rv) = Big0;
00436 #ifndef _DOUBLE_IS_32BITS
00437                   word1 (rv) = Big1;
00438 #endif
00439                 }
00440               else
00441                 word0 (rv) += P * Exp_msk1;
00442             }
00443 
00444         }
00445     }
00446   else if (e1 < 0)
00447     {
00448       e1 = -e1;
00449       if ((i = e1 & 15) != 0)
00450    #ifndef SMALL_SCANF
00451         rv.d /= tens[i];
00452         #else
00453         rv.d /= small_tens[i];
00454         #endif
00455       if (e1 &= ~15)
00456         {
00457           e1 >>= 4;
00458           if (e1 >= 1 << n_bigtens)
00459             goto undfl;
00460           for (j = 0; e1 > 1; j++, e1 >>= 1)
00461             if (e1 & 1)
00462               #ifndef SMALL_SCANF
00463               rv.d *= tinytens[j];
00464           /* The last multiplication could underflow. */
00465           rv0.d = rv.d;
00466           rv.d *=tinytens[j];
00467              #else
00468               rv.d *= small_tinytens[j];
00469           /* The last multiplication could underflow. */
00470           rv0.d = rv.d;
00471           rv.d *= small_tinytens[j];
00472              #endif
00473           if (!rv.d)
00474             {
00475               rv.d = 2. * rv0.d;
00476               #ifndef SMALL_SCANF
00477               rv.d *= tinytens[j];
00478               #else 
00479               rv.d *= small_tinytens[j];
00480               #endif
00481               if (!rv.d)
00482                 {
00483                 undfl:
00484                   rv.d = 0.;
00485                   ptr->_errno = ERANGE;
00486                   if (bd0)
00487                     goto retfree;
00488                   goto ret;
00489                 }
00490 #ifndef _DOUBLE_IS_32BITS
00491               word0 (rv) = Tiny0;
00492               word1 (rv) = Tiny1;
00493 #else
00494               word0 (rv) = Tiny1;
00495 #endif
00496               /* The refinement below will clean
00497                * this approximation up.
00498                */
00499             }
00500         }
00501     }
00502 
00503   /* Now the hard part -- adjusting rv to the correct value.*/
00504 
00505   /* Put digits into bd: true value = bd * 10^e */
00506   #ifndef SMALL_SCANF
00507   bd0 = s2b (ptr, s0, nd0, nd, y);
00508   #else
00509   bd0 = small_s2b(ptr,s0, nd0, nd, y, &tab_bd0[0]);
00510   #endif
00511 
00512   for (;;)
00513     {
00514       #ifndef SMALL_SCANF
00515       bd = Balloc (ptr, bd0->_k);
00516       #else
00517       bd = &tab_bd[0];
00518       bd->_k = bd0->_k;
00519       bd->_maxwds = 1 << (bd0->_k);
00520       bd->_sign = bd->_wds =0;
00521      
00522       #endif
00523       Bcopy (bd, bd0);
00524       #ifndef SMALL_SCANF
00525       bb = d2b (ptr, rv.d, &bbe, &bbbits);      /* rv.d = bb * 2^bbe */
00526       bs = i2b (ptr, 1);
00527       #else
00528       bb = small_d2b (ptr, rv.d, &bbe, &bbbits, &tab_bb[0]);    /* rv.d = bb * 2^bbe */
00529       bs = small_i2b (ptr, 1, &tab_bs[0]); 
00530       #endif
00531       if (e >= 0)
00532         {
00533           bb2 = bb5 = 0;
00534           bd2 = bd5 = e;
00535         }
00536       else
00537         {
00538           bb2 = bb5 = -e;
00539           bd2 = bd5 = 0;
00540         }
00541       if (bbe >= 0)
00542         bb2 += bbe;
00543       else
00544         bd2 -= bbe;
00545       bs2 = bb2;
00546 #ifdef Sudden_Underflow
00547 #ifdef IBM
00548       j = 1 + 4 * P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
00549 #else
00550       j = P + 1 - bbbits;
00551 #endif
00552 #else
00553       i = bbe + bbbits - 1;     /* logb(rv.d) */
00554       if (i < Emin)             /* denormal */
00555         j = bbe + (P - Emin);
00556       else
00557         j = P + 1 - bbbits;
00558 #endif
00559       bb2 += j;
00560       bd2 += j;
00561       i = bb2 < bd2 ? bb2 : bd2;
00562       if (i > bs2)
00563         i = bs2;
00564       if (i > 0)
00565         {
00566           bb2 -= i;
00567           bd2 -= i;
00568           bs2 -= i;
00569         }
00570       if (bb5 > 0)
00571         {
00572           #ifndef SMALL_SCANF
00573           bs = pow5mult (ptr, bs, bb5);
00574           bb1 = mult (ptr, bs, bb);
00575           Bfree (ptr, bb);
00576           bb = bb1;
00577           #else
00578           if (bs == &tab_bs[0]){
00579           bs = small_pow5mult (ptr, bs, bb5,&tab_bslshift[0]);
00580           }
00581           else{
00582           bs = small_pow5mult (ptr, bs, bb5,&tab_bs[0]);
00583           }
00584           bb1 = small_mult (ptr, bs, bb,&tab_bb1[0]);
00585           bb = bb1;
00586           #endif
00587           
00588         }
00589         
00590         #ifndef SMALL_SCANF
00591       if (bb2 > 0)
00592         bb = lshift (ptr, bb, bb2);
00593       if (bd5 > 0)
00594         bd = pow5mult (ptr, bd, bd5);
00595       if (bd2 > 0)
00596         bd = lshift (ptr, bd, bd2);
00597       if (bs2 > 0)
00598         bs = lshift (ptr, bs, bs2);
00599       delta = diff (ptr, bb, bd);
00600       dsign = delta->_sign;
00601       delta->_sign = 0;
00602       i = cmp (delta, bs);
00603   #else
00604   if (bb2 > 0){
00605         if (bb == &tab_bb[0] ){
00606                         bb = small_lshift (ptr, bb, bb2,&tab_bblshift[0]);
00607                 }
00608                 else {
00609                 bb = small_lshift (ptr, bb, bb2,&tab_bblshift[0]);
00610                 }
00611   }     
00612    if (bd5 > 0){
00613                 if (bd == &tab_bd[0]){
00614                         bd = small_pow5mult (ptr, bd, bd5, &tab_bdlshift[0]);
00615         }
00616         else{
00617                         bd = small_pow5mult (ptr, bd, bd5, &tab_bd[0]);
00618                 }
00619         }
00620    if (bd2 > 0){
00621         if (bd == &tab_bd[0] ){
00622                         bd = small_lshift (ptr, bb, bd2,&tab_bdlshift[0]);
00623                 }
00624                 else {
00625                         bd = small_lshift (ptr, bd, bd2,&tab_bd[0]);
00626                 }
00627    } 
00628    if (bs2 > 0){
00629         if ( bs == &tab_bs[0] ){
00630                         bs = small_lshift (ptr, bs, bs2,&tab_bslshift[0]);
00631             }
00632         else{
00633               bs = small_lshift (ptr, bs, bs2,&tab_bs[0]);
00634         }
00635    }
00636       
00637       delta = small_diff (ptr, bb, bd,&tab_delta[0]);      
00638       dsign = delta->_sign;
00639       delta->_sign = 0;   
00640       i = small_cmp (delta, bs);
00641 
00642   #endif
00643       if (i < 0)
00644         {
00645           /* Error is less than half an ulp -- check for
00646            * special case of mantissa a power of two.
00647            */
00648           if (dsign || word1 (rv) || word0 (rv) & Bndry_mask)
00649             break;
00650             
00651           #ifndef SMALL_SCANF  
00652           delta = lshift (ptr, delta, Log2P);
00653           if (cmp (delta, bs) > 0)
00654             goto drop_down;
00655           #else
00656                 if (delta == &tab_delta[0]){
00657                         delta = small_lshift (ptr, delta, Log2P,&tab_deltalshift[0]);
00658            }
00659            else{
00660              delta = small_lshift (ptr, delta, Log2P,&tab_delta[0]);
00661            }
00662            if (small_cmp (delta, bs) > 0)
00663             goto drop_down;     
00664           #endif
00665           break;
00666         }
00667       if (i == 0)
00668         {
00669           /* exactly half-way between */
00670           if (dsign)
00671             {
00672               if ((word0 (rv) & Bndry_mask1) == Bndry_mask1
00673                   && word1 (rv) == 0xffffffff)
00674                 {
00675                   /*boundary case -- increment exponent*/
00676                   word0 (rv) = (word0 (rv) & Exp_mask)
00677                     + Exp_msk1
00678 #ifdef IBM
00679                     | Exp_msk1 >> 4
00680 #endif
00681                     ;
00682 #ifndef _DOUBLE_IS_32BITS
00683                   word1 (rv) = 0;
00684 #endif
00685                   break;
00686                 }
00687             }
00688           else if (!(word0 (rv) & Bndry_mask) && !word1 (rv))
00689             {
00690             drop_down:
00691               /* boundary case -- decrement exponent */
00692 #ifdef Sudden_Underflow
00693               L = word0 (rv) & Exp_mask;
00694 #ifdef IBM
00695               if (L < Exp_msk1)
00696 #else
00697               if (L <= Exp_msk1)
00698 #endif
00699                 goto undfl;
00700               L -= Exp_msk1;
00701 #else
00702               L = (word0 (rv) & Exp_mask) - Exp_msk1;
00703 #endif
00704               word0 (rv) = L | Bndry_mask1;
00705 #ifndef _DOUBLE_IS_32BITS
00706               word1 (rv) = 0xffffffff;
00707 #endif
00708 #ifdef IBM
00709               goto cont;
00710 #else
00711               break;
00712 #endif
00713             }
00714 #ifndef ROUND_BIASED
00715           if (!(word1 (rv) & LSB))
00716             break;
00717 #endif
00718           if (dsign)
00719             #ifndef SMALL_SCANF
00720             rv.d += ulp (rv.d);
00721             #else
00722             rv.d += small_ulp (rv.d);
00723             #endif
00724 #ifndef ROUND_BIASED
00725           else
00726             {
00727             #ifndef SMALL_SCANF
00728             rv.d -= ulp (rv.d);
00729             #else
00730             rv.d -= small_ulp (rv.d);
00731             #endif
00732 #ifndef Sudden_Underflow
00733               if (!rv.d)
00734                 goto undfl;
00735 #endif
00736             }
00737 #endif
00738           break;
00739         }
00740         
00741         #ifndef SMALL_SCANF
00742       if ((aadj = ratio (delta, bs)) <= 2.)
00743         {
00744         #else
00745          if ((aadj = small_ratio (delta, bs)) <= 2.)
00746         {
00747         #endif
00748           if (dsign)
00749             aadj = aadj1 = 1.;
00750           else if (word1 (rv) || word0 (rv) & Bndry_mask)
00751             {
00752 #ifndef Sudden_Underflow
00753               if (word1 (rv) == Tiny1 && !word0 (rv))
00754                 goto undfl;
00755 #endif
00756               aadj = 1.;
00757               aadj1 = -1.;
00758             }
00759           else
00760             {
00761               /* special case -- power of FLT_RADIX to be */
00762               /* rounded down... */
00763 
00764               if (aadj < 2. / FLT_RADIX)
00765                 aadj = 1. / FLT_RADIX;
00766               else
00767                 aadj *= 0.5;
00768               aadj1 = -aadj;
00769             }
00770         }
00771       else
00772         {
00773           aadj *= 0.5;
00774           aadj1 = dsign ? aadj : -aadj;
00775 #ifdef Check_FLT_ROUNDS
00776           switch (FLT_ROUNDS)
00777             {
00778             case 2:             /* towards +infinity */
00779               aadj1 -= 0.5;
00780               break;
00781             case 0:             /* towards 0 */
00782             case 3:             /* towards -infinity */
00783               aadj1 += 0.5;
00784             }
00785 #else
00786           if (FLT_ROUNDS == 0)
00787             aadj1 += 0.5;
00788 #endif
00789         }
00790       y = word0 (rv) & Exp_mask;
00791 
00792       /* Check for overflow */
00793 
00794       if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
00795         {
00796           rv0.d = rv.d;
00797           word0 (rv) -= P * Exp_msk1;
00798           #ifndef SMALL_SCANF
00799           adj = aadj1 * ulp (rv.d);
00800           #else
00801           adj = aadj1 * small_ulp (rv.d);
00802           #endif
00803           rv.d += adj;
00804           if ((word0 (rv) & Exp_mask) >=
00805               Exp_msk1 * (DBL_MAX_EXP + Bias - P))
00806             {
00807               if (word0 (rv0) == Big0 && word1 (rv0) == Big1)
00808                 goto ovfl;
00809 #ifdef _DOUBLE_IS_32BITS
00810               word0 (rv) = Big1;
00811 #else
00812               word0 (rv) = Big0;
00813               word1 (rv) = Big1;
00814 #endif
00815               goto cont;
00816             }
00817           else
00818             word0 (rv) += P * Exp_msk1;
00819         }
00820       else
00821         {
00822 #ifdef Sudden_Underflow
00823           if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
00824             {
00825               rv0.d = rv.d;
00826               word0 (rv) += P * Exp_msk1;
00827               #ifndef SMALL_SCANF
00828                         adj = aadj1 * ulp (rv.d);
00829                         #else
00830                         adj = aadj1 * small_ulp (rv.d);
00831                         #endif
00832               rv.d += adj;
00833         #ifdef IBM
00834               if ((word0 (rv) & Exp_mask) < P * Exp_msk1)
00835         #else
00836               if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
00837         #endif
00838                 {
00839                   if (word0 (rv0) == Tiny0
00840                       && word1 (rv0) == Tiny1)
00841                     goto undfl;
00842                   word0 (rv) = Tiny0;
00843                   word1 (rv) = Tiny1;
00844                   goto cont;
00845                 }
00846               else
00847                 word0 (rv) -= P * Exp_msk1;
00848             }
00849           else
00850             {
00851               #ifndef SMALL_SCANF
00852                         adj = aadj1 * ulp (rv.d);
00853                         #else
00854                         adj = aadj1 * small_ulp (rv.d);
00855                         #endif
00856               rv.d += adj;
00857             }
00858 #else
00859           /* Compute adj so that the IEEE rounding rules will
00860            * correctly round rv.d + adj in some half-way cases.
00861            * If rv.d * ulp(rv.d) is denormalized (i.e.,
00862            * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
00863            * trouble from bits lost to denormalization;
00864            * example: 1.2e-307 .
00865            */
00866           if (y <= (P - 1) * Exp_msk1 && aadj >= 1.)
00867             {
00868               aadj1 = (double) (int) (aadj + 0.5);
00869               if (!dsign)
00870                 aadj1 = -aadj1;
00871             }
00872           #ifndef SMALL_SCANF
00873           adj = aadj1 * ulp (rv.d);       
00874           #else
00875           adj = aadj1 * small_ulp (rv.d);
00876           rv.d += adj;
00877           #endif
00878 #endif
00879         }
00880       z = word0 (rv) & Exp_mask;
00881       if (y == z)
00882         {
00883           /* Can we stop now? */
00884           L = aadj;
00885           aadj -= L;
00886           /* The tolerances below are conservative. */
00887           if (dsign || word1 (rv) || word0 (rv) & Bndry_mask)
00888             {
00889               if (aadj < .4999999 || aadj > .5000001)
00890                 break;
00891             }
00892           else if (aadj < .4999999 / FLT_RADIX)
00893             break;
00894         }
00895     cont:
00896      #ifndef SMALL_SCANF
00897       Bfree (ptr, bb);
00898       Bfree (ptr, bd);
00899       Bfree (ptr, bs);
00900       Bfree (ptr, delta);
00901      #else
00902      ;
00903      #endif
00904     }
00905 retfree:
00906  #ifndef SMALL_SCANF
00907   Bfree (ptr, bb);
00908   Bfree (ptr, bd);
00909   Bfree (ptr, bs);
00910   Bfree (ptr, bd0);
00911   Bfree (ptr, delta);
00912   #endif
00913 ret:
00914   if (se)
00915     *se = (char *) s;
00916   return sign ? -rv.d : rv.d;
00917 }
00918 
00919 #ifndef NO_REENT
00920 
00921 double
00922 _DEFUN (strtod, (s00, se),
00923         _CONST char *s00 _AND char **se)
00924 {
00925   return _strtod_r (_REENT, s00, se);
00926 }
00927 
00928 float
00929 _DEFUN (strtof, (s00, se),
00930         _CONST char *s00 _AND
00931         char **se)
00932 {
00933   return (float)_strtod_r (_REENT, s00, se);
00934 }
00935 
00936 #endif