home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / misc / eval / source / src.lha / base.c next >
C/C++ Source or Header  |  1993-04-13  |  9KB  |  503 lines

  1. /*
  2. ** BASE.C   Handles float to ASCII and ASCII to float conversion
  3. **          in any number base.
  4. ** Will Menninger, 11-14-92, ANSI C
  5. **
  6. ** Eval is a floating point expression evaluator.
  7. ** This file last updated in version 1.10
  8. ** For the version number, see eval.h
  9. ** Copyright (C) 1993  Will Menninger
  10. **
  11. ** This program is free software; you can redistribute it and/or modify it
  12. ** under the terms of the GNU General Public License as published by the
  13. ** Free Software Foundation; either version 2 of the License, or any
  14. ** later version.
  15. **
  16. ** This program is distributed in the hope that it will be useful, but
  17. ** WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19. ** General Public License for more details.
  20. **
  21. ** You should have received a copy of the GNU General Public License along
  22. ** with this program; if not, write to the Free Software Foundation, Inc.,
  23. ** 675 Mass Ave, Cambridge, MA 02139, USA.
  24. **
  25. ** The author until 9/93 can be contacted at:
  26. ** e-mail:     willus@ilm.pfc.mit.edu
  27. ** U.S. mail:  Will Menninger, 45 River St., #2, Boston, MA 02108-1124
  28. **
  29. **
  30. */
  31.  
  32. #include "eval.h"
  33. #include <float.h>
  34.  
  35. #define SCI     1
  36. #define FREE    3
  37.  
  38. static int  sigfig;
  39. static int  maxexp;
  40. static int  fixed;
  41. static int  sci;
  42. static int  dplace;
  43. static int  maxdigits;
  44. static int  ibase;
  45. static int  obase;
  46.  
  47. static void sci_out(double val,char *buf);
  48. static void intadd(int x);
  49. static void free_out(double val,char *buf);
  50. static int  digval(char c);
  51. static int  ascii_int(int base,char *s);
  52. static void addtobuf(char *s);
  53. static void initbuf(char *s);
  54. static void incbuf(char c);
  55.  
  56.  
  57. void baseconv(double val,char *buf)
  58.  
  59.     {
  60.     if (sci)
  61.         sci_out(val,buf);
  62.     else
  63.         free_out(val,buf);
  64.     }
  65.  
  66.  
  67. void set_scinote(int val)
  68.  
  69.     {
  70.     sci=val;
  71.     }
  72.  
  73.  
  74. void set_sigfig(int val)
  75.  
  76.     {
  77.     sigfig=val;
  78.     }
  79.  
  80.  
  81. void set_dplace(int val)
  82.  
  83.     {
  84.     dplace=val;
  85.     }
  86.  
  87.  
  88. void set_maxexp(int val)
  89.  
  90.     {
  91.     maxexp=val;
  92.     }
  93.  
  94.  
  95. void set_fix(int val)
  96.  
  97.     {
  98.     fixed=val;
  99.     }
  100.  
  101.  
  102. void setobase(int base)
  103.  
  104.     {
  105.     obase=base;
  106.     maxdigits=precision(base);
  107.     }
  108.  
  109.  
  110. void setibase(int base)
  111.  
  112.     {
  113.     ibase=base;
  114.     }
  115.  
  116.  
  117. int getobase(void)
  118.  
  119.     {
  120.     return(obase);
  121.     }
  122.  
  123.  
  124. int getibase(void)
  125.  
  126.     {
  127.     return(ibase);
  128.     }
  129.  
  130.  
  131. int get_scinote(void)
  132.  
  133.     {
  134.     return(sci);
  135.     }
  136.  
  137.  
  138. int get_fix(void)
  139.  
  140.     {
  141.     return(fixed);
  142.     }
  143.  
  144.  
  145. int precision(int base)
  146.  
  147.     {
  148.     return((int)(DBL_MANT_DIG*log(2.)/log((double)base)));
  149.     }
  150.  
  151.  
  152. void print_outtype(void)
  153.  
  154.     {
  155.     printf("\nScientific notation:       %s\n",sci ? "ON" : "OFF");
  156.     printf("Significant digits:        ");
  157.     if (sigfig>0)
  158.         printf("%d",sigfig);
  159.     else
  160.         printf("max");
  161.     if (!sci && fixed)
  162.         printf(" (ignored)");
  163.     printf("\n");
  164.     printf("Fixed precision:           %s",fixed ? "ON" : "OFF");
  165.     if (sci)
  166.         printf(" (trailing zeroes printed.)");
  167.     printf("\n");
  168.     printf("Digits after the decimal:  %d",dplace);
  169.     if (sci || !fixed)
  170.         printf(" (ignored)");
  171.     printf("\n");
  172.     printf("Exponent limit:            ");
  173.     if (maxexp<0)
  174.         printf("none");
  175.     else
  176.         printf("%d",maxexp);
  177.     if (sci)
  178.         printf(" (ignored)");
  179.     printf("\n\n");
  180.     }
  181.  
  182.  
  183. double asciiconv(int base,char *s)
  184.  
  185.     {
  186.     double  val;
  187.     int     i,div,expc;
  188.  
  189.     for (i=0;s[i]!=EOS;i++)
  190.         s[i]=tolower((int)s[i]);
  191.     expc= base>14 ? '\\' : 'e';
  192.     div=-1;
  193.     val=0;
  194.     for (i=0;s[i]!=expc && s[i]!='\\' && s[i]!=EOS;i++)
  195.         {
  196.         if (s[i]=='.')
  197.             {
  198.             div++;
  199.             continue;
  200.             }
  201.         if (div>=0)
  202.             div++;
  203.         val=val*base+digval(s[i]);
  204.         }
  205.     if (div<0)
  206.         div=0;
  207.     if (s[i]!=EOS)
  208.         div-=ascii_int(base,&s[i+1]);
  209.     if (div!=0)
  210.         val=val/pow((double)base,(double)div);
  211.     return(val);
  212.     }
  213.  
  214.  
  215. static int ascii_int(int base,char *s)
  216.  
  217.     {
  218.     int     i,val,sign;
  219.  
  220.     val=0;
  221.     if (s[0]=='-' || s[0]=='+')
  222.         {
  223.         sign=(s[0]=='+');
  224.         i=1;
  225.         }
  226.     else
  227.         {
  228.         sign=1;
  229.         i=0;
  230.         }
  231.     for (;s[i]!=EOS;i++)
  232.         val=base*val+digval(s[i]);
  233.     return(sign ? val : -val);
  234.     }
  235.  
  236.  
  237. static int digval(char c)
  238.  
  239.     {
  240.     c=tolower((int)c);
  241.     return((int)(c<='9' ? c-'0' : c-'a'+10));
  242.     }
  243.  
  244.  
  245. static void sci_out(double val,char *buf)
  246.  
  247.     {
  248.     double   ex,f;
  249.     int      sf,sn,i,j,iex,dec,nz;
  250.  
  251.     initbuf(buf);
  252.     if (sigfig<=0)
  253.         sf=maxdigits;
  254.     else
  255.         sf=sigfig;
  256.     if (val==0.)
  257.         {
  258.         incbuf((char)'0');
  259.         if (fixed && sf>1)
  260.             {
  261.             incbuf((char)'.');
  262.             for (i=1;i<sf;i++)
  263.                 incbuf((char)'0');
  264.             }
  265.         addtobuf(obase>14 ? " x 10^0":"e0");
  266.         return;
  267.         }
  268.     sn=val>0;
  269.     val=fabs(val);
  270.     ex=log(val)/log((double)obase);
  271.     ex=floor(ex)+1.;
  272.     iex=ex;
  273.     val=val+(obase/2.)*pow((double)obase,ex-1.-sf);
  274.     f=val/pow((double)obase,ex);
  275.     if (f>=1.)
  276.         {
  277.         f=f/obase;
  278.         iex++;
  279.         }
  280.     initbuf(buf);
  281.     dec=0;
  282.     nz=0;
  283.     if (!sn)
  284.         incbuf((char)'-');
  285.     for (i=0;i<sf;i++)
  286.         {
  287.         if (i==1)
  288.             dec=1;
  289.         if (i>=maxdigits)
  290.             nz++;
  291.         else
  292.             {
  293.             f=f*obase;
  294.             if (f>=1.)
  295.                 {
  296.                 if (dec)
  297.                     {
  298.                     incbuf((char)'.');
  299.                     dec=0;
  300.                     }
  301.                 if (nz)
  302.                     {
  303.                     for (j=0;j<nz;j++)
  304.                         incbuf((char)'0');
  305.                     nz=0;
  306.                     }
  307.                 j=f;
  308.                 incbuf((char)(j<10 ? '0'+j : 'A'+j-10));
  309.                 f=f-j;
  310.                 }
  311.             else
  312.                 nz++;
  313.             }
  314.         }
  315.     if (fixed)
  316.         {
  317.         if (dec)
  318.             incbuf((char)'.');
  319.         if (nz)
  320.             for (j=0;j<nz;j++)
  321.                 incbuf((char)'0');
  322.         }
  323.     addtobuf(obase>14 ? " x 10^" : "e");
  324.     intadd(iex-1);
  325.     }
  326.  
  327.  
  328. static void intadd(int x)
  329.  
  330.     {
  331.     char    temp[100];
  332.     int     i,j,sn;
  333.  
  334.     if (!x)
  335.         {
  336.         incbuf((char)'0');
  337.         return;
  338.         }
  339.     sn=(x>=0);
  340.     if (x<0)
  341.         x=-x;
  342.     for (i=0;x;i++)
  343.         {
  344.         j=x%obase;
  345.         temp[i]=j<10 ? j+'0' : 'A'+j-10;
  346.         x/=obase;
  347.         }
  348.     if (!sn)
  349.         incbuf((char)'-');
  350.     for (j=i-1;j>=0;j--)
  351.         incbuf((char)temp[j]);
  352.     }
  353.  
  354.  
  355. static void free_out(double val,char *buf)
  356.  
  357.     {
  358.     double  ex,f;
  359.     int     sf,sn,i,j,k,iex,iex2,nz,dec;
  360.  
  361.     initbuf(buf);
  362.     if (fixed || sigfig<=0)
  363.         sf=maxdigits;
  364.     else
  365.         sf=sigfig;
  366.     if (val==0.)
  367.         {
  368.         incbuf((char)'0');
  369.         if (fixed)
  370.             {
  371.             if (dplace>0)
  372.                 incbuf((char)'.');
  373.             for (i=0;i<dplace;i++)
  374.                 incbuf((char)'0');
  375.             }
  376.         return;
  377.         }
  378.     sn=val>0;
  379.     val=fabs(val);
  380.     ex=log(val)/log((double)obase);
  381.     ex=floor(ex)+1.;
  382.     if (maxexp>=0 && fabs(ex)>=maxexp+1)
  383.         {
  384.         sci_out(sn ? val : -val,buf);
  385.         return;
  386.         }
  387.     iex=ex;
  388.     if (fixed)
  389.         iex2=-1-dplace;
  390.     else
  391.         iex2=ex-1-sf;
  392.     val=val+(obase/2.)*pow((double)obase,(double)iex2);
  393.     if (iex-maxdigits-1<iex2)
  394.         val=val+pow((double)obase,(double)iex-maxdigits);
  395.     f=val/pow((double)obase,ex);
  396.     if (f>=1.)
  397.         {
  398.         f=f/obase;
  399.         iex++;
  400.         }
  401.     k=iex;
  402.     if (!sn)
  403.         incbuf((char)'-');
  404.     dec=0;
  405.     nz=0;
  406.     if (fixed && iex<=-dplace)
  407.         {
  408.         incbuf((char)'0');
  409.         if (dplace>0)
  410.             {
  411.             incbuf((char)'.');
  412.             for (j=0;j<dplace;j++)
  413.                 incbuf((char)'0');
  414.             }
  415.         return;
  416.         }
  417.     if (iex<=0)
  418.         {
  419.         incbuf((char)'0');
  420.         dec=1;
  421.         nz=-iex;
  422.         }
  423.     for (i=0;fixed || i<sf;i++)
  424.         {
  425.         f=f*obase;
  426.         if (i<maxdigits && f>=1.)
  427.             {
  428.             if (dec)
  429.                 {
  430.                 incbuf((char)'.');
  431.                 dec=0;
  432.                 }
  433.             if (nz)
  434.                 {
  435.                 for (j=0;j<nz;j++)
  436.                     incbuf((char)'0');
  437.                 nz=0;
  438.                 }
  439.             j=f;
  440.             incbuf((char)(j<10 ? '0'+j : 'A'+j-10));
  441.             f=f-j;
  442.             }
  443.         else
  444.             if (k<=0)
  445.                 nz++;
  446.             else
  447.                 incbuf((char)'0');
  448.         k--;
  449.         if (fixed && k<=-dplace)
  450.             break;
  451.         if (k==0)
  452.             dec=1;
  453.         }
  454.     if (k>0)
  455.         for (;k>0;k--)
  456.             incbuf((char)'0');
  457.     if (fixed)
  458.         {
  459.         if (dec)
  460.             incbuf((char)'.');
  461.         if (nz)
  462.             for (j=0;j<nz;j++)
  463.                 incbuf((char)'0');
  464.         }
  465.     }
  466.  
  467.  
  468. static void addtobuf(char *s)
  469.  
  470.     {
  471.     int     i;
  472.  
  473.     for (i=0;s[i]!=EOS;i++)
  474.         incbuf((char)s[i]);
  475.     }
  476.  
  477.  
  478. static int   bufindex;
  479. static char *bufptr;
  480.  
  481. static void initbuf(char *s)
  482.  
  483.     {
  484.     bufindex=0;
  485.     bufptr=s;
  486.     }
  487.  
  488.  
  489. static void incbuf(char c)
  490.  
  491.     {
  492.     if (bufindex>MAXOUTLEN-50)
  493.         return;
  494.     if (bufindex==MAXOUTLEN-50)
  495.         {
  496.         bufindex++;
  497.         strcat(bufptr,"*** BUFFER OVERFLOW!");
  498.         return;
  499.         }
  500.     bufptr[bufindex++]=c;
  501.     bufptr[bufindex]=EOS;
  502.     }
  503.