|
|
1.1 ! root 1: /* ! 2: * strtod.c -- ! 3: * ! 4: * Source code for the "strtod" library procedure. ! 5: * ! 6: * Copyright 1988-1992 Regents of the University of California ! 7: * Permission to use, copy, modify, and distribute this ! 8: * software and its documentation for any purpose and without ! 9: * fee is hereby granted, provided that the above copyright ! 10: * notice appear in all copies. The University of California ! 11: * makes no representations about the suitability of this ! 12: * software for any purpose. It is provided "as is" without ! 13: * express or implied warranty. ! 14: */ ! 15: ! 16: #ifndef lint ! 17: static char rcsid[] = "$Header: /user6/ouster/tcl/compat/RCS/strtod.c,v 1.1 92/01/03 16:39:02 ouster Exp $ SPRITE (Berkeley)"; ! 18: #endif /* not lint */ ! 19: ! 20: #include <stdlib.h> ! 21: #include <ctype.h> ! 22: ! 23: #ifndef TRUE ! 24: #define TRUE 1 ! 25: #define FALSE 0 ! 26: #endif ! 27: #ifndef NULL ! 28: #define NULL 0 ! 29: #endif ! 30: ! 31: static int maxExponent = 511; /* Largest possible base 10 exponent. Any ! 32: * exponent larger than this will already ! 33: * produce underflow or overflow, so there's ! 34: * no need to worry about additional digits. ! 35: */ ! 36: static double powersOf10[] = { /* Table giving binary powers of 10. Entry */ ! 37: 10., /* is 10^2^i. Used to convert decimal */ ! 38: 100., /* exponents into floating-point numbers. */ ! 39: 1.0e4, ! 40: 1.0e8, ! 41: 1.0e16, ! 42: 1.0e32, ! 43: 1.0e64, ! 44: 1.0e128, ! 45: 1.0e256 ! 46: }; ! 47: ! 48: /* ! 49: *---------------------------------------------------------------------- ! 50: * ! 51: * strtod -- ! 52: * ! 53: * This procedure converts a floating-point number from an ASCII ! 54: * decimal representation to internal double-precision format. ! 55: * ! 56: * Results: ! 57: * The return value is the double-precision floating-point ! 58: * representation of the characters in string. If endPtr isn't ! 59: * NULL, then *endPtr is filled in with the address of the ! 60: * next character after the last one that was part of the ! 61: * floating-point number. ! 62: * ! 63: * Side effects: ! 64: * None. ! 65: * ! 66: *---------------------------------------------------------------------- ! 67: */ ! 68: ! 69: double ! 70: strtod(string, endPtr) ! 71: char *string; /* A decimal ASCII floating-point number, ! 72: * optionally preceded by white space. ! 73: * Must have form "-I.FE-X", where I is the ! 74: * integer part of the mantissa, F is the ! 75: * fractional part of the mantissa, and X ! 76: * is the exponent. Either of the signs ! 77: * may be "+", "-", or omitted. Either I ! 78: * or F may be omitted, or both. The decimal ! 79: * point isn't necessary unless F is present. ! 80: * The "E" may actually be an "e". E and X ! 81: * may both be omitted (but not just one). ! 82: */ ! 83: char **endPtr; /* If non-NULL, store terminating character's ! 84: * address here. */ ! 85: { ! 86: int sign, expSign = FALSE; ! 87: double fraction, dblExp, *d; ! 88: register char *p, c; ! 89: int exp = 0; /* Exponent read from "EX" field. */ ! 90: int fracExp = 0; /* Exponent that derives from the fractional ! 91: * part. Under normal circumstatnces, it is ! 92: * the negative of the number of digits in F. ! 93: * However, if I is very long, the last digits ! 94: * of I get dropped (otherwise a long I with a ! 95: * large negative exponent could cause an ! 96: * unnecessary overflow on I alone). In this ! 97: * case, fracExp is incremented one for each ! 98: * dropped digit. ! 99: */ ! 100: int mantSize; /* Number of digits in mantissa. */ ! 101: int decPt; /* Number of mantissa digits BEFORE decimal ! 102: * point. ! 103: */ ! 104: char *pExp; /* Temporarily holds location of exponent ! 105: * in string. ! 106: */ ! 107: ! 108: /* ! 109: * Strip off leading blanks and check for a sign. ! 110: */ ! 111: ! 112: p = string; ! 113: while (isspace(*p)) { ! 114: p += 1; ! 115: } ! 116: if (*p == '-') { ! 117: sign = TRUE; ! 118: p += 1; ! 119: } else { ! 120: if (*p == '+') { ! 121: p += 1; ! 122: } ! 123: sign = FALSE; ! 124: } ! 125: ! 126: /* ! 127: * Count the number of digits in the mantissa (including the decimal ! 128: * point), and also locate the decimal point. ! 129: */ ! 130: ! 131: decPt = -1; ! 132: for (mantSize = 0; ; mantSize += 1) ! 133: { ! 134: c = *p; ! 135: if (!isdigit(c)) { ! 136: if ((c != '.') || (decPt >= 0)) { ! 137: break; ! 138: } ! 139: decPt = mantSize; ! 140: } ! 141: p += 1; ! 142: } ! 143: ! 144: /* ! 145: * Now suck up the digits in the mantissa. Use two integers to ! 146: * collect 9 digits each (this is faster than using floating-point). ! 147: * If the mantissa has more than 18 digits, ignore the extras, since ! 148: * they can't affect the value anyway. ! 149: */ ! 150: ! 151: pExp = p; ! 152: p -= mantSize; ! 153: if (decPt < 0) { ! 154: decPt = mantSize; ! 155: } else { ! 156: mantSize -= 1; /* One of the digits was the point. */ ! 157: } ! 158: if (mantSize > 18) { ! 159: fracExp = decPt - 18; ! 160: mantSize = 18; ! 161: } else { ! 162: fracExp = decPt - mantSize; ! 163: } ! 164: if (mantSize == 0) { ! 165: fraction = 0.0; ! 166: p = string; ! 167: goto done; ! 168: } else { ! 169: int frac1, frac2; ! 170: frac1 = 0; ! 171: for ( ; mantSize > 9; mantSize -= 1) ! 172: { ! 173: c = *p; ! 174: p += 1; ! 175: if (c == '.') { ! 176: c = *p; ! 177: p += 1; ! 178: } ! 179: frac1 = 10*frac1 + (c - '0'); ! 180: } ! 181: frac2 = 0; ! 182: for (; mantSize > 0; mantSize -= 1) ! 183: { ! 184: c = *p; ! 185: p += 1; ! 186: if (c == '.') { ! 187: c = *p; ! 188: p += 1; ! 189: } ! 190: frac2 = 10*frac2 + (c - '0'); ! 191: } ! 192: fraction = (1.0e9 * frac1) + frac2; ! 193: } ! 194: ! 195: /* ! 196: * Skim off the exponent. ! 197: */ ! 198: ! 199: p = pExp; ! 200: if ((*p == 'E') || (*p == 'e')) { ! 201: p += 1; ! 202: if (*p == '-') { ! 203: expSign = TRUE; ! 204: p += 1; ! 205: } else { ! 206: if (*p == '+') { ! 207: p += 1; ! 208: } ! 209: expSign = FALSE; ! 210: } ! 211: while (isdigit(*p)) { ! 212: exp = exp * 10 + (*p - '0'); ! 213: p += 1; ! 214: } ! 215: } ! 216: if (expSign) { ! 217: exp = fracExp - exp; ! 218: } else { ! 219: exp = fracExp + exp; ! 220: } ! 221: ! 222: /* ! 223: * Generate a floating-point number that represents the exponent. ! 224: * Do this by processing the exponent one bit at a time to combine ! 225: * many powers of 2 of 10. Then combine the exponent with the ! 226: * fraction. ! 227: */ ! 228: ! 229: if (exp < 0) { ! 230: expSign = TRUE; ! 231: exp = -exp; ! 232: } else { ! 233: expSign = FALSE; ! 234: } ! 235: if (exp > maxExponent) { ! 236: exp = maxExponent; ! 237: } ! 238: dblExp = 1.0; ! 239: for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { ! 240: if (exp & 01) { ! 241: dblExp *= *d; ! 242: } ! 243: } ! 244: if (expSign) { ! 245: fraction /= dblExp; ! 246: } else { ! 247: fraction *= dblExp; ! 248: } ! 249: ! 250: done: ! 251: if (endPtr != NULL) { ! 252: *endPtr = p; ! 253: } ! 254: ! 255: if (sign) { ! 256: return -fraction; ! 257: } ! 258: return fraction; ! 259: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.