1c0b746e5SOllivier Robert /* 2c0b746e5SOllivier Robert * dofptoa - do the grunge work to convert an fp number to ascii 3c0b746e5SOllivier Robert */ 42b15cb3dSCy Schubert #include <config.h> 5c0b746e5SOllivier Robert #include <stdio.h> 6c0b746e5SOllivier Robert 7c0b746e5SOllivier Robert #include "ntp_fp.h" 8c0b746e5SOllivier Robert #include "lib_strbuf.h" 9c0b746e5SOllivier Robert #include "ntp_string.h" 10c0b746e5SOllivier Robert #include "ntp_stdlib.h" 11c0b746e5SOllivier Robert 12c0b746e5SOllivier Robert char * 13c0b746e5SOllivier Robert dofptoa( 14c0b746e5SOllivier Robert u_fp fpv, 15*2d4e511cSCy Schubert char sign, 169c2daa00SOllivier Robert short ndec, 17c0b746e5SOllivier Robert int msec 18c0b746e5SOllivier Robert ) 19c0b746e5SOllivier Robert { 20c0b746e5SOllivier Robert register u_char *cp, *cpend; 21c0b746e5SOllivier Robert register u_long val; 22c0b746e5SOllivier Robert register short dec; 23c0b746e5SOllivier Robert u_char cbuf[12]; 24c0b746e5SOllivier Robert u_char *cpdec; 25c0b746e5SOllivier Robert char *buf; 26c0b746e5SOllivier Robert char *bp; 27c0b746e5SOllivier Robert 28c0b746e5SOllivier Robert /* 29c0b746e5SOllivier Robert * Get a string buffer before starting 30c0b746e5SOllivier Robert */ 31c0b746e5SOllivier Robert LIB_GETBUF(buf); 32c0b746e5SOllivier Robert 33c0b746e5SOllivier Robert /* 34c0b746e5SOllivier Robert * Zero out the buffer 35c0b746e5SOllivier Robert */ 362b15cb3dSCy Schubert ZERO(cbuf); 37c0b746e5SOllivier Robert 38c0b746e5SOllivier Robert /* 39c0b746e5SOllivier Robert * Set the pointers to point at the first 40c0b746e5SOllivier Robert * decimal place. Get a local copy of the value. 41c0b746e5SOllivier Robert */ 42c0b746e5SOllivier Robert cp = cpend = &cbuf[5]; 43c0b746e5SOllivier Robert val = fpv; 44c0b746e5SOllivier Robert 45c0b746e5SOllivier Robert /* 46c0b746e5SOllivier Robert * If we have to, decode the integral part 47c0b746e5SOllivier Robert */ 48c0b746e5SOllivier Robert if (!(val & 0xffff0000)) 49c0b746e5SOllivier Robert cp--; 50c0b746e5SOllivier Robert else { 51c0b746e5SOllivier Robert register u_short sv = (u_short)(val >> 16); 52c0b746e5SOllivier Robert register u_short tmp; 53c0b746e5SOllivier Robert register u_short ten = 10; 54c0b746e5SOllivier Robert 55c0b746e5SOllivier Robert do { 56c0b746e5SOllivier Robert tmp = sv; 579c2daa00SOllivier Robert sv = (u_short) (sv/ten); 589c2daa00SOllivier Robert *(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1))); 59c0b746e5SOllivier Robert } while (sv != 0); 60c0b746e5SOllivier Robert } 61c0b746e5SOllivier Robert 62c0b746e5SOllivier Robert /* 63c0b746e5SOllivier Robert * Figure out how much of the fraction to do 64c0b746e5SOllivier Robert */ 65c0b746e5SOllivier Robert if (msec) { 669c2daa00SOllivier Robert dec = (short)(ndec + 3); 67c0b746e5SOllivier Robert if (dec < 3) 68c0b746e5SOllivier Robert dec = 3; 69c0b746e5SOllivier Robert cpdec = &cbuf[8]; 70c0b746e5SOllivier Robert } else { 71c0b746e5SOllivier Robert dec = ndec; 72c0b746e5SOllivier Robert cpdec = cpend; 73c0b746e5SOllivier Robert } 74c0b746e5SOllivier Robert 75c0b746e5SOllivier Robert if (dec > 6) 76c0b746e5SOllivier Robert dec = 6; 77c0b746e5SOllivier Robert 78c0b746e5SOllivier Robert if (dec > 0) { 79c0b746e5SOllivier Robert do { 80c0b746e5SOllivier Robert val &= 0xffff; 81c0b746e5SOllivier Robert val = (val << 3) + (val << 1); 82c0b746e5SOllivier Robert *cpend++ = (u_char)(val >> 16); 83c0b746e5SOllivier Robert } while (--dec > 0); 84c0b746e5SOllivier Robert } 85c0b746e5SOllivier Robert 86c0b746e5SOllivier Robert if (val & 0x8000) { 87c0b746e5SOllivier Robert register u_char *tp; 88c0b746e5SOllivier Robert /* 89c0b746e5SOllivier Robert * Round it. Ick. 90c0b746e5SOllivier Robert */ 91c0b746e5SOllivier Robert tp = cpend; 92c0b746e5SOllivier Robert *(--tp) += 1; 93c0b746e5SOllivier Robert while (*tp >= 10) { 94c0b746e5SOllivier Robert *tp = 0; 95c0b746e5SOllivier Robert *(--tp) += 1; 96c0b746e5SOllivier Robert } 97c0b746e5SOllivier Robert } 98c0b746e5SOllivier Robert 99c0b746e5SOllivier Robert /* 100c0b746e5SOllivier Robert * Remove leading zeroes if necessary 101c0b746e5SOllivier Robert */ 102c0b746e5SOllivier Robert while (cp < (cpdec -1) && *cp == 0) 103c0b746e5SOllivier Robert cp++; 104c0b746e5SOllivier Robert 105c0b746e5SOllivier Robert /* 106c0b746e5SOllivier Robert * Copy it into the buffer, asciizing as we go. 107c0b746e5SOllivier Robert */ 108c0b746e5SOllivier Robert bp = buf; 109*2d4e511cSCy Schubert if (sign) 110*2d4e511cSCy Schubert *bp++ = sign; 111c0b746e5SOllivier Robert 112c0b746e5SOllivier Robert while (cp < cpend) { 113c0b746e5SOllivier Robert if (cp == cpdec) 114c0b746e5SOllivier Robert *bp++ = '.'; 115c0b746e5SOllivier Robert *bp++ = (char)(*cp++ + '0'); 116c0b746e5SOllivier Robert } 117c0b746e5SOllivier Robert *bp = '\0'; 118c0b746e5SOllivier Robert return buf; 119c0b746e5SOllivier Robert } 1202b15cb3dSCy Schubert 1212b15cb3dSCy Schubert 1222b15cb3dSCy Schubert char * 1232b15cb3dSCy Schubert fptoa( 1242b15cb3dSCy Schubert s_fp fpv, 1252b15cb3dSCy Schubert short ndec 1262b15cb3dSCy Schubert ) 1272b15cb3dSCy Schubert { 1282b15cb3dSCy Schubert u_fp plusfp; 1292b15cb3dSCy Schubert int neg; 1302b15cb3dSCy Schubert 1312b15cb3dSCy Schubert neg = (fpv < 0); 1322b15cb3dSCy Schubert if (neg) { 1332b15cb3dSCy Schubert plusfp = (u_fp)(-fpv); 1342b15cb3dSCy Schubert } else { 1352b15cb3dSCy Schubert plusfp = (u_fp)fpv; 1362b15cb3dSCy Schubert } 1372b15cb3dSCy Schubert 138*2d4e511cSCy Schubert return dofptoa(plusfp, (neg?'-':0), ndec, FALSE); 1392b15cb3dSCy Schubert } 1402b15cb3dSCy Schubert 1412b15cb3dSCy Schubert 1422b15cb3dSCy Schubert char * 1432b15cb3dSCy Schubert fptoms( 1442b15cb3dSCy Schubert s_fp fpv, 1452b15cb3dSCy Schubert short ndec 1462b15cb3dSCy Schubert ) 1472b15cb3dSCy Schubert { 1482b15cb3dSCy Schubert u_fp plusfp; 1492b15cb3dSCy Schubert int neg; 1502b15cb3dSCy Schubert 1512b15cb3dSCy Schubert neg = (fpv < 0); 1522b15cb3dSCy Schubert if (neg) { 1532b15cb3dSCy Schubert plusfp = (u_fp)(-fpv); 1542b15cb3dSCy Schubert } else { 1552b15cb3dSCy Schubert plusfp = (u_fp)fpv; 1562b15cb3dSCy Schubert } 1572b15cb3dSCy Schubert 158*2d4e511cSCy Schubert return dofptoa(plusfp, (neg?'-':0), ndec, TRUE); 1592b15cb3dSCy Schubert } 160