154359Sroberto/* 254359Sroberto * dofptoa - do the grunge work to convert an fp number to ascii 354359Sroberto */ 4290001Sglebius#include <config.h> 554359Sroberto#include <stdio.h> 654359Sroberto 754359Sroberto#include "ntp_fp.h" 854359Sroberto#include "lib_strbuf.h" 954359Sroberto#include "ntp_string.h" 1054359Sroberto#include "ntp_stdlib.h" 1154359Sroberto 1254359Srobertochar * 1354359Srobertodofptoa( 1454359Sroberto u_fp fpv, 1554359Sroberto int neg, 16132451Sroberto short ndec, 1754359Sroberto int msec 1854359Sroberto ) 1954359Sroberto{ 2054359Sroberto register u_char *cp, *cpend; 2154359Sroberto register u_long val; 2254359Sroberto register short dec; 2354359Sroberto u_char cbuf[12]; 2454359Sroberto u_char *cpdec; 2554359Sroberto char *buf; 2654359Sroberto char *bp; 2754359Sroberto 2854359Sroberto /* 2954359Sroberto * Get a string buffer before starting 3054359Sroberto */ 3154359Sroberto LIB_GETBUF(buf); 3254359Sroberto 3354359Sroberto /* 3454359Sroberto * Zero out the buffer 3554359Sroberto */ 36290001Sglebius ZERO(cbuf); 3754359Sroberto 3854359Sroberto /* 3954359Sroberto * Set the pointers to point at the first 4054359Sroberto * decimal place. Get a local copy of the value. 4154359Sroberto */ 4254359Sroberto cp = cpend = &cbuf[5]; 4354359Sroberto val = fpv; 4454359Sroberto 4554359Sroberto /* 4654359Sroberto * If we have to, decode the integral part 4754359Sroberto */ 4854359Sroberto if (!(val & 0xffff0000)) 4954359Sroberto cp--; 5054359Sroberto else { 5154359Sroberto register u_short sv = (u_short)(val >> 16); 5254359Sroberto register u_short tmp; 5354359Sroberto register u_short ten = 10; 5454359Sroberto 5554359Sroberto do { 5654359Sroberto tmp = sv; 57132451Sroberto sv = (u_short) (sv/ten); 58132451Sroberto *(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1))); 5954359Sroberto } while (sv != 0); 6054359Sroberto } 6154359Sroberto 6254359Sroberto /* 6354359Sroberto * Figure out how much of the fraction to do 6454359Sroberto */ 6554359Sroberto if (msec) { 66132451Sroberto dec = (short)(ndec + 3); 6754359Sroberto if (dec < 3) 6854359Sroberto dec = 3; 6954359Sroberto cpdec = &cbuf[8]; 7054359Sroberto } else { 7154359Sroberto dec = ndec; 7254359Sroberto cpdec = cpend; 7354359Sroberto } 7454359Sroberto 7554359Sroberto if (dec > 6) 7654359Sroberto dec = 6; 7754359Sroberto 7854359Sroberto if (dec > 0) { 7954359Sroberto do { 8054359Sroberto val &= 0xffff; 8154359Sroberto val = (val << 3) + (val << 1); 8254359Sroberto *cpend++ = (u_char)(val >> 16); 8354359Sroberto } while (--dec > 0); 8454359Sroberto } 8554359Sroberto 8654359Sroberto if (val & 0x8000) { 8754359Sroberto register u_char *tp; 8854359Sroberto /* 8954359Sroberto * Round it. Ick. 9054359Sroberto */ 9154359Sroberto tp = cpend; 9254359Sroberto *(--tp) += 1; 9354359Sroberto while (*tp >= 10) { 9454359Sroberto *tp = 0; 9554359Sroberto *(--tp) += 1; 9654359Sroberto } 9754359Sroberto } 9854359Sroberto 9954359Sroberto /* 10054359Sroberto * Remove leading zeroes if necessary 10154359Sroberto */ 10254359Sroberto while (cp < (cpdec -1) && *cp == 0) 10354359Sroberto cp++; 10454359Sroberto 10554359Sroberto /* 10654359Sroberto * Copy it into the buffer, asciizing as we go. 10754359Sroberto */ 10854359Sroberto bp = buf; 10954359Sroberto if (neg) 11054359Sroberto *bp++ = '-'; 11154359Sroberto 11254359Sroberto while (cp < cpend) { 11354359Sroberto if (cp == cpdec) 11454359Sroberto *bp++ = '.'; 11554359Sroberto *bp++ = (char)(*cp++ + '0'); 11654359Sroberto } 11754359Sroberto *bp = '\0'; 11854359Sroberto return buf; 11954359Sroberto} 120290001Sglebius 121290001Sglebius 122290001Sglebiuschar * 123290001Sglebiusfptoa( 124290001Sglebius s_fp fpv, 125290001Sglebius short ndec 126290001Sglebius ) 127290001Sglebius{ 128290001Sglebius u_fp plusfp; 129290001Sglebius int neg; 130290001Sglebius 131290001Sglebius neg = (fpv < 0); 132290001Sglebius if (neg) { 133290001Sglebius plusfp = (u_fp)(-fpv); 134290001Sglebius } else { 135290001Sglebius plusfp = (u_fp)fpv; 136290001Sglebius } 137290001Sglebius 138290001Sglebius return dofptoa(plusfp, neg, ndec, FALSE); 139290001Sglebius} 140290001Sglebius 141290001Sglebius 142290001Sglebiuschar * 143290001Sglebiusfptoms( 144290001Sglebius s_fp fpv, 145290001Sglebius short ndec 146290001Sglebius ) 147290001Sglebius{ 148290001Sglebius u_fp plusfp; 149290001Sglebius int neg; 150290001Sglebius 151290001Sglebius neg = (fpv < 0); 152290001Sglebius if (neg) { 153290001Sglebius plusfp = (u_fp)(-fpv); 154290001Sglebius } else { 155290001Sglebius plusfp = (u_fp)fpv; 156290001Sglebius } 157290001Sglebius 158290001Sglebius return dofptoa(plusfp, neg, ndec, TRUE); 159290001Sglebius} 160