Don't install progressbar suid.
[minix3.git] / lib / ack / libp / cvt.c
blobd3c2116dcc9148e5c62af03183a68ed5dc16fe2c
1 /* $Header$ */
2 #ifndef NOFLOAT
4 #if __STDC__
5 #include <float.h>
6 #else
7 #include <math.h>
8 #define DBL_MAX M_MAX_D
9 #endif
11 static char *cvt();
12 #define NDIGITS 128
14 char *
15 _ecvt(value, ndigit, decpt, sign)
16 double value;
17 int ndigit, *decpt, *sign;
19 return cvt(value, ndigit, decpt, sign, 1);
22 char *
23 _fcvt(value, ndigit, decpt, sign)
24 double value;
25 int ndigit, *decpt, *sign;
27 return cvt(value, ndigit, decpt, sign, 0);
30 static struct powers_of_10 {
31 double pval;
32 double rpval;
33 int exp;
34 } p10[] = {
35 1.0e32, 1.0e-32, 32,
36 1.0e16, 1.0e-16, 16,
37 1.0e8, 1.0e-8, 8,
38 1.0e4, 1.0e-4, 4,
39 1.0e2, 1.0e-2, 2,
40 1.0e1, 1.0e-1, 1,
41 1.0e0, 1.0e0, 0
44 static char *
45 cvt(value, ndigit, decpt, sign, ecvtflag)
46 double value;
47 int ndigit, *decpt, *sign;
49 static char buf[NDIGITS+1];
50 register char *p = buf;
51 register char *pe;
53 if (ndigit < 0) ndigit = 0;
54 if (ndigit > NDIGITS) ndigit = NDIGITS;
55 pe = &buf[ndigit];
56 buf[0] = '\0';
58 *sign = 0;
59 if (value < 0) {
60 *sign = 1;
61 value = -value;
64 *decpt = 0;
65 if (value >= DBL_MAX) {
66 value = DBL_MAX;
68 if (value != 0.0) {
69 register struct powers_of_10 *pp = &p10[0];
71 if (value >= 10.0) do {
72 while (value >= pp->pval) {
73 value *= pp->rpval;
74 *decpt += pp->exp;
76 } while ((++pp)->exp > 0);
78 pp = &p10[0];
79 if (value < 1.0) do {
80 while (value * pp->pval < 10.0) {
81 value *= pp->pval;
82 *decpt -= pp->exp;
84 } while ((++pp)->exp > 0);
86 (*decpt)++; /* because now value in [1.0, 10.0) */
88 if (! ecvtflag) {
89 /* for fcvt() we need ndigit digits behind the dot */
90 pe += *decpt;
91 if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
93 while (p <= pe) {
94 *p++ = (int)value + '0';
95 value = 10.0 * (value - (int)value);
97 if (pe >= buf) {
98 p = pe;
99 *p += 5; /* round of at the end */
100 while (*p > '9') {
101 *p = '0';
102 if (p > buf) ++*--p;
103 else {
104 *p = '1';
105 ++*decpt;
106 if (! ecvtflag) {
107 /* maybe add another digit at the end,
108 because the point was shifted right
110 if (pe > buf) *pe = '0';
111 pe++;
115 *pe = '\0';
117 return buf;
119 #endif