home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 212_01 / floatr.c < prev    next >
Text File  |  1979-12-31  |  30KB  |  1,326 lines

  1. /* FLOATR.C    VERS:- 01.00  DATE:- 09/26/86  TIME:- 09:36:35 PM */
  2. /*
  3. %CC1 $1.C 
  4. */
  5. /* 
  6. Description:
  7.  
  8. Library of floating point functions (FLOAT.C, by Bob Mathias)
  9.     with additions (FLOAT+44.C, by L.C. Calhoun)
  10.     with added trig functions (CTRIG.C, by L.C. Calhoun)
  11.     with added log functions (CLOGS.C, by L.C. Calhoun)
  12.     with additional function(s) (by J.A. Rupley)
  13.  
  14. FLOAT.C from BDS C distribution package, version 1.5
  15. FLOAT+44.C, CTRIG.C, AND CLOGS.C are from cug disk "functions III".
  16.  
  17. Note: the v1.5 FLOAT.C has an updated version of _spr;
  18. replaced v1.44 std functions by v1.5 std functions
  19.  
  20. By J.A. Rupley, Tucson, Arizona
  21. Coded for BDS C compiler, version 1.50a
  22. */
  23.  
  24.  
  25.     /* page eject */
  26.  
  27. /* summary of functions 
  28.  
  29. (from FLOAT, by Mathias)
  30. int fpcomp(op1,op2)            return = (1,0,-1) || (op1 >,=,< op2)
  31. char *fpadd(result,op1,op2)        result = op1 + op2
  32. char *fpsub(result,op1,op2)        result = op1 - op2
  33. char *fpmult(result,op1,op2)        result = op1*op2
  34. char *fpdiv(result,op1,op2)        result = op1/op2
  35. char *itof(result,int#)            result = float(int#)
  36. char *atof(result,string#)        result = float(string#)
  37. char *ftoa(result,fpno)            result = string(fpno)
  38. char *itoa(result,int#)            result = string(int#)
  39. void printf(format)            standard C print function
  40. void _spr(line,&format)            float formatting function
  41.  
  42. (from FLOAT+44, by Calhoun)
  43. char *fpmag(result,fpno)        result = abs(fpno)
  44. char *fpchs(result,fpno)        result = - fpno
  45. char *fpasg(result,fpno)        result = fpno
  46. int ftoit(fpno)                return = truncate then to integer
  47. int ftoir(fpno)                return = round then to integer
  48.  
  49. (from CLOGS, by Calhoun)
  50. int exprange(fpno)            service function
  51. char *pi(result)            result = float(pi)
  52. char *expe(result,fpno)            result = e^(fpno)
  53. char *exp10(result,fpno)        result = 10^(fpno)
  54. char *log10(result,&int,fpno)        result = log10(abs(fpno)) //
  55.                             *int = sgn(fpno)
  56.  
  57. (from CTRIG, by Calhoun)
  58. char *degtorad(result,fpno)        result = rad(fpno-degrees)
  59. char *radtodeg(result,fpno)        result = deg(fpno-radians)
  60. char *sinev(result,fpno)        service function
  61. char *sine(result,fpno)            result = sin(fpno-radians)
  62. char *cosine(result,fpno)        result = cos(fpno-radians)
  63. char *tangent(result,fpno)        result = tangent(fpno-radians)
  64. char *atanev(result,fpno)        service function
  65. char *arctan(result,fpno)        result = arctan-radians(fpno)
  66. char *arctan2(result,quadrant,opside,adjside)
  67.         result = arctan-radians(opside/adjside) // quadrant = 1 to 4
  68.     
  69. (additions, by Rupley)
  70. char *sqrt(result,&int,fpno)        result = sqrt(abs(fpno)) //
  71.                             *int = sgn(fpno)
  72. */
  73.  
  74.  
  75.     /* page eject */
  76.  
  77. /* FLOAT.C ***************/
  78.  
  79. /*
  80.     Floating point package support routines
  81.  
  82.     Note the "fp" library function, available in DEFF2.CRL,
  83.     is used extensively by all the floating point number
  84.     crunching functions.
  85.  
  86.     -------------------------------------------------------------
  87.     Usage: After compiling your program, link with this library
  88.     by typing:
  89.  
  90.     A>clink <your program files> -f float <cr>
  91.     -------------------------------------------------------------
  92.  
  93.     NEW FEATURE: a special "printf" function has been included
  94.              in this source file for use with floating point
  95.              operands, in addition to the normal types. The
  96.              printf presented here will take precedence over
  97.              the DEFF.CRL version when "float" is specified
  98.              on the CLINK command line at linkage time.
  99.              Note that the "fp" function, needed by most of
  100.              the functions in this file, resides in DEFF2.CRL
  101.              and will be automatically collected by CLINK.
  102.  
  103.     All functions here written by Bob Mathias, except printf and
  104.     _spr (written by Leor Zolman.)
  105. */
  106.  
  107. #include <bdscio.h>
  108.  
  109. #define NORM_CODE    0
  110. #define ADD_CODE    1
  111. #define SUB_CODE    2
  112. #define MULT_CODE    3
  113. #define DIV_CODE    4
  114. #define FTOA_CODE    5
  115.  
  116. fpcomp(op1, op2)
  117. char *op1, *op2;
  118. {
  119.     char work[5];
  120.     fpsub(work, op1, op2);
  121.     if (work[3] > 127)
  122.         return (-1);
  123.     if (work[0] + work[1] + work[2] + work[3])
  124.         return (1);
  125.     return (0);
  126. }
  127.  
  128. fpnorm(op1) char *op1;
  129. {
  130.     fp(NORM_CODE, op1, op1);
  131.     return (op1);
  132. }
  133.  
  134. fpadd(result, op1, op2)
  135. char *result, *op1, *op2;
  136. {
  137.     fp(ADD_CODE, result, op1, op2);
  138.     return (result);
  139. }
  140.  
  141. fpsub(result, op2, op1)
  142. char *result, *op1, *op2;
  143. {
  144.     fp(SUB_CODE, result, op1, op2);
  145.     return (result);
  146. }
  147.  
  148. fpmult(result, op1, op2)
  149. char *result, *op1, *op2;
  150. {
  151.     fp(MULT_CODE, result, op1, op2);
  152.     return (result);
  153. }
  154.  
  155. fpdiv(result, op1, op2)
  156. char *result, *op1, *op2;
  157. {
  158.     fp(DIV_CODE, result, op1, op2);
  159.     return (result);
  160. }
  161.  
  162. atof(fpno, s)
  163. char fpno[5], *s;
  164. {
  165.     char *fpnorm(), work[5], ZERO[5], FP_10[5];
  166.     int sign_boolean, power;
  167.  
  168.     initb(FP_10, "0,0,0,80,4");
  169.     setmem(fpno, 5, 0);
  170.     sign_boolean = power = 0;
  171.  
  172.     while (*s == ' ' || *s == '\t')
  173.         ++s;
  174.     if (*s == '-')
  175.     {
  176.         sign_boolean = 1;
  177.         ++s;
  178.     }
  179.     for (; isdigit(*s); ++s)
  180.     {
  181.         fpmult(fpno, fpno, FP_10);
  182.         work[0] = *s - '0';
  183.         work[1] = work[2] = work[3] = 0;
  184.         work[4] = 31;
  185.         fpadd(fpno, fpno, fpnorm(work));
  186.     }
  187.     if (*s == '.')
  188.     {
  189.         ++s;
  190.         for (; isdigit(*s); --power, ++s)
  191.         {
  192.             fpmult(fpno, fpno, FP_10);
  193.             work[0] = *s - '0';
  194.             work[1] = work[2] = work[3] = 0;
  195.             work[4] = 31;
  196.             fpadd(fpno, fpno, fpnorm(work));
  197.         }
  198.     }
  199.     if (toupper(*s) == 'E')
  200.     {
  201.         ++s;
  202.         power += atoi(s);
  203.     }
  204.     if (power > 0)
  205.         for (; power != 0; --power)
  206.             fpmult(fpno, fpno, FP_10);
  207.     else
  208.         if (power < 0)
  209.         for (; power != 0; ++power)
  210.             fpdiv(fpno, fpno, FP_10);
  211.     if (sign_boolean)
  212.     {
  213.         setmem(ZERO, 5, 0);
  214.         fpsub(fpno, ZERO, fpno);
  215.     }
  216.     return (fpno);
  217. }
  218. ftoa(result, op1)
  219. char *result, *op1;
  220. {
  221.     fp(FTOA_CODE, result, op1);
  222.     return (result);
  223. }
  224.  
  225. itof(op1, n)
  226. char *op1;
  227. int n;
  228. {
  229.     int *p;
  230.     p = op1;
  231.     p[0] = 0;
  232.     p[1] = n;
  233.     op1[4] = 15;
  234.     fp(NORM_CODE, op1, op1);
  235.     return op1;
  236. }
  237.  
  238. itoa(str, n)
  239. char *str;
  240. {
  241.     char *sptr;
  242.     sptr = str;
  243.     if (n < 0)
  244.     {
  245.         *sptr++ = '-';
  246.         n = -n;
  247.     }
  248.     _uspr(&sptr, n, 10);
  249.     *sptr = '\0';
  250.     return str;
  251. }
  252.  
  253. /*
  254.     This is the special formatting function, which supports the
  255.     "e" and "f" conversions as well as the normal "d", "s", etc.
  256.     When using "e" or "f" format, the corresponding argument in
  257.     the argument list should be a pointer to one of the five-byte
  258.     strings used as floating point numbers by the floating point
  259.     functions. Note that you don't need to ever use the "ftoa"
  260.     function when using this special printf/sprintf combination;
  261.     to achieve the same result as ftoa, a simple "%e" format
  262.     conversion will do the trick. "%f" is used to eliminate the
  263.     scientific notation and set the precision. The only [known]
  264.     difference between the "e" and "f" conversions as used here
  265.     and the ones described in the Kernighan & Ritchie book is that
  266.     ROUNDING does not take place in this version...e.g., printing
  267.     a floating point number which happens to equal exactly 3.999
  268.     using a "%5.2f" format conversion will produce " 3.99" instead
  269.     of " 4.00".
  270. */
  271.  
  272. printf(format)
  273. char *format;
  274. {
  275.     int putchar();
  276.     _spr(&format, &putchar);        /* use "_spr" to form the output */
  277. }
  278.  
  279.  
  280. _spr(fmt, putcf, arg1)
  281. int (*putcf)();
  282. char **fmt;
  283. {
  284.     char _uspr(), c, base, *sptr, *format;
  285.     char wbuf[MAXLINE], *wptr, pf, ljflag, zfflag;
  286.     int width, precision, exp, *args;
  287.  
  288.     format = *fmt++;        /* fmt first points to the format string */
  289.     args = fmt;        /* now fmt points to the first arg value */
  290.     while (c = *format++)
  291.         if (c == '%')
  292.         {
  293.             wptr = wbuf;
  294.             precision = 6;
  295.             ljflag = pf = zfflag = 0;
  296.  
  297.             if (*format == '-')
  298.             {
  299.                 format++;
  300.                 ljflag++;
  301.             }
  302.  
  303.             if (*format == '0')
  304.                 zfflag++;        /* test for zero fill */
  305.  
  306.             width = isdigit(*format) ? _gv2(&format) : 0;
  307.  
  308.             if ((c = *format++) == '.')
  309.             {
  310.                 precision = _gv2(&format);
  311.                 pf++;
  312.                 c = *format++;
  313.             }
  314.  
  315.             switch (toupper(c))
  316.             {
  317.             case 'E' :
  318.                 if (precision > 7)
  319.                     precision = 7;
  320.                 ftoa(wbuf, *args++);
  321.                 strcpy(wbuf + precision + 3, wbuf + 10);
  322.                 width -= strlen(wbuf);
  323.                 goto pad2;
  324.  
  325.             case 'F' :
  326.                 ftoa(&wbuf[60], *args++);
  327.                 sptr = &wbuf[60];
  328.                 while (*sptr++ != 'E')
  329.                     ;
  330.                 exp = atoi(sptr);
  331.                 sptr = &wbuf[60];
  332.                 if (*sptr == ' ')
  333.                     sptr++;
  334.                 if (*