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