]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/libntp/dofptoa.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / ntp / libntp / dofptoa.c
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 "lib_strbuf.h"
9 #include "ntp_string.h"
10 #include "ntp_stdlib.h"
11
12 char *
13 dofptoa(
14         u_fp fpv,
15         int neg,
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 (neg)
110             *bp++ = '-';
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 *
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, ndec, FALSE);
139 }
140
141
142 char *
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, ndec, TRUE);
159 }