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