1*eabc0478Schristos /* $NetBSD: dofptoa.c,v 1.6 2024/08/18 20:47:13 christos Exp $ */ 2abb0f93cSkardel 3abb0f93cSkardel /* 4abb0f93cSkardel * dofptoa - do the grunge work to convert an fp number to ascii 5abb0f93cSkardel */ 68585484eSchristos #include <config.h> 7abb0f93cSkardel #include <stdio.h> 8abb0f93cSkardel 9abb0f93cSkardel #include "ntp_fp.h" 10abb0f93cSkardel #include "ntp_stdlib.h" 11abb0f93cSkardel 12abb0f93cSkardel char * 13abb0f93cSkardel dofptoa( 14abb0f93cSkardel u_fp fpv, 15cdfa2a7eSchristos char sign, 16abb0f93cSkardel short ndec, 17abb0f93cSkardel int msec 18abb0f93cSkardel ) 19abb0f93cSkardel { 20abb0f93cSkardel register u_char *cp, *cpend; 21abb0f93cSkardel register u_long val; 22abb0f93cSkardel register short dec; 23abb0f93cSkardel u_char cbuf[12]; 24abb0f93cSkardel u_char *cpdec; 25abb0f93cSkardel char *buf; 26abb0f93cSkardel char *bp; 27abb0f93cSkardel 28abb0f93cSkardel /* 29abb0f93cSkardel * Get a string buffer before starting 30abb0f93cSkardel */ 31abb0f93cSkardel LIB_GETBUF(buf); 32abb0f93cSkardel 33abb0f93cSkardel /* 34abb0f93cSkardel * Zero out the buffer 35abb0f93cSkardel */ 368585484eSchristos ZERO(cbuf); 37abb0f93cSkardel 38abb0f93cSkardel /* 39abb0f93cSkardel * Set the pointers to point at the first 40abb0f93cSkardel * decimal place. Get a local copy of the value. 41abb0f93cSkardel */ 42abb0f93cSkardel cp = cpend = &cbuf[5]; 43abb0f93cSkardel val = fpv; 44abb0f93cSkardel 45abb0f93cSkardel /* 46abb0f93cSkardel * If we have to, decode the integral part 47abb0f93cSkardel */ 48abb0f93cSkardel if (!(val & 0xffff0000)) 49abb0f93cSkardel cp--; 50abb0f93cSkardel else { 51abb0f93cSkardel register u_short sv = (u_short)(val >> 16); 52abb0f93cSkardel register u_short tmp; 53abb0f93cSkardel register u_short ten = 10; 54abb0f93cSkardel 55abb0f93cSkardel do { 56abb0f93cSkardel tmp = sv; 57abb0f93cSkardel sv = (u_short) (sv/ten); 58abb0f93cSkardel *(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1))); 59abb0f93cSkardel } while (sv != 0); 60abb0f93cSkardel } 61abb0f93cSkardel 62abb0f93cSkardel /* 63abb0f93cSkardel * Figure out how much of the fraction to do 64abb0f93cSkardel */ 65abb0f93cSkardel if (msec) { 66abb0f93cSkardel dec = (short)(ndec + 3); 67abb0f93cSkardel if (dec < 3) 68abb0f93cSkardel dec = 3; 69abb0f93cSkardel cpdec = &cbuf[8]; 70abb0f93cSkardel } else { 71abb0f93cSkardel dec = ndec; 72abb0f93cSkardel cpdec = cpend; 73abb0f93cSkardel } 74abb0f93cSkardel 75abb0f93cSkardel if (dec > 6) 76abb0f93cSkardel dec = 6; 77abb0f93cSkardel 78abb0f93cSkardel if (dec > 0) { 79abb0f93cSkardel do { 80abb0f93cSkardel val &= 0xffff; 81abb0f93cSkardel val = (val << 3) + (val << 1); 82abb0f93cSkardel *cpend++ = (u_char)(val >> 16); 83abb0f93cSkardel } while (--dec > 0); 84abb0f93cSkardel } 85abb0f93cSkardel 86abb0f93cSkardel if (val & 0x8000) { 87abb0f93cSkardel register u_char *tp; 88abb0f93cSkardel /* 89abb0f93cSkardel * Round it. Ick. 90abb0f93cSkardel */ 91abb0f93cSkardel tp = cpend; 92abb0f93cSkardel *(--tp) += 1; 93abb0f93cSkardel while (*tp >= 10) { 94abb0f93cSkardel *tp = 0; 95abb0f93cSkardel *(--tp) += 1; 96abb0f93cSkardel } 97abb0f93cSkardel } 98abb0f93cSkardel 99abb0f93cSkardel /* 100abb0f93cSkardel * Remove leading zeroes if necessary 101abb0f93cSkardel */ 102abb0f93cSkardel while (cp < (cpdec -1) && *cp == 0) 103abb0f93cSkardel cp++; 104abb0f93cSkardel 105abb0f93cSkardel /* 106abb0f93cSkardel * Copy it into the buffer, asciizing as we go. 107abb0f93cSkardel */ 108abb0f93cSkardel bp = buf; 109cdfa2a7eSchristos if (sign) 110cdfa2a7eSchristos *bp++ = sign; 111abb0f93cSkardel 112abb0f93cSkardel while (cp < cpend) { 113abb0f93cSkardel if (cp == cpdec) 114abb0f93cSkardel *bp++ = '.'; 115abb0f93cSkardel *bp++ = (char)(*cp++ + '0'); 116abb0f93cSkardel } 117abb0f93cSkardel *bp = '\0'; 118abb0f93cSkardel return buf; 119abb0f93cSkardel } 1208585484eSchristos 1218585484eSchristos 1228585484eSchristos char * 1238585484eSchristos fptoa( 1248585484eSchristos s_fp fpv, 1258585484eSchristos short ndec 1268585484eSchristos ) 1278585484eSchristos { 1288585484eSchristos u_fp plusfp; 1298585484eSchristos int neg; 1308585484eSchristos 1318585484eSchristos neg = (fpv < 0); 1328585484eSchristos if (neg) { 1338585484eSchristos plusfp = (u_fp)(-fpv); 1348585484eSchristos } else { 1358585484eSchristos plusfp = (u_fp)fpv; 1368585484eSchristos } 1378585484eSchristos 138cdfa2a7eSchristos return dofptoa(plusfp, (neg?'-':0), ndec, FALSE); 1398585484eSchristos } 1408585484eSchristos 1418585484eSchristos 1428585484eSchristos char * 1438585484eSchristos fptoms( 1448585484eSchristos s_fp fpv, 1458585484eSchristos short ndec 1468585484eSchristos ) 1478585484eSchristos { 1488585484eSchristos u_fp plusfp; 1498585484eSchristos int neg; 1508585484eSchristos 1518585484eSchristos neg = (fpv < 0); 1528585484eSchristos if (neg) { 1538585484eSchristos plusfp = (u_fp)(-fpv); 1548585484eSchristos } else { 1558585484eSchristos plusfp = (u_fp)fpv; 1568585484eSchristos } 1578585484eSchristos 158cdfa2a7eSchristos return dofptoa(plusfp, (neg?'-':0), ndec, TRUE); 1598585484eSchristos } 160