|
|
1.1 root 1: /* @(#)ecvt.c 2.7 */
2: /* 3.0 SID # 1.2 */
3: /*LINTLIBRARY*/
4: /*
5: * ecvt converts to decimal
6: * the number of digits is specified by ndigit
7: * decpt is set to the position of the decimal point
8: * sign is set to 0 for positive, 1 for negative
9: *
10: */
11: #include <nan.h>
12: #include <values.h>
13: #define NMAX ((DSIGNIF * 3 + 19)/10) /* restrict max precision */
14: #define NDIG 80
15:
16: extern char *cvt();
17:
18: char *
19: ecvt(value, ndigit, decpt, sign)
20: double value;
21: int ndigit, *decpt, *sign;
22: {
23: return (cvt(value, ndigit, decpt, sign, 0));
24: }
25:
26: char *
27: fcvt(value, ndigit, decpt, sign)
28: double value;
29: int ndigit, *decpt, *sign;
30: {
31: return (cvt(value, ndigit, decpt, sign, 1));
32: }
33:
34: static char buf[NDIG];
35:
36: static char *
37: cvt(value, ndigit, decpt, sign, f_flag)
38: double value;
39: int ndigit, *sign, f_flag;
40: register int *decpt;
41: {
42: register char *p = &buf[0], *p_last = &buf[ndigit];
43:
44: KILLNaN(value); /* raise exception on Not-a-Number (3b only) */
45: if (*sign = (value < 0.0))
46: value = -value;
47: buf[0] = '\0';
48: *decpt = 0;
49: if (value != 0.0) { /* rescale to range [1.0, 10.0) */
50: /* in binary for speed and to minimize error build-up */
51: /* even for the IEEE standard with its high exponents,
52: it's probably better for speed to just loop on them */
53: static struct s { double p10; int n; } s[] = {
54: 1e32, 32,
55: 1e16, 16,
56: 1e8, 8,
57: 1e4, 4,
58: 1e2, 2,
59: 1e1, 1,
60: };
61: register struct s *sp = s;
62:
63: ++*decpt;
64: if (value >= 2.0 * MAXPOWTWO) /* can't be precisely integral */
65: do {
66: for ( ; value >= sp->p10; *decpt += sp->n)
67: value /= sp->p10;
68: } while (sp++->n > 1);
69: else if (value >= 10.0) { /* convert integer part separately */
70: register double pow10 = 10.0, powtemp;
71:
72: while ((powtemp = 10.0 * pow10) <= value)
73: pow10 = powtemp;
74: for ( ; ; pow10 /= 10.0) {
75: register int digit = value/pow10;
76: *p++ = digit + '0';
77: value -= digit * pow10;
78: ++*decpt;
79: if (pow10 <= 10.0)
80: break;
81: }
82: } else if (value < 1.0)
83: do {
84: for ( ; value * sp->p10 < 10.0; *decpt -= sp->n)
85: value *= sp->p10;
86: } while (sp++->n > 1);
87: }
88: if (f_flag)
89: p_last += *decpt;
90: if (p_last >= buf) {
91: if (p_last > &buf[NDIG - 2])
92: p_last = &buf[NDIG - 2];
93: for ( ; ; ++p) {
94: if (value == 0 || p >= &buf[NMAX])
95: *p = '0';
96: else {
97: register int intx; /* intx in [0, 9] */
98: *p = (intx = (int)value) + '0';
99: value = 10.0 * (value - (double)intx);
100: }
101: if (p >= p_last) {
102: p = p_last;
103: break;
104: }
105: }
106: if (*p >= '5') /* check rounding in last place + 1 */
107: do {
108: if (p == buf) { /* rollover from 99999... */
109: buf[0] = '1'; /* later digits are 0 */
110: ++*decpt;
111: if (f_flag)
112: ++p_last;
113: break;
114: }
115: *p-- = '0';
116: } while (++*p > '9'); /* propagate carries left */
117: *p_last = '\0';
118: }
119: return (buf);
120: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.