use new ecvt.c from C library

This commit is contained in:
ceriel 1988-08-10 11:21:40 +00:00
parent 03610bb643
commit d7d16cbede

View file

@ -1,122 +1,109 @@
/* $Header$ */ /* $Header$ */
/* #ifndef NOFLOAT
* (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
*
*/
extern double _fif(); static char *cvt();
#define NDIGITS 128
/* char *
* _ecvt converts to decimal _ecvt(value, ndigit, decpt, sign)
* the number of digits is specified by ndigit double value;
* decpt is set to the position of the decimal point int ndigit, *decpt, *sign;
* sign is set to 0 for positive, 1 for negative
*/
#define NDIG 80
static char*
cvt(arg, ndigits, decpt, sign, eflag)
double arg;
int ndigits, *decpt, *sign, eflag;
{ {
register int r2; return cvt(value, ndigit, decpt, sign, 1);
double fi, fj; }
register char *p, *p1;
static char buf[NDIG]; char *
int i; /*!*/ _fcvt(value, ndigit, decpt, sign)
double value;
int ndigit, *decpt, *sign;
{
return cvt(value, ndigit, decpt, sign, 0);
}
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(value, ndigit, decpt, sign, ecvtflag)
double value;
int ndigit, *decpt, *sign;
{
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; *sign = 0;
p = &buf[0]; if (value < 0) {
if (arg<0) {
*sign = 1; *sign = 1;
arg = -arg; value = -value;
} }
arg = _fif(arg, 1.0, &fi);
/* *decpt = 0;
* Do integer part if (value != 0.0) {
*/ register struct powers_of_10 *pp = &p10[0];
if (fi != 0) {
p1 = &buf[NDIG]; if (value >= 10.0) do {
while (fi != 0) { while (value >= pp->pval) {
i = (_fif(fi, 0.1, &fi) + 0.03) * 10; value *= pp->rpval;
*--p1 = i + '0'; *decpt += pp->exp;
r2++; }
} } while ((++pp)->exp > 0);
while (p1 < &buf[NDIG])
*p++ = *p1++; pp = &p10[0];
} else if (arg > 0) { if (value < 1.0) do {
while ((fj = arg*10) < 1) { while (value * pp->pval < 10.0) {
arg = fj; value *= pp->pval;
r2--; *decpt -= pp->exp;
} }
} while ((++pp)->exp > 0);
(*decpt)++; /* because now value in [1.0, 10.0) */
} }
p1 = &buf[ndigits]; if (! ecvtflag) {
if (eflag==0) /* for fcvt() we need ndigit digits behind the dot */
p1 += r2; pe += *decpt;
*decpt = r2; if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
if (p1 < &buf[0]) {
buf[0] = '\0';
return(buf);
} }
while (p<=p1 && p<&buf[NDIG]) { while (p <= pe) {
arg = _fif(arg, 10.0, &fj); *p++ = (int)value + '0';
i = fj; value = 10.0 * (value - (int)value);
*p++ = i + '0';
} }
if (p1 >= &buf[NDIG]) { if (pe >= buf) {
buf[NDIG-1] = '\0'; p = pe;
return(buf); *p += 5; /* round of at the end */
} while (*p > '9') {
p = p1; *p = '0';
*p1 += 5; if (p > buf) ++*--p;
while (*p1 > '9') { else {
*p1 = '0'; *p = '1';
if (p1>buf) { ++*decpt;
p1--; *p1 += 1; if (! ecvtflag) {
} else { /* maybe add another digit at the end,
*p1 = '1'; because the point was shifted right
(*decpt)++; */
if (eflag==0) { if (pe > buf) *pe = '0';
if (p>buf) pe++;
*p = '0'; }
p++;
} }
} }
*pe = '\0';
} }
*p = '\0'; return buf;
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));
} }
#endif