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