From d7d16cbede6e50170d5f2f917945322cb3c814e5 Mon Sep 17 00:00:00 2001 From: ceriel Date: Wed, 10 Aug 1988 11:21:40 +0000 Subject: [PATCH] use new ecvt.c from C library --- lang/pc/libpc/cvt.c | 197 +++++++++++++++++++++----------------------- 1 file changed, 92 insertions(+), 105 deletions(-) diff --git a/lang/pc/libpc/cvt.c b/lang/pc/libpc/cvt.c index 07aff23aa..9867a6372 100644 --- a/lang/pc/libpc/cvt.c +++ b/lang/pc/libpc/cvt.c @@ -1,122 +1,109 @@ /* $Header$ */ -/* - * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. - * - * This product is part of the Amsterdam Compiler Kit. - * - * Permission to use, sell, duplicate or disclose this software must be - * obtained in writing. Requests for such permissions may be sent to - * - * Dr. Andrew S. Tanenbaum - * Wiskundig Seminarium - * Vrije Universiteit - * Postbox 7161 - * 1007 MC Amsterdam - * The Netherlands - * - */ +#ifndef NOFLOAT -extern double _fif(); +static char *cvt(); +#define NDIGITS 128 -/* - * _ecvt converts to decimal - * the number of digits is specified by ndigit - * decpt is set to the position of the decimal point - * sign is set to 0 for positive, 1 for negative - */ +char * +_ecvt(value, ndigit, decpt, sign) + double value; + int ndigit, *decpt, *sign; +{ + return cvt(value, ndigit, decpt, sign, 1); +} + +char * +_fcvt(value, ndigit, decpt, sign) + double value; + int ndigit, *decpt, *sign; +{ + return cvt(value, ndigit, decpt, sign, 0); +} -#define NDIG 80 +static struct powers_of_10 { + double pval; + double rpval; + int exp; +} p10[] = { + 1.0e32, 1.0e-32, 32, + 1.0e16, 1.0e-16, 16, + 1.0e8, 1.0e-8, 8, + 1.0e4, 1.0e-4, 4, + 1.0e2, 1.0e-2, 2, + 1.0e1, 1.0e-1, 1, + 1.0e0, 1.0e0, 0 +}; -static char* -cvt(arg, ndigits, decpt, sign, eflag) -double arg; -int ndigits, *decpt, *sign, eflag; +static char * +cvt(value, ndigit, decpt, sign, ecvtflag) + double value; + int ndigit, *decpt, *sign; { - register int r2; - double fi, fj; - register char *p, *p1; - static char buf[NDIG]; - int i; /*!*/ + static char buf[NDIGITS+1]; + register char *p = buf; + register char *pe; + + if (ndigit < 0) ndigit = 0; + if (ndigit > NDIGITS) ndigit = NDIGITS; + pe = &buf[ndigit]; + buf[0] = '\0'; - if (ndigits<0) - ndigits = 0; - if (ndigits>=NDIG-1) - ndigits = NDIG-2; - r2 = 0; *sign = 0; - p = &buf[0]; - if (arg<0) { + if (value < 0) { *sign = 1; - arg = -arg; + value = -value; } - arg = _fif(arg, 1.0, &fi); - /* - * Do integer part - */ - if (fi != 0) { - p1 = &buf[NDIG]; - while (fi != 0) { - i = (_fif(fi, 0.1, &fi) + 0.03) * 10; - *--p1 = i + '0'; - r2++; - } - while (p1 < &buf[NDIG]) - *p++ = *p1++; - } else if (arg > 0) { - while ((fj = arg*10) < 1) { - arg = fj; - r2--; - } - } - p1 = &buf[ndigits]; - if (eflag==0) - p1 += r2; - *decpt = r2; - if (p1 < &buf[0]) { - buf[0] = '\0'; - return(buf); + + *decpt = 0; + if (value != 0.0) { + register struct powers_of_10 *pp = &p10[0]; + + if (value >= 10.0) do { + while (value >= pp->pval) { + value *= pp->rpval; + *decpt += pp->exp; + } + } while ((++pp)->exp > 0); + + pp = &p10[0]; + if (value < 1.0) do { + while (value * pp->pval < 10.0) { + value *= pp->pval; + *decpt -= pp->exp; + } + } while ((++pp)->exp > 0); + + (*decpt)++; /* because now value in [1.0, 10.0) */ } - while (p<=p1 && p<&buf[NDIG]) { - arg = _fif(arg, 10.0, &fj); - i = fj; - *p++ = i + '0'; + if (! ecvtflag) { + /* for fcvt() we need ndigit digits behind the dot */ + pe += *decpt; + if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS]; } - if (p1 >= &buf[NDIG]) { - buf[NDIG-1] = '\0'; - return(buf); + while (p <= pe) { + *p++ = (int)value + '0'; + value = 10.0 * (value - (int)value); } - p = p1; - *p1 += 5; - while (*p1 > '9') { - *p1 = '0'; - if (p1>buf) { - p1--; *p1 += 1; - } else { - *p1 = '1'; - (*decpt)++; - if (eflag==0) { - if (p>buf) - *p = '0'; - p++; + if (pe >= buf) { + p = pe; + *p += 5; /* round of at the end */ + while (*p > '9') { + *p = '0'; + if (p > buf) ++*--p; + else { + *p = '1'; + ++*decpt; + if (! ecvtflag) { + /* maybe add another digit at the end, + because the point was shifted right + */ + if (pe > buf) *pe = '0'; + pe++; + } } } + *pe = '\0'; } - *p = '\0'; - return(buf); -} - -char* -_ecvt(arg, ndigits, decpt, sign) -double arg; -int ndigits, *decpt, *sign; -{ - return(cvt(arg, ndigits, decpt, sign, 1)); -} - -char* -_fcvt(arg, ndigits, decpt, sign) -double arg; -int ndigits, *decpt, *sign; -{ - return(cvt(arg, ndigits, decpt, sign, 0)); + return buf; } +#endif -- 2.34.1