llvm.org GIT mirror
Fast-track obviously over-large and over-small exponents during decimal-> integer conversion. In some such cases this makes us one or two orders of magnitude faster than NetBSD's libc. Glibc seems to have a similar fast path. Also, tighten up some upper bounds to save a bit of memory. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42984 91177308-0d34-0410-b5e6-96231b3b80d8 Neil Booth 13 years ago
1 changed file(s) with 44 addition(s) and 8 deletion(s).
 58 58 /* A tight upper bound on number of parts required to hold the value 59 59 pow(5, power) is 60 60 61 power * 1024 / (441 * integerPartWidth) + 1⏎ 61 power * 815 / (351 * integerPartWidth) + 1⏎ 62 62 63 63 However, whilst the result may require only this many parts, 64 64 because we are multiplying two values to get it, the 69 69 const unsigned int maxExponent = 16383; 70 70 const unsigned int maxPrecision = 113; 71 71 const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1; 72 const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 1024) 73 / (441 * integerPartWidth));⏎ 72 const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815)⏎ 73 / (351 * integerPartWidth)); 74 74 } 75 75 76 76 /* Put a bunch of private, handy routines in an anonymous namespace. */ 225 225 dddd.dddd[eE][+-]ddd 226 226 227 227 where the decimal point and exponent are optional, fill out the 228 structure D. If the value is zero, V->firstSigDigit 229 points to a zero, and the return exponent is zero. */⏎ 228 structure D. Exponent is appropriate if the significand is⏎ 229 treated as an integer, and normalizedExponent if the significand 230 is taken to have the decimal point after a single leading 231 non-zero digit. 232 233 If the value is zero, V->firstSigDigit points to a zero, and the 234 return exponent is zero. 235 */ 230 236 struct decimalInfo { 231 237 const char *firstSigDigit; 232 238 const char *lastSigDigit; 233 239 int exponent; 240 int normalizedExponent; 234 241 }; 235 242 236 243 void 242 249 243 250 D->firstSigDigit = p; 244 251 D->exponent = 0; 252 D->normalizedExponent = 0; 245 253 246 254 for (;;) { 247 255 if (*p == '.') { 269 277 while (*p == '0'); 270 278 while (*p == '.'); 271 279 272 /* Adjust the specified exponent for any decimal point. */⏎ 280 /* Adjust the exponents for any decimal point. */⏎ 273 281 D->exponent += (dot - p) - (dot > p); 282 D->normalizedExponent = (D->exponent + (p - D->firstSigDigit) 283 - (dot > D->firstSigDigit && dot < p)); 274 284 } 275 285 276 286 D->lastSigDigit = p; 2078 2088 /* Scan the text. */ 2079 2089 interpretDecimal(p, &D); 2080 2090 2091 /* Handle the quick cases. First the case of no significant digits, 2092 i.e. zero, and then exponents that are obviously too large or too 2093 small. Writing L for log 10 / log 2, a number d.ddddd*10^exp 2094 definitely overflows if 2095 2096 (exp - 1) * L >= maxExponent 2097 2098 and definitely underflows to zero where 2099 2100 (exp + 1) * L <= minExponent - precision 2101 2102 With integer arithmetic the tightest bounds for L are 2103 2104 93/28 < L < 196/59 [ numerator <= 256 ] 2105 42039/12655 < L < 28738/8651 [ numerator <= 65536 ] 2106 */ 2107 2081 2108 if (*D.firstSigDigit == '0') { 2082 2109 category = fcZero; 2083 2110 fs = opOK; 2111 } else if ((D.normalizedExponent + 1) * 28738 2112 <= 8651 * (semantics->minExponent - (int) semantics->precision)) { 2113 /* Underflow to zero and round. */ 2114 zeroSignificand(); 2115 fs = normalize(rounding_mode, lfLessThanHalf); 2116 } else if ((D.normalizedExponent - 1) * 42039 2117 >= 12655 * semantics->maxExponent) { 2118 /* Overflow and round. */ 2119 fs = handleOverflow(rounding_mode); 2084 2120 } else { 2085 2121 integerPart *decSignificand; 2086 2122 unsigned int partCount; 2087 2123 2088 2124 /* A tight upper bound on number of bits required to hold an 2089 N-digit decimal integer is N * 256 / 77. Allocate enough space⏎ 2125 N-digit decimal integer is N * 196 / 59. Allocate enough space⏎ 2090 2126 to hold the full significand, and an extra part required by 2091 2127 tcMultiplyPart. */ 2092 2128 partCount = (D.lastSigDigit - D.firstSigDigit) + 1; 2093 partCount = partCountForBits(1 + 256 * partCount / 77);⏎ 2129 partCount = partCountForBits(1 + 196 * partCount / 59);⏎ 2094 2130 decSignificand = new integerPart[partCount + 1]; 2095 2131 partCount = 0; 2096 2132