1/*
2 * dofptoa - do the grunge work to convert an fp number to ascii
3 */
4#include <config.h>
5#include <stdio.h>
6
7#include "ntp_fp.h"
8#include "ntp_stdlib.h"
9
10char *
11dofptoa(
12	u_fp fpv,
13	char sign,
14	short ndec,
15	int msec
16	)
17{
18	register u_char *cp, *cpend;
19	register u_long val;
20	register short dec;
21	u_char cbuf[12];
22	u_char *cpdec;
23	char *buf;
24	char *bp;
25
26	/*
27	 * Get a string buffer before starting
28	 */
29	LIB_GETBUF(buf);
30
31	/*
32	 * Zero out the buffer
33	 */
34	ZERO(cbuf);
35
36	/*
37	 * Set the pointers to point at the first
38	 * decimal place.  Get a local copy of the value.
39	 */
40	cp = cpend = &cbuf[5];
41	val = fpv;
42
43	/*
44	 * If we have to, decode the integral part
45	 */
46	if (!(val & 0xffff0000))
47	    cp--;
48	else {
49		register u_short sv = (u_short)(val >> 16);
50		register u_short tmp;
51		register u_short ten = 10;
52
53		do {
54			tmp = sv;
55			sv = (u_short) (sv/ten);
56			*(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1)));
57		} while (sv != 0);
58	}
59
60	/*
61	 * Figure out how much of the fraction to do
62	 */
63	if (msec) {
64		dec = (short)(ndec + 3);
65		if (dec < 3)
66		    dec = 3;
67		cpdec = &cbuf[8];
68	} else {
69		dec = ndec;
70		cpdec = cpend;
71	}
72
73	if (dec > 6)
74	    dec = 6;
75
76	if (dec > 0) {
77		do {
78			val &= 0xffff;
79			val = (val << 3) + (val << 1);
80			*cpend++ = (u_char)(val >> 16);
81		} while (--dec > 0);
82	}
83
84	if (val & 0x8000) {
85		register u_char *tp;
86		/*
87		 * Round it. Ick.
88		 */
89		tp = cpend;
90		*(--tp) += 1;
91		while (*tp >= 10) {
92			*tp = 0;
93			*(--tp) += 1;
94		}
95	}
96
97	/*
98	 * Remove leading zeroes if necessary
99	 */
100	while (cp < (cpdec -1) && *cp == 0)
101	    cp++;
102
103	/*
104	 * Copy it into the buffer, asciizing as we go.
105	 */
106	bp = buf;
107	if (sign)
108	    *bp++ = sign;
109
110	while (cp < cpend) {
111		if (cp == cpdec)
112		    *bp++ = '.';
113		*bp++ = (char)(*cp++ + '0');
114	}
115	*bp = '\0';
116	return buf;
117}
118
119
120char *
121fptoa(
122	s_fp	fpv,
123	short	ndec
124	)
125{
126	u_fp	plusfp;
127	int	neg;
128
129	neg = (fpv < 0);
130	if (neg) {
131		plusfp = (u_fp)(-fpv);
132	} else {
133		plusfp = (u_fp)fpv;
134	}
135
136	return dofptoa(plusfp, (neg?'-':0), ndec, FALSE);
137}
138
139
140char *
141fptoms(
142	s_fp	fpv,
143	short	ndec
144	)
145{
146	u_fp	plusfp;
147	int	neg;
148
149	neg = (fpv < 0);
150	if (neg) {
151		plusfp = (u_fp)(-fpv);
152	} else {
153		plusfp = (u_fp)fpv;
154	}
155
156	return dofptoa(plusfp, (neg?'-':0), ndec, TRUE);
157}
158