153913Sarchie/* 253913Sarchie * dofptoa - do the grunge work to convert an fp number to ascii 353913Sarchie */ 453913Sarchie#include <config.h> 553913Sarchie#include <stdio.h> 653913Sarchie 753913Sarchie#include "ntp_fp.h" 853913Sarchie#include "ntp_stdlib.h" 953913Sarchie 1053913Sarchiechar * 1153913Sarchiedofptoa( 1253913Sarchie u_fp fpv, 1353913Sarchie char sign, 1453913Sarchie short ndec, 1553913Sarchie int msec 1653913Sarchie ) 1753913Sarchie{ 1853913Sarchie register u_char *cp, *cpend; 1953913Sarchie register u_long val; 2053913Sarchie register short dec; 2153913Sarchie u_char cbuf[12]; 2253913Sarchie u_char *cpdec; 2353913Sarchie char *buf; 2453913Sarchie char *bp; 2553913Sarchie 2653913Sarchie /* 2753913Sarchie * Get a string buffer before starting 2853913Sarchie */ 2953913Sarchie LIB_GETBUF(buf); 3053913Sarchie 3153913Sarchie /* 3253913Sarchie * Zero out the buffer 3353913Sarchie */ 3453913Sarchie ZERO(cbuf); 3553913Sarchie 3653913Sarchie /* 3753913Sarchie * Set the pointers to point at the first 3853913Sarchie * decimal place. Get a local copy of the value. 3953913Sarchie */ 4053913Sarchie cp = cpend = &cbuf[5]; 4153913Sarchie val = fpv; 4253913Sarchie 4353913Sarchie /* 4453913Sarchie * If we have to, decode the integral part 4553913Sarchie */ 4653913Sarchie if (!(val & 0xffff0000)) 4753913Sarchie cp--; 4853913Sarchie else { 4953913Sarchie register u_short sv = (u_short)(val >> 16); 5053913Sarchie register u_short tmp; 5153913Sarchie register u_short ten = 10; 5253913Sarchie 5353913Sarchie do { 5458018Sarchie tmp = sv; 5553913Sarchie sv = (u_short) (sv/ten); 5653913Sarchie *(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1))); 5753913Sarchie } while (sv != 0); 5853913Sarchie } 5953913Sarchie 6053913Sarchie /* 6153913Sarchie * Figure out how much of the fraction to do 6253913Sarchie */ 6353913Sarchie if (msec) { 6453913Sarchie dec = (short)(ndec + 3); 6553913Sarchie if (dec < 3) 6653913Sarchie dec = 3; 6753913Sarchie cpdec = &cbuf[8]; 6853913Sarchie } else { 6953913Sarchie dec = ndec; 7053913Sarchie cpdec = cpend; 7153913Sarchie } 7253913Sarchie 7353913Sarchie if (dec > 6) 7453913Sarchie dec = 6; 7553913Sarchie 7653913Sarchie if (dec > 0) { 7753913Sarchie do { 7853913Sarchie val &= 0xffff; 7953913Sarchie val = (val << 3) + (val << 1); 8053913Sarchie *cpend++ = (u_char)(val >> 16); 8153913Sarchie } while (--dec > 0); 8253913Sarchie } 8353913Sarchie 8453913Sarchie if (val & 0x8000) { 8553913Sarchie register u_char *tp; 8653913Sarchie /* 87 * Round it. Ick. 88 */ 89 tp = cpend; 90 *(--tp) += 1; 91 while (*tp >= 10) { 92 *tp = 0; 93 *(--tp) += 1; 94 } 95 } 96 97 /* 98 * Remove leading zeroes if necessary 99 */ 100 while (cp < (cpdec -1) && *cp == 0) 101 cp++; 102 103 /* 104 * Copy it into the buffer, asciizing as we go. 105 */ 106 bp = buf; 107 if (sign) 108 *bp++ = sign; 109 110 while (cp < cpend) { 111 if (cp == cpdec) 112 *bp++ = '.'; 113 *bp++ = (char)(*cp++ + '0'); 114 } 115 *bp = '\0'; 116 return buf; 117} 118 119 120char * 121fptoa( 122 s_fp fpv, 123 short ndec 124 ) 125{ 126 u_fp plusfp; 127 int neg; 128 129 neg = (fpv < 0); 130 if (neg) { 131 plusfp = (u_fp)(-fpv); 132 } else { 133 plusfp = (u_fp)fpv; 134 } 135 136 return dofptoa(plusfp, (neg?'-':0), ndec, FALSE); 137} 138 139 140char * 141fptoms( 142 s_fp fpv, 143 short ndec 144 ) 145{ 146 u_fp plusfp; 147 int neg; 148 149 neg = (fpv < 0); 150 if (neg) { 151 plusfp = (u_fp)(-fpv); 152 } else { 153 plusfp = (u_fp)fpv; 154 } 155 156 return dofptoa(plusfp, (neg?'-':0), ndec, TRUE); 157} 158