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