1/* $NetBSD: dofptoa.c,v 1.5 2020/05/25 20:47:24 christos Exp $ */ 2 3/* 4 * dofptoa - do the grunge work to convert an fp number to ascii 5 */ 6#include <config.h> 7#include <stdio.h> 8 9#include "ntp_fp.h" 10#include "lib_strbuf.h" 11#include "ntp_string.h" 12#include "ntp_stdlib.h" 13 14char * 15dofptoa( 16 u_fp fpv, 17 char sign, 18 short ndec, 19 int msec 20 ) 21{ 22 register u_char *cp, *cpend; 23 register u_long val; 24 register short dec; 25 u_char cbuf[12]; 26 u_char *cpdec; 27 char *buf; 28 char *bp; 29 30 /* 31 * Get a string buffer before starting 32 */ 33 LIB_GETBUF(buf); 34 35 /* 36 * Zero out the buffer 37 */ 38 ZERO(cbuf); 39 40 /* 41 * Set the pointers to point at the first 42 * decimal place. Get a local copy of the value. 43 */ 44 cp = cpend = &cbuf[5]; 45 val = fpv; 46 47 /* 48 * If we have to, decode the integral part 49 */ 50 if (!(val & 0xffff0000)) 51 cp--; 52 else { 53 register u_short sv = (u_short)(val >> 16); 54 register u_short tmp; 55 register u_short ten = 10; 56 57 do { 58 tmp = sv; 59 sv = (u_short) (sv/ten); 60 *(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1))); 61 } while (sv != 0); 62 } 63 64 /* 65 * Figure out how much of the fraction to do 66 */ 67 if (msec) { 68 dec = (short)(ndec + 3); 69 if (dec < 3) 70 dec = 3; 71 cpdec = &cbuf[8]; 72 } else { 73 dec = ndec; 74 cpdec = cpend; 75 } 76 77 if (dec > 6) 78 dec = 6; 79 80 if (dec > 0) { 81 do { 82 val &= 0xffff; 83 val = (val << 3) + (val << 1); 84 *cpend++ = (u_char)(val >> 16); 85 } while (--dec > 0); 86 } 87 88 if (val & 0x8000) { 89 register u_char *tp; 90 /* 91 * Round it. Ick. 92 */ 93 tp = cpend; 94 *(--tp) += 1; 95 while (*tp >= 10) { 96 *tp = 0; 97 *(--tp) += 1; 98 } 99 } 100 101 /* 102 * Remove leading zeroes if necessary 103 */ 104 while (cp < (cpdec -1) && *cp == 0) 105 cp++; 106 107 /* 108 * Copy it into the buffer, asciizing as we go. 109 */ 110 bp = buf; 111 if (sign) 112 *bp++ = sign; 113 114 while (cp < cpend) { 115 if (cp == cpdec) 116 *bp++ = '.'; 117 *bp++ = (char)(*cp++ + '0'); 118 } 119 *bp = '\0'; 120 return buf; 121} 122 123 124char * 125fptoa( 126 s_fp fpv, 127 short ndec 128 ) 129{ 130 u_fp plusfp; 131 int neg; 132 133 neg = (fpv < 0); 134 if (neg) { 135 plusfp = (u_fp)(-fpv); 136 } else { 137 plusfp = (u_fp)fpv; 138 } 139 140 return dofptoa(plusfp, (neg?'-':0), ndec, FALSE); 141} 142 143 144char * 145fptoms( 146 s_fp fpv, 147 short ndec 148 ) 149{ 150 u_fp plusfp; 151 int neg; 152 153 neg = (fpv < 0); 154 if (neg) { 155 plusfp = (u_fp)(-fpv); 156 } else { 157 plusfp = (u_fp)fpv; 158 } 159 160 return dofptoa(plusfp, (neg?'-':0), ndec, TRUE); 161} 162