154359Sroberto/* 254359Sroberto * dofptoa - do the grunge work to convert an fp number to ascii 354359Sroberto */ 4280849Scy#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, 15358659Scy char sign, 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 */ 36280849Scy 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; 109358659Scy if (sign) 110358659Scy *bp++ = sign; 11154359Sroberto 11254359Sroberto while (cp < cpend) { 11354359Sroberto if (cp == cpdec) 11454359Sroberto *bp++ = '.'; 11554359Sroberto *bp++ = (char)(*cp++ + '0'); 11654359Sroberto } 11754359Sroberto *bp = '\0'; 11854359Sroberto return buf; 11954359Sroberto} 120280849Scy 121280849Scy 122280849Scychar * 123280849Scyfptoa( 124280849Scy s_fp fpv, 125280849Scy short ndec 126280849Scy ) 127280849Scy{ 128280849Scy u_fp plusfp; 129280849Scy int neg; 130280849Scy 131280849Scy neg = (fpv < 0); 132280849Scy if (neg) { 133280849Scy plusfp = (u_fp)(-fpv); 134280849Scy } else { 135280849Scy plusfp = (u_fp)fpv; 136280849Scy } 137280849Scy 138358659Scy return dofptoa(plusfp, (neg?'-':0), ndec, FALSE); 139280849Scy} 140280849Scy 141280849Scy 142280849Scychar * 143280849Scyfptoms( 144280849Scy s_fp fpv, 145280849Scy short ndec 146280849Scy ) 147280849Scy{ 148280849Scy u_fp plusfp; 149280849Scy int neg; 150280849Scy 151280849Scy neg = (fpv < 0); 152280849Scy if (neg) { 153280849Scy plusfp = (u_fp)(-fpv); 154280849Scy } else { 155280849Scy plusfp = (u_fp)fpv; 156280849Scy } 157280849Scy 158358659Scy return dofptoa(plusfp, (neg?'-':0), ndec, TRUE); 159280849Scy} 160