1 | /* $Header: /cvsup/minix/src/lib/ack/libp/cvt.c,v 1.1 2005/10/10 15:27:46 beng Exp $ */
|
---|
2 | #ifndef NOFLOAT
|
---|
3 |
|
---|
4 | #if __STDC__
|
---|
5 | #include <float.h>
|
---|
6 | #else
|
---|
7 | #include <math.h>
|
---|
8 | #define DBL_MAX M_MAX_D
|
---|
9 | #endif
|
---|
10 |
|
---|
11 | static char *cvt();
|
---|
12 | #define NDIGITS 128
|
---|
13 |
|
---|
14 | char *
|
---|
15 | _ecvt(value, ndigit, decpt, sign)
|
---|
16 | double value;
|
---|
17 | int ndigit, *decpt, *sign;
|
---|
18 | {
|
---|
19 | return cvt(value, ndigit, decpt, sign, 1);
|
---|
20 | }
|
---|
21 |
|
---|
22 | char *
|
---|
23 | _fcvt(value, ndigit, decpt, sign)
|
---|
24 | double value;
|
---|
25 | int ndigit, *decpt, *sign;
|
---|
26 | {
|
---|
27 | return cvt(value, ndigit, decpt, sign, 0);
|
---|
28 | }
|
---|
29 |
|
---|
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
|
---|
42 | };
|
---|
43 |
|
---|
44 | static char *
|
---|
45 | cvt(value, ndigit, decpt, sign, ecvtflag)
|
---|
46 | double value;
|
---|
47 | int ndigit, *decpt, *sign;
|
---|
48 | {
|
---|
49 | static char buf[NDIGITS+1];
|
---|
50 | register char *p = buf;
|
---|
51 | register char *pe;
|
---|
52 |
|
---|
53 | if (ndigit < 0) ndigit = 0;
|
---|
54 | if (ndigit > NDIGITS) ndigit = NDIGITS;
|
---|
55 | pe = &buf[ndigit];
|
---|
56 | buf[0] = '\0';
|
---|
57 |
|
---|
58 | *sign = 0;
|
---|
59 | if (value < 0) {
|
---|
60 | *sign = 1;
|
---|
61 | value = -value;
|
---|
62 | }
|
---|
63 |
|
---|
64 | *decpt = 0;
|
---|
65 | if (value >= DBL_MAX) {
|
---|
66 | value = DBL_MAX;
|
---|
67 | }
|
---|
68 | if (value != 0.0) {
|
---|
69 | register struct powers_of_10 *pp = &p10[0];
|
---|
70 |
|
---|
71 | if (value >= 10.0) do {
|
---|
72 | while (value >= pp->pval) {
|
---|
73 | value *= pp->rpval;
|
---|
74 | *decpt += pp->exp;
|
---|
75 | }
|
---|
76 | } while ((++pp)->exp > 0);
|
---|
77 |
|
---|
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;
|
---|
83 | }
|
---|
84 | } while ((++pp)->exp > 0);
|
---|
85 |
|
---|
86 | (*decpt)++; /* because now value in [1.0, 10.0) */
|
---|
87 | }
|
---|
88 | if (! ecvtflag) {
|
---|
89 | /* for fcvt() we need ndigit digits behind the dot */
|
---|
90 | pe += *decpt;
|
---|
91 | if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
|
---|
92 | }
|
---|
93 | while (p <= pe) {
|
---|
94 | *p++ = (int)value + '0';
|
---|
95 | value = 10.0 * (value - (int)value);
|
---|
96 | }
|
---|
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
|
---|
109 | */
|
---|
110 | if (pe > buf) *pe = '0';
|
---|
111 | pe++;
|
---|
112 | }
|
---|
113 | }
|
---|
114 | }
|
---|
115 | *pe = '\0';
|
---|
116 | }
|
---|
117 | return buf;
|
---|
118 | }
|
---|
119 | #endif
|
---|