home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 270_01 / atof.c < prev    next >
Text File  |  1979-12-31  |  3KB  |  120 lines

  1. /*
  2. TITLE:        ATOF;
  3. DATE:        2/9/88;
  4. DESCRIPTION:    "atof() and strtod()";
  5. VERSION:    1;
  6. KEYWORDS:    ATOF, STRTOD;
  7. FILENAME:    ATOF.C;
  8. WARNINGS:    "Probably causes rounding errors.";
  9. SEE-ALSO:    
  10. SYSTEM:        MS-DOS;
  11. COMPILERS:    Aztec C86;
  12. AUTHORS:    Dan Schechter;
  13.  */
  14.  
  15. /* Public domain source code from KITTENSOFT by Dan Schechter.
  16. Aztec C v 4.1b has a bug in atof() which is scheduled to be fixed in the
  17. next release. Aztec C does not have strtod(). The following is intended to
  18. be a TEMPORARY work-around for atof() and a BETTER-THAN-NOTHING strtod().
  19. These functions will probably introduce minor rounding errors. 
  20. Otherwise I think they work like their "real" counterparts. */
  21.  
  22. #include <stdio.h>
  23.  
  24. main()
  25. {
  26.     char *r,s[200];
  27.     double d,atof(),strtod();
  28.     
  29.     for(;;){
  30.         printf("?:");
  31.         gets(s);
  32.         if (s[0]==0) exit(0);
  33.         d=strtod(s,&r);
  34.         printf("%.15g\n%s\n",d,r);
  35.     }
  36. }
  37.  
  38.  
  39. double atof(s)
  40. char *s;
  41. {
  42.     double strtod();
  43.     
  44.     return( strtod(s,(char *)0) );
  45. }
  46.  
  47. #define STRTODLEN 100
  48.  
  49. double strtod(s,p)
  50. char *s,**p;
  51. {
  52.     char     is[STRTODLEN], /* string to hold the integer portion */
  53.         fs[STRTODLEN], /* string to hold the fractional portion */
  54.         es[STRTODLEN]; /* string to hold the exponent portion */
  55.     double     ii,        /* the integer part as a double */
  56.         fi,        /* the fractional part as a double */
  57.         efac;        /* the factor represented by the 
  58.                 exponent portion of the string. */
  59.     int     ei,        /* the power of 10 */
  60.         flen,        /* the length of the string containing 
  61.                 the decimal fraction */
  62.         sign=1,        /* sign=0 if the number is < 0. */
  63.         esign=1;    /* esign=0 if the exponent is < 0 */
  64.     char *_digitcopy();
  65.     double atoi_d();
  66.     
  67.     is[0]=fs[0]=es[0]= '\0';
  68.     while((*s==' ')||(*s=='\t')) s++;   /* disregard leading white space */
  69.     
  70.     switch (*s){
  71.         case '-': sign = 0;
  72.         case '+': s++;
  73.     }
  74.     
  75.     if ((*s)&&(*s != '.')) s= _digitcopy(s,is);
  76.     if (*s == '.') s= _digitcopy(++s,fs);
  77.     if ((*s == 'e')||(*s == 'E')) {
  78.         switch (*(++s)){
  79.             case '-': esign = 0;
  80.             case '+': s++;
  81.         }
  82.         s= _digitcopy(s,es);
  83.     }
  84.     ii= atoi_d(is);
  85.     fi= atoi_d(fs);
  86.     ei= esign ? atoi(es) : -atoi(es);
  87.     
  88.     if (p) *p=s;
  89.     
  90.     efac=1.0;
  91.     if (ei>0) for(;ei;ei--) efac *= 10.0;   /* This probably introduces */
  92.     if (ei<0) for(;ei;ei++) efac /= 10.0;    /* rounding errors.         */
  93.     
  94.     flen= strlen(fs);
  95.     while(flen--) fi /= 10.0;        /* Ditto. */
  96.     
  97.     if (!sign) efac = -efac;
  98.     return ( (ii + fi) * efac );
  99. }
  100.  
  101. double atoi_d(s)
  102. char *s;
  103. {
  104.     double n=0.0;
  105.     for (;*s;s++){
  106.         n *= 10.0;
  107.         n += *s - 48;
  108.     }
  109.     return(n);
  110. }
  111.  
  112. char *_digitcopy(from,to)
  113. char *from,*to;
  114. {
  115.     
  116.     while((*from>='0')&&(*from<='9')) (*to++)=(*from++);
  117.     *to=0;
  118.     return(from);
  119. }
  120.