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