|
|
1.1 ! root 1: /* @(#)ecvt.c 2.7 */ ! 2: /* 3.0 SID # 1.2 */ ! 3: /*LINTLIBRARY*/ ! 4: /* ! 5: * ecvt converts to decimal ! 6: * the number of digits is specified by ndigit ! 7: * decpt is set to the position of the decimal point ! 8: * sign is set to 0 for positive, 1 for negative ! 9: * ! 10: */ ! 11: #include <nan.h> ! 12: #include <values.h> ! 13: #define NMAX ((DSIGNIF * 3 + 19)/10) /* restrict max precision */ ! 14: #define NDIG 80 ! 15: ! 16: extern char *cvt(); ! 17: ! 18: char * ! 19: ecvt(value, ndigit, decpt, sign) ! 20: double value; ! 21: int ndigit, *decpt, *sign; ! 22: { ! 23: return (cvt(value, ndigit, decpt, sign, 0)); ! 24: } ! 25: ! 26: char * ! 27: fcvt(value, ndigit, decpt, sign) ! 28: double value; ! 29: int ndigit, *decpt, *sign; ! 30: { ! 31: return (cvt(value, ndigit, decpt, sign, 1)); ! 32: } ! 33: ! 34: static char buf[NDIG]; ! 35: ! 36: static char * ! 37: cvt(value, ndigit, decpt, sign, f_flag) ! 38: double value; ! 39: int ndigit, *sign, f_flag; ! 40: register int *decpt; ! 41: { ! 42: register char *p = &buf[0], *p_last = &buf[ndigit]; ! 43: ! 44: KILLNaN(value); /* raise exception on Not-a-Number (3b only) */ ! 45: if (*sign = (value < 0.0)) ! 46: value = -value; ! 47: buf[0] = '\0'; ! 48: *decpt = 0; ! 49: if (value != 0.0) { /* rescale to range [1.0, 10.0) */ ! 50: /* in binary for speed and to minimize error build-up */ ! 51: /* even for the IEEE standard with its high exponents, ! 52: it's probably better for speed to just loop on them */ ! 53: static struct s { double p10; int n; } s[] = { ! 54: 1e32, 32, ! 55: 1e16, 16, ! 56: 1e8, 8, ! 57: 1e4, 4, ! 58: 1e2, 2, ! 59: 1e1, 1, ! 60: }; ! 61: register struct s *sp = s; ! 62: ! 63: ++*decpt; ! 64: if (value >= 2.0 * MAXPOWTWO) /* can't be precisely integral */ ! 65: do { ! 66: for ( ; value >= sp->p10; *decpt += sp->n) ! 67: value /= sp->p10; ! 68: } while (sp++->n > 1); ! 69: else if (value >= 10.0) { /* convert integer part separately */ ! 70: register double pow10 = 10.0, powtemp; ! 71: ! 72: while ((powtemp = 10.0 * pow10) <= value) ! 73: pow10 = powtemp; ! 74: for ( ; ; pow10 /= 10.0) { ! 75: register int digit = value/pow10; ! 76: *p++ = digit + '0'; ! 77: value -= digit * pow10; ! 78: ++*decpt; ! 79: if (pow10 <= 10.0) ! 80: break; ! 81: } ! 82: } else if (value < 1.0) ! 83: do { ! 84: for ( ; value * sp->p10 < 10.0; *decpt -= sp->n) ! 85: value *= sp->p10; ! 86: } while (sp++->n > 1); ! 87: } ! 88: if (f_flag) ! 89: p_last += *decpt; ! 90: if (p_last >= buf) { ! 91: if (p_last > &buf[NDIG - 2]) ! 92: p_last = &buf[NDIG - 2]; ! 93: for ( ; ; ++p) { ! 94: if (value == 0 || p >= &buf[NMAX]) ! 95: *p = '0'; ! 96: else { ! 97: register int intx; /* intx in [0, 9] */ ! 98: *p = (intx = (int)value) + '0'; ! 99: value = 10.0 * (value - (double)intx); ! 100: } ! 101: if (p >= p_last) { ! 102: p = p_last; ! 103: break; ! 104: } ! 105: } ! 106: if (*p >= '5') /* check rounding in last place + 1 */ ! 107: do { ! 108: if (p == buf) { /* rollover from 99999... */ ! 109: buf[0] = '1'; /* later digits are 0 */ ! 110: ++*decpt; ! 111: if (f_flag) ! 112: ++p_last; ! 113: break; ! 114: } ! 115: *p-- = '0'; ! 116: } while (++*p > '9'); /* propagate carries left */ ! 117: *p_last = '\0'; ! 118: } ! 119: return (buf); ! 120: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.