* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / libc / i386fp / ecvt.c
blob6e0cef1e4af576569e965676c707d85471b3adb2
2 #define DIGMAX 30 /* max # of digits in string */
3 #define DIGPREC 17 /* max # of significant digits */
4 #define ECVT 0
5 #define FCVT 1
6 static char digstr[DIGMAX + 1 + 1]; /* +1 for end of string */
8 /* +1 in case rounding adds */
9 /* another digit */
10 static double negtab[] =
11 { 1e-256, 1e-128, 1e-64, 1e-32, 1e-16, 1e-8, 1e-4, 1e-2, 1e-1, 1.0 };
12 static double postab[] =
13 { 1e+256, 1e+128, 1e+64, 1e+32, 1e+16, 1e+8, 1e+4, 1e+2, 1e+1 };
15 static char *_cvt();
17 /*************************
18 * Convert double val to a string of
19 * decimal digits.
20 * ndig = # of digits in resulting string
21 * Returns:
22 * *pdecpt = position of decimal point from left of first digit
23 * *psign = nonzero if value was negative
25 char *
26 ecvt(val, ndig, pdecpt, psign)
27 double val;
28 int ndig, *pdecpt, *psign;
31 return _cvt(ECVT, val, ndig, pdecpt, psign);
34 char *
35 fcvt(val, nfrac, pdecpt, psign)
36 double val;
37 int nfrac, *pdecpt, *psign;
40 return _cvt(FCVT, val, nfrac, pdecpt, psign);
43 static char *
44 _cvt(cnvflag, val, ndig, pdecpt, psign)
45 double val;
46 int ndig, *pdecpt, *psign;
49 int decpt, pow, i;
50 char *p;
51 *psign = (val < 0) ? ((val = -val), 1) : 0;
52 ndig = (ndig < 0) ? 0 : (ndig < DIGMAX) ? ndig : DIGMAX;
53 if (val == 0) {
54 for (p = &digstr[0]; p < &digstr[ndig]; p++)
55 *p = '0';
56 decpt = 0;
57 } else {
58 /* Adjust things so that 1 <= val < 10 */
59 /* in these loops if val == MAXDOUBLE) */
60 decpt = 1;
61 pow = 256;
62 i = 0;
63 while (val < 1) {
64 while (val < negtab[i + 1]) {
65 val /= negtab[i];
66 decpt -= pow;
68 pow >>= 1;
69 i++;
71 pow = 256;
72 i = 0;
73 while (val >= 10) {
74 while (val >= postab[i]) {
75 val /= postab[i];
76 decpt += pow;
78 pow >>= 1;
79 i++;
81 if (cnvflag == FCVT) {
82 ndig += decpt;
83 ndig = (ndig < 0) ? 0 : (ndig < DIGMAX) ? ndig : DIGMAX;
86 /* Pick off digits 1 by 1 and stuff into digstr[] */
87 /* Do 1 extra digit for rounding purposes */
88 for (p = &digstr[0]; p <= &digstr[ndig]; p++) {
89 int n;
91 /* 'twould be silly to have zillions of digits */
92 /* when only DIGPREC are significant */
93 if (p >= &digstr[DIGPREC])
94 *p = '0';
96 else {
97 n = val;
98 *p = n + '0';
99 val = (val - n) * 10; /* get next digit */
102 if (*--p >= '5') { /* if we need to round */
103 while (1) {
104 if (p == &digstr[0]) { /* if at start */
105 ndig += cnvflag;
106 decpt++; /* shift dec pnt */
107 digstr[0] = '1'; /* "100000..." */
108 break;
110 *p = '0';
111 --p;
112 if (*p != '9') {
113 (*p)++;
114 break;
116 } /* while */
117 } /* if */
118 } /* else */
119 *pdecpt = decpt;
120 digstr[ndig] = 0; /* terminate string */
121 return &digstr[0];