xref: /csrg-svn/lib/libcompat/4.3/ecvt.c (revision 61241)
148399Sbostic /*-
2*61241Sbostic  * Copyright (c) 1991, 1993
3*61241Sbostic  *	The Regents of the University of California.  All rights reserved.
448399Sbostic  *
548399Sbostic  * %sccs.include.proprietary.c%
648399Sbostic  */
748399Sbostic 
826889Smckusick #if defined(LIBC_SCCS) && !defined(lint)
9*61241Sbostic static char sccsid[] = "@(#)ecvt.c	8.1 (Berkeley) 06/04/93";
1048399Sbostic #endif /* LIBC_SCCS and not lint */
1126889Smckusick 
1243615Sbostic #if defined(hp300) && !defined(IEEE)
1343615Sbostic #define	IEEE	1
1443615Sbostic #endif
1543615Sbostic 
161963Swnj /*
171963Swnj  *	ecvt converts to decimal
181963Swnj  *	the number of digits is specified by ndigit
191963Swnj  *	decpt is set to the position of the decimal point
201963Swnj  *	sign is set to 0 for positive, 1 for negative
211963Swnj  */
221963Swnj 
2354674Storek static char *cvt();
241963Swnj 
2543615Sbostic #ifdef IEEE
2643615Sbostic #include <signal.h>
2743615Sbostic #define	NDIG	512
2843615Sbostic #else
291963Swnj #define	NDIG	80
3043615Sbostic #endif
3143615Sbostic 
321963Swnj char*
ecvt(arg,ndigits,decpt,sign)331963Swnj ecvt(arg, ndigits, decpt, sign)
341963Swnj double arg;
351963Swnj int ndigits, *decpt, *sign;
361963Swnj {
371963Swnj 	return(cvt(arg, ndigits, decpt, sign, 1));
381963Swnj }
391963Swnj 
401963Swnj char*
fcvt(arg,ndigits,decpt,sign)411963Swnj fcvt(arg, ndigits, decpt, sign)
421963Swnj double arg;
431963Swnj int ndigits, *decpt, *sign;
441963Swnj {
451963Swnj 	return(cvt(arg, ndigits, decpt, sign, 0));
461963Swnj }
471963Swnj 
481963Swnj static char*
cvt(arg,ndigits,decpt,sign,eflag)491963Swnj cvt(arg, ndigits, decpt, sign, eflag)
501963Swnj double arg;
511963Swnj int ndigits, *decpt, *sign;
521963Swnj {
531963Swnj 	register int r2;
541963Swnj 	double fi, fj;
551963Swnj 	register char *p, *p1;
561963Swnj 	static char buf[NDIG];
571963Swnj 	double modf();
581963Swnj 
5943615Sbostic #ifdef IEEE
6043615Sbostic 	/* XXX */
6143615Sbostic 	if (isspecial(arg, buf))
6243615Sbostic 		return(buf);
6343615Sbostic #endif
641963Swnj 	if (ndigits<0)
651963Swnj 		ndigits = 0;
661963Swnj 	if (ndigits>=NDIG-1)
671963Swnj 		ndigits = NDIG-2;
681963Swnj 	r2 = 0;
691963Swnj 	*sign = 0;
701963Swnj 	p = &buf[0];
711963Swnj 	if (arg<0) {
721963Swnj 		*sign = 1;
731963Swnj 		arg = -arg;
741963Swnj 	}
751963Swnj 	arg = modf(arg, &fi);
761963Swnj 	p1 = &buf[NDIG];
771963Swnj 	/*
781963Swnj 	 * Do integer part
791963Swnj 	 */
801963Swnj 	if (fi != 0) {
811963Swnj 		p1 = &buf[NDIG];
821963Swnj 		while (fi != 0) {
831963Swnj 			fj = modf(fi/10, &fi);
841963Swnj 			*--p1 = (int)((fj+.03)*10) + '0';
851963Swnj 			r2++;
861963Swnj 		}
871963Swnj 		while (p1 < &buf[NDIG])
881963Swnj 			*p++ = *p1++;
891963Swnj 	} else if (arg > 0) {
901963Swnj 		while ((fj = arg*10) < 1) {
911963Swnj 			arg = fj;
921963Swnj 			r2--;
931963Swnj 		}
941963Swnj 	}
951963Swnj 	p1 = &buf[ndigits];
961963Swnj 	if (eflag==0)
971963Swnj 		p1 += r2;
981963Swnj 	*decpt = r2;
991963Swnj 	if (p1 < &buf[0]) {
1001963Swnj 		buf[0] = '\0';
1011963Swnj 		return(buf);
1021963Swnj 	}
1031963Swnj 	while (p<=p1 && p<&buf[NDIG]) {
1041963Swnj 		arg *= 10;
1051963Swnj 		arg = modf(arg, &fj);
1061963Swnj 		*p++ = (int)fj + '0';
1071963Swnj 	}
1081963Swnj 	if (p1 >= &buf[NDIG]) {
1091963Swnj 		buf[NDIG-1] = '\0';
1101963Swnj 		return(buf);
1111963Swnj 	}
1121963Swnj 	p = p1;
1131963Swnj 	*p1 += 5;
1141963Swnj 	while (*p1 > '9') {
1151963Swnj 		*p1 = '0';
1161963Swnj 		if (p1>buf)
1171963Swnj 			++*--p1;
1181963Swnj 		else {
1191963Swnj 			*p1 = '1';
1201963Swnj 			(*decpt)++;
1211963Swnj 			if (eflag==0) {
1221963Swnj 				if (p>buf)
1231963Swnj 					*p = '0';
1241963Swnj 				p++;
1251963Swnj 			}
1261963Swnj 		}
1271963Swnj 	}
1281963Swnj 	*p = '\0';
1291963Swnj 	return(buf);
1301963Swnj }
13143615Sbostic 
13243615Sbostic #ifdef IEEE
13343615Sbostic struct IEEEdp {
13443615Sbostic 	unsigned sign:1,
13543615Sbostic 		 exp:11,
13643615Sbostic 		 manh:20,
13743615Sbostic 		 manl:32;
13843615Sbostic };
13943615Sbostic 
isspecial(f,bp)14043615Sbostic isspecial(f, bp)
14143615Sbostic 	double f;
14243615Sbostic 	char *bp;
14343615Sbostic {
14443615Sbostic 	register struct IEEEdp *ip = (struct IEEEdp *) &f;
14543615Sbostic 
14643615Sbostic 	if (ip->exp != 0x7ff)
14743615Sbostic 		return(0);
14843615Sbostic 	if (ip->manh || ip->manl)
14943615Sbostic 		strcpy(bp, "NaN");
15043615Sbostic 	else if (ip->sign)
15143615Sbostic 		strcpy(bp, "-Infinity");
15243615Sbostic 	else
15343615Sbostic 		strcpy(bp, "Infinity");
15443615Sbostic 	return(1);
15543615Sbostic }
15643615Sbostic #endif
157