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