diff options
Diffstat (limited to 'libntp/dofptoa.c')
-rw-r--r-- | libntp/dofptoa.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/libntp/dofptoa.c b/libntp/dofptoa.c new file mode 100644 index 0000000..0f96909 --- /dev/null +++ b/libntp/dofptoa.c @@ -0,0 +1,118 @@ +/* + * dofptoa - do the grunge work to convert an fp number to ascii + */ +#include <stdio.h> + +#include "ntp_fp.h" +#include "lib_strbuf.h" +#include "ntp_string.h" +#include "ntp_stdlib.h" + +char * +dofptoa( + u_fp fpv, + int neg, + short ndec, + int msec + ) +{ + register u_char *cp, *cpend; + register u_long val; + register short dec; + u_char cbuf[12]; + u_char *cpdec; + char *buf; + char *bp; + + /* + * Get a string buffer before starting + */ + LIB_GETBUF(buf); + + /* + * Zero out the buffer + */ + memset((char *)cbuf, 0, sizeof cbuf); + + /* + * Set the pointers to point at the first + * decimal place. Get a local copy of the value. + */ + cp = cpend = &cbuf[5]; + val = fpv; + + /* + * If we have to, decode the integral part + */ + if (!(val & 0xffff0000)) + cp--; + else { + register u_short sv = (u_short)(val >> 16); + register u_short tmp; + register u_short ten = 10; + + do { + tmp = sv; + sv = (u_short) (sv/ten); + *(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1))); + } while (sv != 0); + } + + /* + * Figure out how much of the fraction to do + */ + if (msec) { + dec = (short)(ndec + 3); + if (dec < 3) + dec = 3; + cpdec = &cbuf[8]; + } else { + dec = ndec; + cpdec = cpend; + } + + if (dec > 6) + dec = 6; + + if (dec > 0) { + do { + val &= 0xffff; + val = (val << 3) + (val << 1); + *cpend++ = (u_char)(val >> 16); + } while (--dec > 0); + } + + if (val & 0x8000) { + register u_char *tp; + /* + * Round it. Ick. + */ + tp = cpend; + *(--tp) += 1; + while (*tp >= 10) { + *tp = 0; + *(--tp) += 1; + } + } + + /* + * Remove leading zeroes if necessary + */ + while (cp < (cpdec -1) && *cp == 0) + cp++; + + /* + * Copy it into the buffer, asciizing as we go. + */ + bp = buf; + if (neg) + *bp++ = '-'; + + while (cp < cpend) { + if (cp == cpdec) + *bp++ = '.'; + *bp++ = (char)(*cp++ + '0'); + } + *bp = '\0'; + return buf; +} |