1 /*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.proprietary.c%
6 */
7
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)ecvt.c 8.1 (Berkeley) 06/04/93";
10 #endif /* LIBC_SCCS and not lint */
11
12 #if defined(hp300) && !defined(IEEE)
13 #define IEEE 1
14 #endif
15
16 /*
17 * ecvt converts to decimal
18 * the number of digits is specified by ndigit
19 * decpt is set to the position of the decimal point
20 * sign is set to 0 for positive, 1 for negative
21 */
22
23 static char *cvt();
24
25 #ifdef IEEE
26 #include <signal.h>
27 #define NDIG 512
28 #else
29 #define NDIG 80
30 #endif
31
32 char*
ecvt(arg,ndigits,decpt,sign)33 ecvt(arg, ndigits, decpt, sign)
34 double arg;
35 int ndigits, *decpt, *sign;
36 {
37 return(cvt(arg, ndigits, decpt, sign, 1));
38 }
39
40 char*
fcvt(arg,ndigits,decpt,sign)41 fcvt(arg, ndigits, decpt, sign)
42 double arg;
43 int ndigits, *decpt, *sign;
44 {
45 return(cvt(arg, ndigits, decpt, sign, 0));
46 }
47
48 static char*
cvt(arg,ndigits,decpt,sign,eflag)49 cvt(arg, ndigits, decpt, sign, eflag)
50 double arg;
51 int ndigits, *decpt, *sign;
52 {
53 register int r2;
54 double fi, fj;
55 register char *p, *p1;
56 static char buf[NDIG];
57 double modf();
58
59 #ifdef IEEE
60 /* XXX */
61 if (isspecial(arg, buf))
62 return(buf);
63 #endif
64 if (ndigits<0)
65 ndigits = 0;
66 if (ndigits>=NDIG-1)
67 ndigits = NDIG-2;
68 r2 = 0;
69 *sign = 0;
70 p = &buf[0];
71 if (arg<0) {
72 *sign = 1;
73 arg = -arg;
74 }
75 arg = modf(arg, &fi);
76 p1 = &buf[NDIG];
77 /*
78 * Do integer part
79 */
80 if (fi != 0) {
81 p1 = &buf[NDIG];
82 while (fi != 0) {
83 fj = modf(fi/10, &fi);
84 *--p1 = (int)((fj+.03)*10) + '0';
85 r2++;
86 }
87 while (p1 < &buf[NDIG])
88 *p++ = *p1++;
89 } else if (arg > 0) {
90 while ((fj = arg*10) < 1) {
91 arg = fj;
92 r2--;
93 }
94 }
95 p1 = &buf[ndigits];
96 if (eflag==0)
97 p1 += r2;
98 *decpt = r2;
99 if (p1 < &buf[0]) {
100 buf[0] = '\0';
101 return(buf);
102 }
103 while (p<=p1 && p<&buf[NDIG]) {
104 arg *= 10;
105 arg = modf(arg, &fj);
106 *p++ = (int)fj + '0';
107 }
108 if (p1 >= &buf[NDIG]) {
109 buf[NDIG-1] = '\0';
110 return(buf);
111 }
112 p = p1;
113 *p1 += 5;
114 while (*p1 > '9') {
115 *p1 = '0';
116 if (p1>buf)
117 ++*--p1;
118 else {
119 *p1 = '1';
120 (*decpt)++;
121 if (eflag==0) {
122 if (p>buf)
123 *p = '0';
124 p++;
125 }
126 }
127 }
128 *p = '\0';
129 return(buf);
130 }
131
132 #ifdef IEEE
133 struct IEEEdp {
134 unsigned sign:1,
135 exp:11,
136 manh:20,
137 manl:32;
138 };
139
isspecial(f,bp)140 isspecial(f, bp)
141 double f;
142 char *bp;
143 {
144 register struct IEEEdp *ip = (struct IEEEdp *) &f;
145
146 if (ip->exp != 0x7ff)
147 return(0);
148 if (ip->manh || ip->manl)
149 strcpy(bp, "NaN");
150 else if (ip->sign)
151 strcpy(bp, "-Infinity");
152 else
153 strcpy(bp, "Infinity");
154 return(1);
155 }
156 #endif
157