154359Sroberto/*
254359Sroberto * dofptoa - do the grunge work to convert an fp number to ascii
354359Sroberto */
4280849Scy#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,
15358659Scy	char sign,
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	 */
36280849Scy	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;
109358659Scy	if (sign)
110358659Scy	    *bp++ = sign;
11154359Sroberto
11254359Sroberto	while (cp < cpend) {
11354359Sroberto		if (cp == cpdec)
11454359Sroberto		    *bp++ = '.';
11554359Sroberto		*bp++ = (char)(*cp++ + '0');
11654359Sroberto	}
11754359Sroberto	*bp = '\0';
11854359Sroberto	return buf;
11954359Sroberto}
120280849Scy
121280849Scy
122280849Scychar *
123280849Scyfptoa(
124280849Scy	s_fp	fpv,
125280849Scy	short	ndec
126280849Scy	)
127280849Scy{
128280849Scy	u_fp	plusfp;
129280849Scy	int	neg;
130280849Scy
131280849Scy	neg = (fpv < 0);
132280849Scy	if (neg) {
133280849Scy		plusfp = (u_fp)(-fpv);
134280849Scy	} else {
135280849Scy		plusfp = (u_fp)fpv;
136280849Scy	}
137280849Scy
138358659Scy	return dofptoa(plusfp, (neg?'-':0), ndec, FALSE);
139280849Scy}
140280849Scy
141280849Scy
142280849Scychar *
143280849Scyfptoms(
144280849Scy	s_fp	fpv,
145280849Scy	short	ndec
146280849Scy	)
147280849Scy{
148280849Scy	u_fp	plusfp;
149280849Scy	int	neg;
150280849Scy
151280849Scy	neg = (fpv < 0);
152280849Scy	if (neg) {
153280849Scy		plusfp = (u_fp)(-fpv);
154280849Scy	} else {
155280849Scy		plusfp = (u_fp)fpv;
156280849Scy	}
157280849Scy
158358659Scy	return dofptoa(plusfp, (neg?'-':0), ndec, TRUE);
159280849Scy}
160