154359Sroberto/*
254359Sroberto * dofptoa - do the grunge work to convert an fp number to ascii
354359Sroberto */
4285612Sdelphij#include <config.h>
554359Sroberto#include <stdio.h>
654359Sroberto
754359Sroberto#include "ntp_fp.h"
854359Sroberto#include "lib_strbuf.h"
954359Sroberto#include "ntp_string.h"
1054359Sroberto#include "ntp_stdlib.h"
1154359Sroberto
1254359Srobertochar *
1354359Srobertodofptoa(
1454359Sroberto	u_fp fpv,
1554359Sroberto	int neg,
16132451Sroberto	short ndec,
1754359Sroberto	int msec
1854359Sroberto	)
1954359Sroberto{
2054359Sroberto	register u_char *cp, *cpend;
2154359Sroberto	register u_long val;
2254359Sroberto	register short dec;
2354359Sroberto	u_char cbuf[12];
2454359Sroberto	u_char *cpdec;
2554359Sroberto	char *buf;
2654359Sroberto	char *bp;
2754359Sroberto
2854359Sroberto	/*
2954359Sroberto	 * Get a string buffer before starting
3054359Sroberto	 */
3154359Sroberto	LIB_GETBUF(buf);
3254359Sroberto
3354359Sroberto	/*
3454359Sroberto	 * Zero out the buffer
3554359Sroberto	 */
36285612Sdelphij	ZERO(cbuf);
3754359Sroberto
3854359Sroberto	/*
3954359Sroberto	 * Set the pointers to point at the first
4054359Sroberto	 * decimal place.  Get a local copy of the value.
4154359Sroberto	 */
4254359Sroberto	cp = cpend = &cbuf[5];
4354359Sroberto	val = fpv;
4454359Sroberto
4554359Sroberto	/*
4654359Sroberto	 * If we have to, decode the integral part
4754359Sroberto	 */
4854359Sroberto	if (!(val & 0xffff0000))
4954359Sroberto	    cp--;
5054359Sroberto	else {
5154359Sroberto		register u_short sv = (u_short)(val >> 16);
5254359Sroberto		register u_short tmp;
5354359Sroberto		register u_short ten = 10;
5454359Sroberto
5554359Sroberto		do {
5654359Sroberto			tmp = sv;
57132451Sroberto			sv = (u_short) (sv/ten);
58132451Sroberto			*(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1)));
5954359Sroberto		} while (sv != 0);
6054359Sroberto	}
6154359Sroberto
6254359Sroberto	/*
6354359Sroberto	 * Figure out how much of the fraction to do
6454359Sroberto	 */
6554359Sroberto	if (msec) {
66132451Sroberto		dec = (short)(ndec + 3);
6754359Sroberto		if (dec < 3)
6854359Sroberto		    dec = 3;
6954359Sroberto		cpdec = &cbuf[8];
7054359Sroberto	} else {
7154359Sroberto		dec = ndec;
7254359Sroberto		cpdec = cpend;
7354359Sroberto	}
7454359Sroberto
7554359Sroberto	if (dec > 6)
7654359Sroberto	    dec = 6;
7754359Sroberto
7854359Sroberto	if (dec > 0) {
7954359Sroberto		do {
8054359Sroberto			val &= 0xffff;
8154359Sroberto			val = (val << 3) + (val << 1);
8254359Sroberto			*cpend++ = (u_char)(val >> 16);
8354359Sroberto		} while (--dec > 0);
8454359Sroberto	}
8554359Sroberto
8654359Sroberto	if (val & 0x8000) {
8754359Sroberto		register u_char *tp;
8854359Sroberto		/*
8954359Sroberto		 * Round it. Ick.
9054359Sroberto		 */
9154359Sroberto		tp = cpend;
9254359Sroberto		*(--tp) += 1;
9354359Sroberto		while (*tp >= 10) {
9454359Sroberto			*tp = 0;
9554359Sroberto			*(--tp) += 1;
9654359Sroberto		}
9754359Sroberto	}
9854359Sroberto
9954359Sroberto	/*
10054359Sroberto	 * Remove leading zeroes if necessary
10154359Sroberto	 */
10254359Sroberto	while (cp < (cpdec -1) && *cp == 0)
10354359Sroberto	    cp++;
10454359Sroberto
10554359Sroberto	/*
10654359Sroberto	 * Copy it into the buffer, asciizing as we go.
10754359Sroberto	 */
10854359Sroberto	bp = buf;
10954359Sroberto	if (neg)
11054359Sroberto	    *bp++ = '-';
11154359Sroberto
11254359Sroberto	while (cp < cpend) {
11354359Sroberto		if (cp == cpdec)
11454359Sroberto		    *bp++ = '.';
11554359Sroberto		*bp++ = (char)(*cp++ + '0');
11654359Sroberto	}
11754359Sroberto	*bp = '\0';
11854359Sroberto	return buf;
11954359Sroberto}
120285612Sdelphij
121285612Sdelphij
122285612Sdelphijchar *
123285612Sdelphijfptoa(
124285612Sdelphij	s_fp	fpv,
125285612Sdelphij	short	ndec
126285612Sdelphij	)
127285612Sdelphij{
128285612Sdelphij	u_fp	plusfp;
129285612Sdelphij	int	neg;
130285612Sdelphij
131285612Sdelphij	neg = (fpv < 0);
132285612Sdelphij	if (neg) {
133285612Sdelphij		plusfp = (u_fp)(-fpv);
134285612Sdelphij	} else {
135285612Sdelphij		plusfp = (u_fp)fpv;
136285612Sdelphij	}
137285612Sdelphij
138285612Sdelphij	return dofptoa(plusfp, neg, ndec, FALSE);
139285612Sdelphij}
140285612Sdelphij
141285612Sdelphij
142285612Sdelphijchar *
143285612Sdelphijfptoms(
144285612Sdelphij	s_fp	fpv,
145285612Sdelphij	short	ndec
146285612Sdelphij	)
147285612Sdelphij{
148285612Sdelphij	u_fp	plusfp;
149285612Sdelphij	int	neg;
150285612Sdelphij
151285612Sdelphij	neg = (fpv < 0);
152285612Sdelphij	if (neg) {
153285612Sdelphij		plusfp = (u_fp)(-fpv);
154285612Sdelphij	} else {
155285612Sdelphij		plusfp = (u_fp)fpv;
156285612Sdelphij	}
157285612Sdelphij
158285612Sdelphij	return dofptoa(plusfp, neg, ndec, TRUE);
159285612Sdelphij}
160