dofptoa.c revision 54359
154359Sroberto/* 254359Sroberto * dofptoa - do the grunge work to convert an fp number to ascii 354359Sroberto */ 454359Sroberto#include <stdio.h> 554359Sroberto 654359Sroberto#include "ntp_fp.h" 754359Sroberto#include "lib_strbuf.h" 854359Sroberto#include "ntp_string.h" 954359Sroberto#include "ntp_stdlib.h" 1054359Sroberto 1154359Srobertochar * 1254359Srobertodofptoa( 1354359Sroberto u_fp fpv, 1454359Sroberto int neg, 1554359Sroberto int ndec, 1654359Sroberto int msec 1754359Sroberto ) 1854359Sroberto{ 1954359Sroberto register u_char *cp, *cpend; 2054359Sroberto register u_long val; 2154359Sroberto register short dec; 2254359Sroberto u_char cbuf[12]; 2354359Sroberto u_char *cpdec; 2454359Sroberto char *buf; 2554359Sroberto char *bp; 2654359Sroberto 2754359Sroberto /* 2854359Sroberto * Get a string buffer before starting 2954359Sroberto */ 3054359Sroberto LIB_GETBUF(buf); 3154359Sroberto 3254359Sroberto /* 3354359Sroberto * Zero out the buffer 3454359Sroberto */ 3554359Sroberto memset((char *)cbuf, 0, sizeof cbuf); 3654359Sroberto 3754359Sroberto /* 3854359Sroberto * Set the pointers to point at the first 3954359Sroberto * decimal place. Get a local copy of the value. 4054359Sroberto */ 4154359Sroberto cp = cpend = &cbuf[5]; 4254359Sroberto val = fpv; 4354359Sroberto 4454359Sroberto /* 4554359Sroberto * If we have to, decode the integral part 4654359Sroberto */ 4754359Sroberto if (!(val & 0xffff0000)) 4854359Sroberto cp--; 4954359Sroberto else { 5054359Sroberto register u_short sv = (u_short)(val >> 16); 5154359Sroberto register u_short tmp; 5254359Sroberto register u_short ten = 10; 5354359Sroberto 5454359Sroberto do { 5554359Sroberto tmp = sv; 5654359Sroberto sv /= ten; 5754359Sroberto *(--cp) = tmp - ((sv<<3) + (sv<<1)); 5854359Sroberto } while (sv != 0); 5954359Sroberto } 6054359Sroberto 6154359Sroberto /* 6254359Sroberto * Figure out how much of the fraction to do 6354359Sroberto */ 6454359Sroberto if (msec) { 6554359Sroberto dec = ndec + 3; 6654359Sroberto if (dec < 3) 6754359Sroberto dec = 3; 6854359Sroberto cpdec = &cbuf[8]; 6954359Sroberto } else { 7054359Sroberto dec = ndec; 7154359Sroberto cpdec = cpend; 7254359Sroberto } 7354359Sroberto 7454359Sroberto if (dec > 6) 7554359Sroberto dec = 6; 7654359Sroberto 7754359Sroberto if (dec > 0) { 7854359Sroberto do { 7954359Sroberto val &= 0xffff; 8054359Sroberto val = (val << 3) + (val << 1); 8154359Sroberto *cpend++ = (u_char)(val >> 16); 8254359Sroberto } while (--dec > 0); 8354359Sroberto } 8454359Sroberto 8554359Sroberto if (val & 0x8000) { 8654359Sroberto register u_char *tp; 8754359Sroberto /* 8854359Sroberto * Round it. Ick. 8954359Sroberto */ 9054359Sroberto tp = cpend; 9154359Sroberto *(--tp) += 1; 9254359Sroberto while (*tp >= 10) { 9354359Sroberto *tp = 0; 9454359Sroberto *(--tp) += 1; 9554359Sroberto } 9654359Sroberto } 9754359Sroberto 9854359Sroberto /* 9954359Sroberto * Remove leading zeroes if necessary 10054359Sroberto */ 10154359Sroberto while (cp < (cpdec -1) && *cp == 0) 10254359Sroberto cp++; 10354359Sroberto 10454359Sroberto /* 10554359Sroberto * Copy it into the buffer, asciizing as we go. 10654359Sroberto */ 10754359Sroberto bp = buf; 10854359Sroberto if (neg) 10954359Sroberto *bp++ = '-'; 11054359Sroberto 11154359Sroberto while (cp < cpend) { 11254359Sroberto if (cp == cpdec) 11354359Sroberto *bp++ = '.'; 11454359Sroberto *bp++ = (char)(*cp++ + '0'); 11554359Sroberto } 11654359Sroberto *bp = '\0'; 11754359Sroberto return buf; 11854359Sroberto} 119