2 * dolfptoa - do the grunge work of converting an l_fp number to decimal
8 #include "lib_strbuf.h"
9 #include "ntp_string.h"
10 #include "ntp_stdlib.h"
21 u_char *cp, *cpend, *cpdec;
27 * Get a string buffer before starting
32 * Zero the character buffer
37 * Work on the integral part. This should work reasonable on
38 * all machines with 32 bit arithmetic. Please note that 32 bits
39 * can *always* be represented with at most 10 decimal digits,
40 * including a possible rounding from the fractional part.
42 cp = cpend = cpdec = &cbuf[10];
43 for (dec = (int)(cp - cbuf); dec > 0 && fpi != 0; dec--) {
44 /* can add another digit */
49 digit -= (fpi << 3) + (fpi << 1); /* i*10 */
50 *--cp = (u_char)digit;
54 * Done that, now deal with the problem of the fraction. First
55 * determine the number of decimal places.
64 if ((size_t)dec > sizeof(cbuf) - (cpend - cbuf))
65 dec = (int)(sizeof(cbuf) - (cpend - cbuf));
68 * If there's a fraction to deal with, do so.
70 for (/*NOP*/; dec > 0 && fpv != 0; dec--) {
71 u_int32 digit, tmph, tmpl;
74 * The scheme here is to multiply the fraction
75 * (0.1234...) by ten. This moves a junk of BCD into
76 * the units part. record that and iterate.
77 * multiply by shift/add in two dwords.
85 M_ADD(digit, fpv, tmph, tmpl);
86 *cpend++ = (u_char)digit;
89 /* decide whether to round or simply extend by zeros */
91 /* only '0' digits left -- just reposition end */
94 /* some bits remain in 'fpv'; do round */
96 int carry = ((fpv & 0x80000000) != 0);
98 for (dec = (int)(tp - cbuf); carry && dec > 0; dec--) {
106 if (tp < cp) /* rounding from 999 to 1000 or similiar? */
111 * We've now got the fraction in cbuf[], with cp pointing at
112 * the first character, cpend pointing past the last, and
113 * cpdec pointing at the first character past the decimal.
114 * Remove leading zeros, then format the number into the
117 while (cp < cpdec && *cp == 0)
128 *bp++ = (char)(*cp++) + '0';
148 isneg = M_ISNEG(fpi);
153 return dolfptoa(fpi, fpf, isneg, ndec, FALSE);
166 isneg = M_ISNEG(fpi);
171 return dolfptoa(fpi, fpf, isneg, ndec, TRUE);