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