154359Sroberto/*
254359Sroberto * dofptoa - do the grunge work to convert an fp number to ascii
354359Sroberto */
454359Sroberto#include <stdio.h>
554359Sroberto
654359Sroberto#include "ntp_fp.h"
754359Sroberto#include "lib_strbuf.h"
854359Sroberto#include "ntp_string.h"
954359Sroberto#include "ntp_stdlib.h"
1054359Sroberto
1154359Srobertochar *
1254359Srobertodofptoa(
1354359Sroberto	u_fp fpv,
1454359Sroberto	int neg,
15132451Sroberto	short ndec,
1654359Sroberto	int msec
1754359Sroberto	)
1854359Sroberto{
1954359Sroberto	register u_char *cp, *cpend;
2054359Sroberto	register u_long val;
2154359Sroberto	register short dec;
2254359Sroberto	u_char cbuf[12];
2354359Sroberto	u_char *cpdec;
2454359Sroberto	char *buf;
2554359Sroberto	char *bp;
2654359Sroberto
2754359Sroberto	/*
2854359Sroberto	 * Get a string buffer before starting
2954359Sroberto	 */
3054359Sroberto	LIB_GETBUF(buf);
3154359Sroberto
3254359Sroberto	/*
3354359Sroberto	 * Zero out the buffer
3454359Sroberto	 */
3554359Sroberto	memset((char *)cbuf, 0, sizeof cbuf);
3654359Sroberto
3754359Sroberto	/*
3854359Sroberto	 * Set the pointers to point at the first
3954359Sroberto	 * decimal place.  Get a local copy of the value.
4054359Sroberto	 */
4154359Sroberto	cp = cpend = &cbuf[5];
4254359Sroberto	val = fpv;
4354359Sroberto
4454359Sroberto	/*
4554359Sroberto	 * If we have to, decode the integral part
4654359Sroberto	 */
4754359Sroberto	if (!(val & 0xffff0000))
4854359Sroberto	    cp--;
4954359Sroberto	else {
5054359Sroberto		register u_short sv = (u_short)(val >> 16);
5154359Sroberto		register u_short tmp;
5254359Sroberto		register u_short ten = 10;
5354359Sroberto
5454359Sroberto		do {
5554359Sroberto			tmp = sv;
56132451Sroberto			sv = (u_short) (sv/ten);
57132451Sroberto			*(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1)));
5854359Sroberto		} while (sv != 0);
5954359Sroberto	}
6054359Sroberto
6154359Sroberto	/*
6254359Sroberto	 * Figure out how much of the fraction to do
6354359Sroberto	 */
6454359Sroberto	if (msec) {
65132451Sroberto		dec = (short)(ndec + 3);
6654359Sroberto		if (dec < 3)
6754359Sroberto		    dec = 3;
6854359Sroberto		cpdec = &cbuf[8];
6954359Sroberto	} else {
7054359Sroberto		dec = ndec;
7154359Sroberto		cpdec = cpend;
7254359Sroberto	}
7354359Sroberto
7454359Sroberto	if (dec > 6)
7554359Sroberto	    dec = 6;
7654359Sroberto
7754359Sroberto	if (dec > 0) {
7854359Sroberto		do {
7954359Sroberto			val &= 0xffff;
8054359Sroberto			val = (val << 3) + (val << 1);
8154359Sroberto			*cpend++ = (u_char)(val >> 16);
8254359Sroberto		} while (--dec > 0);
8354359Sroberto	}
8454359Sroberto
8554359Sroberto	if (val & 0x8000) {
8654359Sroberto		register u_char *tp;
8754359Sroberto		/*
8854359Sroberto		 * Round it. Ick.
8954359Sroberto		 */
9054359Sroberto		tp = cpend;
9154359Sroberto		*(--tp) += 1;
9254359Sroberto		while (*tp >= 10) {
9354359Sroberto			*tp = 0;
9454359Sroberto			*(--tp) += 1;
9554359Sroberto		}
9654359Sroberto	}
9754359Sroberto
9854359Sroberto	/*
9954359Sroberto	 * Remove leading zeroes if necessary
10054359Sroberto	 */
10154359Sroberto	while (cp < (cpdec -1) && *cp == 0)
10254359Sroberto	    cp++;
10354359Sroberto
10454359Sroberto	/*
10554359Sroberto	 * Copy it into the buffer, asciizing as we go.
10654359Sroberto	 */
10754359Sroberto	bp = buf;
10854359Sroberto	if (neg)
10954359Sroberto	    *bp++ = '-';
11054359Sroberto
11154359Sroberto	while (cp < cpend) {
11254359Sroberto		if (cp == cpdec)
11354359Sroberto		    *bp++ = '.';
11454359Sroberto		*bp++ = (char)(*cp++ + '0');
11554359Sroberto	}
11654359Sroberto	*bp = '\0';
11754359Sroberto	return buf;
11854359Sroberto}
119