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