1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.proprietary.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)ecvt.c 8.1 (Berkeley) 06/04/93"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #if defined(hp300) && !defined(IEEE) 13 #define IEEE 1 14 #endif 15 16 /* 17 * ecvt converts to decimal 18 * the number of digits is specified by ndigit 19 * decpt is set to the position of the decimal point 20 * sign is set to 0 for positive, 1 for negative 21 */ 22 23 static char *cvt(); 24 25 #ifdef IEEE 26 #include <signal.h> 27 #define NDIG 512 28 #else 29 #define NDIG 80 30 #endif 31 32 char* 33 ecvt(arg, ndigits, decpt, sign) 34 double arg; 35 int ndigits, *decpt, *sign; 36 { 37 return(cvt(arg, ndigits, decpt, sign, 1)); 38 } 39 40 char* 41 fcvt(arg, ndigits, decpt, sign) 42 double arg; 43 int ndigits, *decpt, *sign; 44 { 45 return(cvt(arg, ndigits, decpt, sign, 0)); 46 } 47 48 static char* 49 cvt(arg, ndigits, decpt, sign, eflag) 50 double arg; 51 int ndigits, *decpt, *sign; 52 { 53 register int r2; 54 double fi, fj; 55 register char *p, *p1; 56 static char buf[NDIG]; 57 double modf(); 58 59 #ifdef IEEE 60 /* XXX */ 61 if (isspecial(arg, buf)) 62 return(buf); 63 #endif 64 if (ndigits<0) 65 ndigits = 0; 66 if (ndigits>=NDIG-1) 67 ndigits = NDIG-2; 68 r2 = 0; 69 *sign = 0; 70 p = &buf[0]; 71 if (arg<0) { 72 *sign = 1; 73 arg = -arg; 74 } 75 arg = modf(arg, &fi); 76 p1 = &buf[NDIG]; 77 /* 78 * Do integer part 79 */ 80 if (fi != 0) { 81 p1 = &buf[NDIG]; 82 while (fi != 0) { 83 fj = modf(fi/10, &fi); 84 *--p1 = (int)((fj+.03)*10) + '0'; 85 r2++; 86 } 87 while (p1 < &buf[NDIG]) 88 *p++ = *p1++; 89 } else if (arg > 0) { 90 while ((fj = arg*10) < 1) { 91 arg = fj; 92 r2--; 93 } 94 } 95 p1 = &buf[ndigits]; 96 if (eflag==0) 97 p1 += r2; 98 *decpt = r2; 99 if (p1 < &buf[0]) { 100 buf[0] = '\0'; 101 return(buf); 102 } 103 while (p<=p1 && p<&buf[NDIG]) { 104 arg *= 10; 105 arg = modf(arg, &fj); 106 *p++ = (int)fj + '0'; 107 } 108 if (p1 >= &buf[NDIG]) { 109 buf[NDIG-1] = '\0'; 110 return(buf); 111 } 112 p = p1; 113 *p1 += 5; 114 while (*p1 > '9') { 115 *p1 = '0'; 116 if (p1>buf) 117 ++*--p1; 118 else { 119 *p1 = '1'; 120 (*decpt)++; 121 if (eflag==0) { 122 if (p>buf) 123 *p = '0'; 124 p++; 125 } 126 } 127 } 128 *p = '\0'; 129 return(buf); 130 } 131 132 #ifdef IEEE 133 struct IEEEdp { 134 unsigned sign:1, 135 exp:11, 136 manh:20, 137 manl:32; 138 }; 139 140 isspecial(f, bp) 141 double f; 142 char *bp; 143 { 144 register struct IEEEdp *ip = (struct IEEEdp *) &f; 145 146 if (ip->exp != 0x7ff) 147 return(0); 148 if (ip->manh || ip->manl) 149 strcpy(bp, "NaN"); 150 else if (ip->sign) 151 strcpy(bp, "-Infinity"); 152 else 153 strcpy(bp, "Infinity"); 154 return(1); 155 } 156 #endif 157