1/* $NetBSD$ */ 2 3/* 4 * dofptoa - do the grunge work to convert an fp number to ascii 5 */ 6#include <stdio.h> 7 8#include "ntp_fp.h" 9#include "lib_strbuf.h" 10#include "ntp_string.h" 11#include "ntp_stdlib.h" 12 13char * 14dofptoa( 15 u_fp fpv, 16 int neg, 17 short ndec, 18 int msec 19 ) 20{ 21 register u_char *cp, *cpend; 22 register u_long val; 23 register short dec; 24 u_char cbuf[12]; 25 u_char *cpdec; 26 char *buf; 27 char *bp; 28 29 /* 30 * Get a string buffer before starting 31 */ 32 LIB_GETBUF(buf); 33 34 /* 35 * Zero out the buffer 36 */ 37 memset((char *)cbuf, 0, sizeof cbuf); 38 39 /* 40 * Set the pointers to point at the first 41 * decimal place. Get a local copy of the value. 42 */ 43 cp = cpend = &cbuf[5]; 44 val = fpv; 45 46 /* 47 * If we have to, decode the integral part 48 */ 49 if (!(val & 0xffff0000)) 50 cp--; 51 else { 52 register u_short sv = (u_short)(val >> 16); 53 register u_short tmp; 54 register u_short ten = 10; 55 56 do { 57 tmp = sv; 58 sv = (u_short) (sv/ten); 59 *(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1))); 60 } while (sv != 0); 61 } 62 63 /* 64 * Figure out how much of the fraction to do 65 */ 66 if (msec) { 67 dec = (short)(ndec + 3); 68 if (dec < 3) 69 dec = 3; 70 cpdec = &cbuf[8]; 71 } else { 72 dec = ndec; 73 cpdec = cpend; 74 } 75 76 if (dec > 6) 77 dec = 6; 78 79 if (dec > 0) { 80 do { 81 val &= 0xffff; 82 val = (val << 3) + (val << 1); 83 *cpend++ = (u_char)(val >> 16); 84 } while (--dec > 0); 85 } 86 87 if (val & 0x8000) { 88 register u_char *tp; 89 /* 90 * Round it. Ick. 91 */ 92 tp = cpend; 93 *(--tp) += 1; 94 while (*tp >= 10) { 95 *tp = 0; 96 *(--tp) += 1; 97 } 98 } 99 100 /* 101 * Remove leading zeroes if necessary 102 */ 103 while (cp < (cpdec -1) && *cp == 0) 104 cp++; 105 106 /* 107 * Copy it into the buffer, asciizing as we go. 108 */ 109 bp = buf; 110 if (neg) 111 *bp++ = '-'; 112 113 while (cp < cpend) { 114 if (cp == cpdec) 115 *bp++ = '.'; 116 *bp++ = (char)(*cp++ + '0'); 117 } 118 *bp = '\0'; 119 return buf; 120} 121