home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / unix / gawk.sit / source / missing.d / strtod.c < prev    next >
Text File  |  1990-07-29  |  2KB  |  118 lines

  1. /*
  2.  * strtod.c
  3.  *
  4.  * Stupid version of System V strtod(3) library routine.
  5.  * Does no overflow/underflow checking.
  6.  *
  7.  * A real number is defined to be
  8.  *    optional leading white space
  9.  *    optional sign
  10.  *    string of digits with optional decimal point
  11.  *    optional 'e' or 'E'
  12.  *        followed by optional sign or space
  13.  *        followed by an integer
  14.  *
  15.  * if ptr is not NULL a pointer to the character terminating the
  16.  * scan is returned in *ptr.  If no number formed, *ptr is set to str
  17.  * and 0 is returned.
  18.  *
  19.  * For speed, we don't do the conversion ourselves.  Instead, we find
  20.  * the end of the number and then call atof() to do the dirty work.
  21.  * This bought us a 10% speedup on a sample program at uunet.uu.net.
  22.  */
  23.  
  24. #include <ctype.h>
  25.  
  26. extern double atof();
  27.  
  28. double
  29. strtod (s, ptr)
  30. register char *s, **ptr;
  31. {
  32.     double ret = 0.0;
  33.     char *start = s;
  34.     char *begin = NULL;
  35.     int success = 0;
  36.  
  37.     /* optional white space */
  38.     while (isspace(*s))
  39.         s++;
  40.  
  41.     /* optional sign */
  42.     if (*s == '+' || *s == '-') {
  43.         s++;
  44.         if (*(s-1) == '-')
  45.             begin = s - 1;
  46.         else
  47.             begin = s;
  48.     }
  49.  
  50.     /* string of digits with optional decimal point */
  51.     if (isdigit(*s) && ! begin)
  52.         begin = s;
  53.  
  54.     while (isdigit(*s)) {
  55.         s++;
  56.         success++;
  57.     }
  58.  
  59.     if (*s == '.') {
  60.         if (! begin)
  61.             begin = s;
  62.         s++;
  63.         while (isdigit(*s))
  64.             s++;
  65.         success++;
  66.     }
  67.  
  68.     if (s == start || success == 0)        /* nothing there */
  69.         goto out;
  70.  
  71.     /*
  72.       *    optional 'e' or 'E'
  73.      *        followed by optional sign or space
  74.      *        followed by an integer
  75.      */
  76.  
  77.     if (*s == 'e' || *s == 'E') {
  78.         s++;
  79.  
  80.         /* XXX - atof probably doesn't allow spaces here */
  81.         while (isspace(*s))
  82.             s++;
  83.  
  84.         if (*s == '+' || *s == '-')
  85.             s++;
  86.  
  87.         while (isdigit(*s))
  88.             s++;
  89.     }
  90.  
  91.     /* go for it */
  92.     ret = atof(begin);
  93.  
  94. out:
  95.     if (! success)
  96.         s = start;    /* in case all we did was skip whitespace */
  97.  
  98.     if (ptr)
  99.         *ptr = s;
  100.  
  101.     return ret;
  102. }
  103.  
  104. #ifdef TEST
  105. main (argc, argv)
  106. int argc;
  107. char **argv;
  108. {
  109.     double d;
  110.     char *p;
  111.  
  112.     for (argc--, argv++; argc; argc--, argv++) {
  113.         d = strtod (*argv, & p);
  114.         printf ("%lf [%s]\n", d, p);
  115.     }
  116. }
  117. #endif
  118.