home *** CD-ROM | disk | FTP | other *** search
- /***
- * nsupport.c
- *
- * Clipper Summer87
- * Floating point support; C equivalents.
- *
- * Copyright (c) 1988 Nantucket Corp. All rights reserved.
- *
- * CAUTION -- Intended for informational purposes.
- */
-
-
- /* nandef header file (found on Clipper distribution disks) */
- #include "nandef.h"
-
- /* nsupport header file (with XDOUBLE defined as true 'double' type) */
- #define REAL_DOUBLES
- #include "nsupport.h"
-
-
- /* convenience macros */
- #define isdigit(c) ((byte)(c) >= '0' && (byte)(c) <= '9')
- #define iswhite(c) ((byte)(c) == ' ' || (byte)(c) == '\t')
- #define issign(c) ((byte)(c) == '+' || (byte)(c) == '-')
- #define ispoint(c) ((byte)(c) == '.')
-
-
- /* C support routines -- see C manual */
- extern double far cdecl fmod(double, double);
- extern double far cdecl floor(double);
- extern double far cdecl ceil(double);
- extern double far cdecl pow(double, double);
- extern double far cdecl log(double);
- extern double far cdecl sqrt(double);
- extern double far cdecl exp(double);
-
- extern double far cdecl atof(byte far *);
- extern char far * far cdecl fcvt(double, quant, int far *, int far *);
- extern char far * far cdecl ltoa(long, byte far *, quant);
-
-
- /* static data */
- static double near _DV_P5 = (double)0.5;
- static double near _DV_NP5 = (double)-0.5;
- static double near _DV_10 = (double)10.0;
- static double near _DV_0 = (double)0;
-
-
- /* conversion buffer */
- static byte near nbuff[32];
-
-
- /***************************************
- *
- * initialization
- *
- */
-
-
- /***
- * _dvinit()
- *
- * This entry point is called once at the beginning of execution.
- * Note that there is no corresponding exit routine. (!)
- */
-
- void far cdecl _dvinit()
-
- {
- }
-
-
-
- /***************************************
- *
- * relational operators
- *
- */
-
-
- /***
- * _dvlt
- */
-
- Boolean far cdecl _dvlt(x, y)
-
- double x;
- double y;
-
- {
- return (x < y);
- }
-
-
- /***
- * _dvle
- */
-
- Boolean far cdecl _dvle(x, y)
-
- double x;
- double y;
-
- {
- return (x <= y);
- }
-
-
- /***
- * _dveq
- */
-
- Boolean far cdecl _dveq(x, y)
-
- double x;
- double y;
-
- {
- return (x == y);
- }
-
-
- /***
- * _dvge
- */
-
- Boolean far cdecl _dvge(x, y)
-
- double x;
- double y;
-
- {
- return (x >= y);
- }
-
-
- /***
- * _dvgt
- */
-
- Boolean far cdecl _dvgt(x, y)
-
- double x;
- double y;
-
- {
- return (x > y);
- }
-
-
- /***
- * _dvne
- */
-
- Boolean far cdecl _dvne(x, y)
-
- double x;
- double y;
-
- {
- return (x != y);
- }
-
-
- /***
- * _dvltz
- */
-
- Boolean far cdecl _dvltz(x)
-
- double x;
-
- {
- return (x < _DV_0);
- }
-
-
- /***
- * _dveqz
- */
-
- Boolean far cdecl _dveqz(x)
-
- double x;
-
- {
- return (x == _DV_0);
- }
-
-
-
- /***************************************
- *
- * simple operators
- *
- */
-
-
- /***
- * _dvadd
- */
-
- double far cdecl _dvadd(x, y)
-
- double x;
- double y;
-
- {
- return (x + y);
- }
-
-
- /***
- * _dvsub
- */
-
- double far cdecl _dvsub(x, y)
-
- double x;
- double y;
-
- {
- return (x - y);
- }
-
-
- /***
- * _dvmul
- */
-
- double far cdecl _dvmul(x, y)
-
- double x;
- double y;
-
- {
- return (x * y);
- }
-
-
- /***
- * _dvdiv
- */
-
- double far cdecl _dvdiv(x, y)
-
- double x;
- double y;
-
- {
- return (x / y);
- }
-
-
- /***
- * _dvmod
- */
-
- double far cdecl _dvmod(x, y)
-
- double x;
- double y;
-
- {
- return (fmod(x, y));
- }
-
-
- /***
- * _dvneg
- */
-
- double far cdecl _dvneg(x)
-
- double x;
-
- {
- return (-x);
- }
-
-
- /***
- * _dvabs
- */
-
- double far cdecl _dvabs(x)
-
- double x;
-
- {
- return ((x < _DV_0) ? -x : x);
- }
-
-
- /***
- * _dvint
- */
-
- double far cdecl _dvint(x)
-
- double x;
-
- {
- if (x < _DV_0)
- return (ceil(x));
-
- return (floor(x));
- }
-
-
- /***
- * _dvpow
- */
-
- double far cdecl _dvpow(x, y)
-
- double x;
- double y;
-
- {
- return (pow(x, y));
- }
-
-
- /***
- * _dvlog
- */
-
- double far cdecl _dvlog(x)
-
- double x;
-
- {
- return (log(x));
- }
-
-
- /***
- * _dvsqr
- */
-
- double far cdecl _dvsqr(x)
-
- double x;
-
- {
- return (sqrt(x));
- }
-
-
- /***
- * _dvexp
- */
-
- double far cdecl _dvexp(x)
-
- double x;
-
- {
- return (exp(x));
- }
-
-
- /***
- * _dvrnd(x, d)
- *
- * x: double value
- * d: int number of decimal places
- *
- * Returns 'x' rounded to 'd' decimal places.
- */
-
- double far cdecl _dvrnd(x, d)
-
- double x;
- int d;
-
- {
- double p10;
- double half;
-
-
- p10 = pow(_DV_10, _dvfmi(d));
-
- if (x < _DV_0)
- half = _DV_NP5; /* -0.5 */
- else
- half = _DV_P5; /* 0.5 */
-
- return (_dvint(x * p10 + half) / p10);
- }
-
-
-
- /***************************************
- *
- * simple type conversions
- *
- */
-
-
- /***
- * _dvfmq
- */
-
- double far cdecl _dvfmq(x)
-
- quant x;
-
- {
- return ((double)x);
- }
-
-
- /***
- * _dvfmi
- */
-
- double far cdecl _dvfmi(x)
-
- int x;
-
- {
- return ((double)x);
- }
-
-
- /***
- * _dvfml
- */
-
- double far cdecl _dvfml(x)
-
- long x;
-
- {
- return ((double)x);
- }
-
-
- /***
- * _dvtoq
- */
-
- quant far cdecl _dvtoq(x)
-
- double x;
-
- {
- return ((quant)x);
- }
-
-
- /***
- * _dvtoi
- */
-
- int far cdecl _dvtoi(x)
-
- double x;
-
- {
- return ((int)x);
- }
-
-
- /***
- * _dvtol
- */
-
- long far cdecl _dvtol(x)
-
- double x;
-
- {
- return ((long)x);
- }
-
-
-
- /***************************************
- *
- * ASCII type conversions
- *
- */
-
-
- /***
- *
- * dval = _dvfma(str, len)
- *
- * Convert printable ASCII to double value.
- *
- * str: string to convert.
- * len: length of string (not including null byte).
- * dval: double value returned.
- */
-
- double far cdecl _dvfma(str, len)
-
- byte far * str;
- quant len;
-
- {
- quant i;
- quant j;
-
-
- i = 0;
- j = 0;
-
- /* scan over whites */
- while (i < len && iswhite(str[i]))
- {
- i++;
- }
-
- if (isdigit(str[i]) || issign(str[i]))
- {
- /* copy sign / whole digits */
- do
- {
- nbuff[j++] = str[i++];
- } while (i < len && j < sizeof(nbuff) - 1 && isdigit(str[i]));
- }
-
- if (ispoint(str[i]))
- {
- /* copy point, numerics */
- do
- {
- nbuff[j++] = str[i++];
- } while (i < len && j < sizeof(nbuff) - 1 && isdigit(str[i]));
- }
-
- /* terminator */
- nbuff[j] = '\0';
-
- return (atof(nbuff));
- }
-
-
- /***
- *
- * _aton(str, len, dvalp, lenp, decp)
- *
- * Convert printable ASCII to double value.
- *
- * str: string to convert.
- * len: length of string (not including null byte).
- * dvalp: pointer to double which receives converted value.
- * lenp: pointer to quant which receives display length.
- * decp: pointer to quant which receives number of decimal digits.
- *
- */
-
- void far cdecl _aton(str, len, dvalp, lenp, decp)
-
- byte far * str;
- quant len;
- double far * dvalp;
- quant far * lenp;
- quant far * decp;
-
- {
- quant i;
-
-
- /* scan for point */
- i = 0;
- while (i < len && !ispoint(str[i]))
- {
- i++;
- }
-
- if (i < len)
- {
- /* figure decimal count */
- *decp = (len - i) - 1;
- }
-
- *decp = i;
- *lenp = len;
- *dvalp = _dvfma(str, len);
- }
-
-
- /***
- *
- * _ntoa(dval, len, dec, dest)
- *
- * Convert double to printable ASCII.
- *
- * dval: value to convert.
- * len: desired total length.
- * dec: desired number of decimal places.
- * dest: destination buffer.
- *
- * Decimal digits are rounded to desired number of places. If whole digits
- * cannot be fully represented, destination is filled with asterisks.
- *
- * Caution -- dest must be at least len+1 long.
- */
-
- void far cdecl _ntoa(dval, len, dec, dest)
-
- double dval;
- quant len;
- quant dec;
- byte far * dest;
-
- {
- byte far * buff;
- int expt;
- int sign;
- quant total;
- quant b;
- quant d;
-
-
- buff = fcvt(dval, dec, &expt, &sign);
-
- /* check for overflow */
- total = 0;
- while (buff[total])
- {
- total++;
- }
-
- if (sign)
- {
- /* room for sign */
- total++;
- }
-
- if (dec)
- {
- /* room for decimal point */
- total++;
-
- if (expt < 1)
- {
- /* room for single whole zero */
- total++;
-
- /* room for leading fractional zeros */
- total += -expt;
- }
- }
-
-
- b = 0;
- d = 0;
-
- if (total > len)
- {
- /* overflow */
- while (d < len)
- {
- dest[d++] = '*';
- }
- }
- else
- {
- while (total < len)
- {
- /* leading blanks */
- dest[d++] = ' ';
- total++;
- }
-
- if (sign)
- {
- /* put in sign */
- dest[d++] = '-';
- }
-
- if (expt < 1)
- {
- /* whole zero and point */
- dest[d++] = '0';
- dest[d++] = '.';
-
- while (expt)
- {
- /* frac leading zeros */
- dest[d++] = '0';
- expt++;
- }
- }
- else
- {
- while (expt)
- {
- /* copy whole digits */
- dest[d++] = buff[b++];
- expt--;
- }
-
- if (dec)
- {
- /* point */
- dest[d++] = '.';
- }
- }
-
- while (buff[b])
- {
- /* other digits */
- dest[d++] = buff[b++];
- }
- }
-
- /* terminator */
- dest[d] = '\0';
- }
-
-
- /***
- *
- * _lntoa(dest, lval, len, dec)
- *
- * Convert long to printable ASCII.
- *
- * lval: value to convert.
- * len: desired length.
- * dec: desired number of decimal places.
- * dest: destination buffer.
- *
- * If value is too large to be contained in alloted length,
- * buffer is filled with asterisks.
- *
- * Caution -- dest must be at least len+1 long.
- */
-
- void far cdecl _lntoa(dest, lval, len, dec)
-
- byte far * dest;
- long lval;
- quant len;
- quant dec;
-
- {
- byte far * buff;
- quant total;
- quant i;
-
-
- buff = ltoa(lval, nbuff, 10);
-
- /* check for overflow */
- total = 0;
- while (buff[total])
- {
- /* room for digits */
- total++;
- }
-
- if (dec)
- {
- /* room for point and frac zeros */
- total += (dec + 1);
- }
-
- if (total > len)
- {
- /* overflow */
- for (i = 0; i < len; i++)
- {
- dest[i] = '*';
- }
- }
- else
- {
- /* leading blanks */
- for (i = 0; i < len - total; i++)
- {
- dest[i] = ' ';
- }
-
- /* copy whole digits */
- while (*buff)
- {
- dest[i++] = *buff++;
- }
-
- /* point and frac zeros */
- if (dec)
- {
- dest[i++] = '.';
-
- while (dec--)
- {
- dest[i++] = '0';
- }
- }
- }
-
- /* terminator */
- dest[i] = '\0';
- }
-