2018-06-17 20:30:27 +00:00
|
|
|
#include "pc.h"
|
|
|
|
|
1994-06-24 14:02:31 +00:00
|
|
|
/* $Id$ */
|
1988-08-10 11:21:40 +00:00
|
|
|
#ifndef NOFLOAT
|
1984-07-20 11:20:12 +00:00
|
|
|
|
1991-03-19 10:25:36 +00:00
|
|
|
#if __STDC__
|
|
|
|
#include <float.h>
|
1991-03-20 11:30:35 +00:00
|
|
|
#else
|
|
|
|
#include <math.h>
|
2018-06-17 14:11:29 +00:00
|
|
|
#define DBL_MAX M_MAX_D
|
1991-03-19 10:25:36 +00:00
|
|
|
#endif
|
|
|
|
|
2018-06-17 20:30:27 +00:00
|
|
|
static char* cvt(double value, int ndigit, int* decpt, int* sign, int ecvtflag);
|
|
|
|
|
2018-06-17 14:11:29 +00:00
|
|
|
#define NDIGITS 128
|
1984-07-20 10:44:57 +00:00
|
|
|
|
2018-06-17 20:30:27 +00:00
|
|
|
char *_ecvt(double value, int ndigit, int *decpt, int *sign)
|
1988-08-10 11:21:40 +00:00
|
|
|
{
|
|
|
|
return cvt(value, ndigit, decpt, sign, 1);
|
|
|
|
}
|
|
|
|
|
2018-06-17 20:30:27 +00:00
|
|
|
char *_fcvt(double value, int ndigit, int *decpt, int *sign)
|
1988-08-10 11:21:40 +00:00
|
|
|
{
|
|
|
|
return cvt(value, ndigit, decpt, sign, 0);
|
|
|
|
}
|
1984-07-20 10:44:57 +00:00
|
|
|
|
2018-06-17 14:11:29 +00:00
|
|
|
static struct powers_of_10
|
|
|
|
{
|
1988-08-10 11:21:40 +00:00
|
|
|
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
|
|
|
|
};
|
1984-07-20 10:44:57 +00:00
|
|
|
|
2018-06-17 20:30:27 +00:00
|
|
|
static char* cvt(double value, int ndigit, int* decpt, int* sign, int ecvtflag)
|
1984-07-20 10:44:57 +00:00
|
|
|
{
|
2018-06-17 14:11:29 +00:00
|
|
|
static char buf[NDIGITS + 1];
|
|
|
|
register char* p = buf;
|
|
|
|
register char* pe;
|
1988-08-10 11:21:40 +00:00
|
|
|
|
2018-06-17 14:11:29 +00:00
|
|
|
if (ndigit < 0)
|
|
|
|
ndigit = 0;
|
|
|
|
if (ndigit > NDIGITS)
|
|
|
|
ndigit = NDIGITS;
|
1988-08-10 11:21:40 +00:00
|
|
|
pe = &buf[ndigit];
|
|
|
|
buf[0] = '\0';
|
1984-07-20 10:44:57 +00:00
|
|
|
|
|
|
|
*sign = 0;
|
2018-06-17 14:11:29 +00:00
|
|
|
if (value < 0)
|
|
|
|
{
|
1984-07-20 10:44:57 +00:00
|
|
|
*sign = 1;
|
1988-08-10 11:21:40 +00:00
|
|
|
value = -value;
|
1984-07-20 10:44:57 +00:00
|
|
|
}
|
1988-08-10 11:21:40 +00:00
|
|
|
|
|
|
|
*decpt = 0;
|
2018-06-17 14:11:29 +00:00
|
|
|
if (value >= DBL_MAX)
|
|
|
|
{
|
1991-03-19 10:25:36 +00:00
|
|
|
value = DBL_MAX;
|
|
|
|
}
|
2018-06-17 14:11:29 +00:00
|
|
|
if (value != 0.0)
|
|
|
|
{
|
|
|
|
register struct powers_of_10* pp = &p10[0];
|
1988-08-10 11:21:40 +00:00
|
|
|
|
2018-06-17 14:11:29 +00:00
|
|
|
if (value >= 10.0)
|
|
|
|
do
|
|
|
|
{
|
|
|
|
while (value >= pp->pval)
|
|
|
|
{
|
|
|
|
value *= pp->rpval;
|
|
|
|
*decpt += pp->exp;
|
|
|
|
}
|
|
|
|
} while ((++pp)->exp > 0);
|
1988-08-10 11:21:40 +00:00
|
|
|
|
|
|
|
pp = &p10[0];
|
2018-06-17 14:11:29 +00:00
|
|
|
if (value < 1.0)
|
|
|
|
do
|
|
|
|
{
|
|
|
|
while (value * pp->pval < 10.0)
|
|
|
|
{
|
|
|
|
value *= pp->pval;
|
|
|
|
*decpt -= pp->exp;
|
|
|
|
}
|
|
|
|
} while ((++pp)->exp > 0);
|
1988-08-10 11:21:40 +00:00
|
|
|
|
2018-06-17 14:11:29 +00:00
|
|
|
(*decpt)++; /* because now value in [1.0, 10.0) */
|
1984-07-20 10:44:57 +00:00
|
|
|
}
|
2018-06-17 14:11:29 +00:00
|
|
|
if (!ecvtflag)
|
|
|
|
{
|
1988-08-10 11:21:40 +00:00
|
|
|
/* for fcvt() we need ndigit digits behind the dot */
|
|
|
|
pe += *decpt;
|
2018-06-17 14:11:29 +00:00
|
|
|
if (pe > &buf[NDIGITS])
|
|
|
|
pe = &buf[NDIGITS];
|
1984-07-20 10:44:57 +00:00
|
|
|
}
|
2018-06-17 14:11:29 +00:00
|
|
|
while (p <= pe)
|
|
|
|
{
|
1988-08-10 11:21:40 +00:00
|
|
|
*p++ = (int)value + '0';
|
|
|
|
value = 10.0 * (value - (int)value);
|
1984-07-20 10:44:57 +00:00
|
|
|
}
|
2018-06-17 14:11:29 +00:00
|
|
|
if (pe >= buf)
|
|
|
|
{
|
1988-08-10 11:21:40 +00:00
|
|
|
p = pe;
|
2018-06-17 14:11:29 +00:00
|
|
|
*p += 5; /* round of at the end */
|
|
|
|
while (*p > '9')
|
|
|
|
{
|
1988-08-10 11:21:40 +00:00
|
|
|
*p = '0';
|
2018-06-17 14:11:29 +00:00
|
|
|
if (p > buf)
|
|
|
|
++*--p;
|
|
|
|
else
|
|
|
|
{
|
1988-08-10 11:21:40 +00:00
|
|
|
*p = '1';
|
|
|
|
++*decpt;
|
2018-06-17 14:11:29 +00:00
|
|
|
if (!ecvtflag)
|
|
|
|
{
|
1988-08-10 11:21:40 +00:00
|
|
|
/* maybe add another digit at the end,
|
|
|
|
because the point was shifted right
|
|
|
|
*/
|
2018-06-17 14:11:29 +00:00
|
|
|
if (pe > buf)
|
|
|
|
*pe = '0';
|
1988-08-10 11:21:40 +00:00
|
|
|
pe++;
|
|
|
|
}
|
1984-07-20 10:44:57 +00:00
|
|
|
}
|
|
|
|
}
|
1988-08-10 11:21:40 +00:00
|
|
|
*pe = '\0';
|
1984-07-20 10:44:57 +00:00
|
|
|
}
|
1988-08-10 11:21:40 +00:00
|
|
|
return buf;
|
1984-07-20 10:44:57 +00:00
|
|
|
}
|
1988-08-10 11:21:40 +00:00
|
|
|
#endif
|