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];
int i; /*!*/
if (ndigits<0) char *
ndigits = 0; _fcvt(value, ndigit, decpt, sign)
if (ndigits>=NDIG-1) double value;
ndigits = NDIG-2; int ndigit, *decpt, *sign;
r2 = 0; {
*sign = 0; return cvt(value, ndigit, decpt, sign, 0);
p = &buf[0]; }
if (arg<0) {
*sign = 1; static struct powers_of_10 {
arg = -arg; double pval;
} double rpval;
arg = _fif(arg, 1.0, &fi); int exp;
/* } p10[] = {
* Do integer part 1.0e32, 1.0e-32, 32,
*/ 1.0e16, 1.0e-16, 16,
if (fi != 0) { 1.0e8, 1.0e-8, 8,
p1 = &buf[NDIG]; 1.0e4, 1.0e-4, 4,
while (fi != 0) { 1.0e2, 1.0e-2, 2,
i = (_fif(fi, 0.1, &fi) + 0.03) * 10; 1.0e1, 1.0e-1, 1,
*--p1 = i + '0'; 1.0e0, 1.0e0, 0
r2++; };
}
while (p1 < &buf[NDIG]) static char *
*p++ = *p1++; cvt(value, ndigit, decpt, sign, ecvtflag)
} else if (arg > 0) { double value;
while ((fj = arg*10) < 1) { int ndigit, *decpt, *sign;
arg = fj; {
r2--; static char buf[NDIGITS+1];
} register char *p = buf;
} register char *pe;
p1 = &buf[ndigits];
if (eflag==0) if (ndigit < 0) ndigit = 0;
p1 += r2; if (ndigit > NDIGITS) ndigit = NDIGITS;
*decpt = r2; pe = &buf[ndigit];
if (p1 < &buf[0]) {
buf[0] = '\0'; buf[0] = '\0';
return(buf);
*sign = 0;
if (value < 0) {
*sign = 1;
value = -value;
} }
while (p<=p1 && p<&buf[NDIG]) {
arg = _fif(arg, 10.0, &fj); *decpt = 0;
i = fj; if (value != 0.0) {
*p++ = i + '0'; register struct powers_of_10 *pp = &p10[0];
if (value >= 10.0) do {
while (value >= pp->pval) {
value *= pp->rpval;
*decpt += pp->exp;
} }
if (p1 >= &buf[NDIG]) { } while ((++pp)->exp > 0);
buf[NDIG-1] = '\0';
return(buf); pp = &p10[0];
if (value < 1.0) do {
while (value * pp->pval < 10.0) {
value *= pp->pval;
*decpt -= pp->exp;
} }
p = p1; } while ((++pp)->exp > 0);
*p1 += 5;
while (*p1 > '9') { (*decpt)++; /* because now value in [1.0, 10.0) */
*p1 = '0'; }
if (p1>buf) { if (! ecvtflag) {
p1--; *p1 += 1; /* for fcvt() we need ndigit digits behind the dot */
} else { pe += *decpt;
*p1 = '1'; if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
(*decpt)++; }
if (eflag==0) { while (p <= pe) {
if (p>buf) *p++ = (int)value + '0';
value = 10.0 * (value - (int)value);
}
if (pe >= buf) {
p = pe;
*p += 5; /* round of at the end */
while (*p > '9') {
*p = '0'; *p = '0';
p++; 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++;
} }
} }
} }
*p = '\0'; *pe = '\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