home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / BDSC / BDSC-1 / FLOAT.C < prev    next >
Text File  |  2000-06-30  |  7KB  |  298 lines

  1.  
  2.  
  3. /*
  4.     Floating point package support routines
  5.  
  6.     Note the "fp" library function, available in DEFF2.CRL,
  7.     is used extensively by all the floating point number
  8.     crunching functions.
  9.  
  10.     (see FLOAT.DOC for details...)
  11.  
  12.     -------------------------------------------------------------
  13.     Usage: After compiling your program, link with this library
  14.     by typing:
  15.  
  16.     A>clink <your program files> -f float <cr>
  17.     -------------------------------------------------------------
  18.  
  19.     NEW FEATURE: a special "printf" function has been included
  20.              in this source file for use with floating point
  21.              operands, in addition to the normal types. The
  22.              printf presented here will take precedence over
  23.              the DEFF.CRL version when "float" is specified
  24.              on the CLINK command line at linkage time.
  25.              Note that the "fp" function, needed by most of
  26.              the functions in this file, resides in DEFF2.CRL
  27.              and will be automatically collected by CLINK.
  28.  
  29.     All functions here written by Bob Mathias, except printf and
  30.     _spr (written by Leor Zolman.)
  31. */
  32.  
  33. #include "bdscio.h"
  34.  
  35. #define NORM_CODE    0
  36. #define ADD_CODE    1
  37. #define SUB_CODE    2
  38. #define MULT_CODE    3
  39. #define DIV_CODE    4
  40. #define FTOA_CODE    5
  41.  
  42. fpcomp(op1,op2)
  43.     char *op1,*op2;
  44. {
  45.     char work[5];
  46.     fpsub(work,op1,op2);
  47.     if (work[3] > 127) return (-1);
  48.     if (work[0]+work[1]+work[2]+work[3]) return (1);
  49.     return (0);
  50. }
  51.  
  52. fpnorm(op1) char *op1;
  53. {    fp(NORM_CODE,op1,op1);return(op1);}
  54.  
  55. fpadd(result,op1,op2)
  56.     char *result,*op1,*op2;
  57. {    fp(ADD_CODE,result,op1,op2);return(result);}
  58.  
  59. fpsub(result,op2,op1)
  60.     char *result,*op1,*op2;
  61.     {fp(SUB_CODE,result,op1,op2);return(result);}
  62.  
  63. fpmult(result,op1,op2)
  64.     char *result,*op1,*op2;
  65. {    fp(MULT_CODE,result,op1,op2);return(result);}
  66.  
  67. fpdiv(result,op1,op2)
  68.     char *result,*op1,*op2;
  69. {    fp(DIV_CODE,result,op1,op2);return(result);}
  70.  
  71. atof(fpno,s)
  72.     char fpno[5],*s;
  73. {
  74.     char *fpnorm(),work[5],ZERO[5],FP_10[5];
  75.     int sign_boolean,power;
  76.  
  77.     initb(FP_10,"0,0,0,80,4");
  78.     setmem(fpno,5,0);
  79.     sign_boolean=power=0;
  80.  
  81.     while (*s==' ' || *s=='\t') ++s;
  82.     if (*s=='-'){sign_boolean=1;++s;}
  83.     for (;isdigit(*s);++s){
  84.         fpmult(fpno,fpno,FP_10);
  85.         work[0]=*s-'0';
  86.         work[1]=work[2]=work[3]=0;work[4]=31;
  87.         fpadd(fpno,fpno,fpnorm(work));
  88.     }
  89.     if (*s=='.'){
  90.         ++s;
  91.         for (;isdigit(*s);--power,++s){
  92.             fpmult(fpno,fpno,FP_10);
  93.             work[0]=*s-'0';
  94.             work[1]=work[2]=work[3]=0;work[4]=31;
  95.             fpadd(fpno,fpno,fpnorm(work));
  96.         }
  97.     }
  98.     if (toupper(*s) == 'E') {++s; power += atoi(s); }
  99.     if (power>0)
  100.         for (;power!=0;--power) fpmult(fpno,fpno,FP_10);
  101.     else
  102.     if (power<0)
  103.         for (;power!=0;++power) fpdiv(fpno,fpno,FP_10);
  104.     if (sign_boolean){
  105.         setmem(ZERO,5,0);
  106.         fpsub(fpno,ZERO,fpno);
  107.     }
  108.     return(fpno);
  109. }
  110. ftoa(result,op1)
  111.     char *result,*op1;
  112. {    fp(FTOA_CODE,result,op1);return(result);}
  113.  
  114. itof(op1,n)
  115. char *op1;
  116. int n;
  117. {
  118.     char temp[20];
  119.     return atof(op1, itoa(temp,n));
  120. }
  121.  
  122. itoa(str,n)
  123. char *str;
  124. {
  125.     char *sptr;
  126.     sptr = str;
  127.     if (n<0) { *sptr++ = '-'; n = -n; }
  128.     _uspr(&sptr, n, 10);
  129.     *sptr = '\0';
  130.     return str;
  131. }
  132.  
  133. /*
  134.     This is the special formatting function, which supports the
  135.     "e" and "f" conversions as well as the normal "d", "s", etc.
  136.     When using "e" or "f" format, the corresponding argument in
  137.     the argument list should be a pointer to one of the five-byte
  138.     strings used as floating point numbers by the floating point
  139.     functions. Note that you don't need to ever use the "ftoa"
  140.     function when using this special printf/sprintf combination;
  141.     to achieve the same result as ftoa, a simple "%e" format
  142.     conversion will do the trick. "%f" is used to eliminate the
  143.     scientific notation and set the precision. The only [known]
  144.     difference between the "e" and "f" conversions as used here
  145.     and the ones described in the Kernighan & Ritchie book is that
  146.     ROUNDING does not take place in this version...e.g., printing
  147.     a floating point number which happens to equal exactly 3.999
  148.     using a "%5.2f" format conversion will produce " 3.99" instead
  149.     of " 4.00".
  150. */
  151.  
  152.  
  153. _spr(line,fmt)
  154. char *line, **fmt;
  155. {
  156.     char _uspr(), c, base, *sptr, *format;
  157.     char wbuf[MAXLINE], *wptr, pf, ljflag, zfflag;
  158.     int width, precision, exp, *args;
  159.  
  160.     format = *fmt++;    /* fmt first points to the format string */
  161.     args = fmt;        /* now fmt points to the first arg value */
  162.     while (c = *format++)
  163.       if (c == '%') {
  164.         wptr = wbuf;
  165.         precision = 6;
  166.         ljflag = pf = zfflag = 0;
  167.  
  168.         if (*format == '-') {
  169.             format++;
  170.             ljflag++;
  171.          }
  172.  
  173.         if (*format == '0') zfflag++;    /* test for zero fill */
  174.  
  175.         width = isdigit(*format) ? _gv2(&format) : 0;
  176.  
  177.         if ((c = *format++) == '.') {
  178.             precision = _gv2(&format);
  179.             pf++;
  180.             c = *format++;
  181.          }
  182.  
  183.         switch(toupper(c)) {
  184.         case 'E':  if (precision>7) precision = 7;
  185.                ftoa(wbuf,*args++);
  186.                strcpy(wbuf+precision+3, wbuf+10);
  187.                width -= strlen(wbuf);
  188.                goto pad2;
  189.  
  190.         case 'F':  ftoa(&wbuf[60],*args++);
  191.                sptr = &wbuf[60];
  192.                while ( *sptr++ != 'E')
  193.                 ;
  194.                exp = atoi(sptr);
  195.                sptr = &wbuf[60];
  196.                if (*sptr == ' ') sptr++;
  197.                if (*sptr == '-') {
  198.                 *wptr++ = '-';
  199.                 sptr++;
  200.                 width--;
  201.                 }
  202.                sptr += 2;
  203.  
  204.                if (exp < 1) {
  205.                 *wptr++ = '0';
  206.                 width--;
  207.                 }
  208.  
  209.                pf = 7;
  210.                while (exp > 0 && pf) {
  211.                 *wptr++ = *sptr++;
  212.                 pf--;
  213.                 exp--;
  214.                 width--;
  215.                 }
  216.  
  217.                while (exp > 0) {
  218.                 *wptr++ = '0';
  219.                 exp--;
  220.                 width--;
  221.                 }
  222.  
  223.                *wptr++ = '.';
  224.                width--;
  225.  
  226.                while (exp < 0 && precision) {
  227.                 *wptr++ = '0';
  228.                 exp++;
  229.                 precision--;
  230.                 width--;
  231.                 }
  232.  
  233.                while (precision && pf) {
  234.                 *wptr++ = *sptr++;
  235.                 pf--;
  236.                 precision--;
  237.                 width--;
  238.                 }
  239.  
  240.                while (precision>0) {
  241.                 *wptr++ = '0';
  242.                 precision--;
  243.                 width--;
  244.                 }
  245.  
  246.                goto pad;
  247.  
  248.  
  249.         case 'D':  if (*args < 0) {
  250.                 *wptr++ = '-';
  251.                 *args = -*args;
  252.                 width--;
  253.                 }
  254.         case 'U':  base = 10; goto val;
  255.  
  256.         case 'X':  base = 16; goto val;
  257.  
  258.         case 'O':  base = 8;
  259.  
  260.              val:  width -= _uspr(&wptr,*args++,base);
  261.                goto pad;
  262.  
  263.         case 'C':  *wptr++ = *args++;
  264.                width--;
  265.                goto pad;
  266.  
  267.         case 'S':  if (!pf) precision = 200;
  268.                sptr = *args++;
  269.                while (*sptr && precision) {
  270.                 *wptr++ = *sptr++;
  271.                 precision--;
  272.                 width--;
  273.                 }
  274.  
  275.              pad:  *wptr = '\0';
  276.              pad2: wptr = wbuf;
  277.                if (!ljflag)
  278.                 while (width-- > 0)
  279.                     *line++ = zfflag ? '0' : ' ';
  280.  
  281.                while (*line = *wptr++)
  282.                 line++;
  283.  
  284.                if (ljflag)
  285.                 while (width-- > 0)
  286.                     *line++ = ' ';
  287.                break;
  288.  
  289.          default:  *line++ = c;
  290.  
  291.          }
  292.       }
  293.       else *line++ = c;
  294.  
  295.     *line = '\0';
  296. }
  297.  
  298.