1987-03-31 10:45:53 +00:00
|
|
|
/* $Header$ */
|
1987-01-27 15:57:55 +00:00
|
|
|
#ifndef NOFLOAT
|
|
|
|
extern double modf();
|
|
|
|
static char *cvt();
|
|
|
|
#define NDIGITS 128
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
cvt(value, ndigit, decpt, sign, ecvtflag)
|
|
|
|
double value;
|
|
|
|
int ndigit, *decpt, *sign;
|
|
|
|
{
|
|
|
|
double intpart, fractpart;
|
|
|
|
static char buf[NDIGITS];
|
|
|
|
char buf1[NDIGITS];
|
|
|
|
register char *pe = buf1;
|
1987-02-05 20:47:30 +00:00
|
|
|
register char *pb;
|
1987-01-27 15:57:55 +00:00
|
|
|
int pointpos = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (ndigit < 0) ndigit = 0;
|
1987-02-05 20:47:30 +00:00
|
|
|
if (ndigit >= NDIGITS - 10) ndigit = NDIGITS - 11;
|
1987-01-27 15:57:55 +00:00
|
|
|
|
|
|
|
*sign = 0;
|
|
|
|
if (value < 0) {
|
|
|
|
*sign = 1;
|
|
|
|
value = -value;
|
|
|
|
}
|
|
|
|
|
|
|
|
fractpart = modf(value, &intpart);
|
|
|
|
if (intpart != 0) {
|
|
|
|
do { /* get digits of integer part, low order digit
|
|
|
|
first
|
|
|
|
*/
|
|
|
|
value = modf(intpart/10, &intpart);
|
|
|
|
/* compensate for rounding errors, because
|
|
|
|
the conversion to "int" truncates
|
|
|
|
*/
|
1987-02-05 20:47:30 +00:00
|
|
|
if (pe >= &buf1[NDIGITS]) {
|
|
|
|
pb = &buf1[NDIGITS-10];
|
|
|
|
while (pb > buf1) *--pb = *--pe;
|
|
|
|
pe = &buf[NDIGITS-10];
|
|
|
|
}
|
1987-01-27 15:57:55 +00:00
|
|
|
*pe++ = (int)((value+.05) * 10) + '0';
|
|
|
|
pointpos++;
|
|
|
|
} while (intpart != 0);
|
1987-02-06 13:28:01 +00:00
|
|
|
pb = buf;
|
1987-01-27 15:57:55 +00:00
|
|
|
while (pe > buf1) *pb++ = *--pe;
|
|
|
|
}
|
1987-02-06 14:50:57 +00:00
|
|
|
else {
|
|
|
|
pb = &buf[0];
|
|
|
|
if (value > 0) {
|
1987-01-27 15:57:55 +00:00
|
|
|
fractpart = value;
|
1987-02-06 14:50:57 +00:00
|
|
|
while ((value = value*10) < 1) {
|
|
|
|
fractpart = value;
|
|
|
|
pointpos--;
|
|
|
|
}
|
1987-01-27 15:57:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pe = &buf[ndigit];
|
|
|
|
if (! ecvtflag) {
|
|
|
|
/* for fcvt() we need ndigit digits behind the dot */
|
|
|
|
pe += pointpos;
|
|
|
|
if (pe < buf) {
|
|
|
|
/* pointpos was too far left of the beginning */
|
|
|
|
buf[0] = 0;
|
|
|
|
*decpt = pointpos;
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
|
|
|
|
}
|
|
|
|
while (pb <= pe) {
|
|
|
|
fractpart = modf(fractpart * 10, &value);
|
|
|
|
*pb++ = (int)value + '0';
|
|
|
|
}
|
1987-02-05 20:39:11 +00:00
|
|
|
pb = pe;
|
1987-01-27 15:57:55 +00:00
|
|
|
*pb += 5; /* round of at the end */
|
|
|
|
while (*pb > '9') {
|
|
|
|
*pb = '0';
|
|
|
|
if (pb > buf) ++*--pb;
|
|
|
|
else {
|
|
|
|
*pb = '1';
|
|
|
|
pointpos++;
|
|
|
|
if (! ecvtflag) {
|
|
|
|
/* maybe add another digit at the end,
|
|
|
|
because the point was shifted right
|
|
|
|
*/
|
|
|
|
if (pe > buf) *pe = '0';
|
|
|
|
pe++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*decpt = pointpos;
|
|
|
|
*pe = '\0';
|
1987-02-06 13:28:01 +00:00
|
|
|
return buf;
|
1987-01-27 15:57:55 +00:00
|
|
|
}
|
|
|
|
#endif
|