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