llvm.org GIT mirror llvm / 686700e
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). Raw diff Collapse all Expand all
5858 /* A tight upper bound on number of parts required to hold the value
5959 pow(5, power) is
6060
61 power * 1024 / (441 * integerPartWidth) + 1
61 power * 815 / (351 * integerPartWidth) + 1
6262
6363 However, whilst the result may require only this many parts,
6464 because we are multiplying two values to get it, the
6969 const unsigned int maxExponent = 16383;
7070 const unsigned int maxPrecision = 113;
7171 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));
7474 }
7575
7676 /* Put a bunch of private, handy routines in an anonymous namespace. */
225225 dddd.dddd[eE][+-]ddd
226226
227227 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 */
230236 struct decimalInfo {
231237 const char *firstSigDigit;
232238 const char *lastSigDigit;
233239 int exponent;
240 int normalizedExponent;
234241 };
235242
236243 void
242249
243250 D->firstSigDigit = p;
244251 D->exponent = 0;
252 D->normalizedExponent = 0;
245253
246254 for (;;) {
247255 if (*p == '.') {
269277 while (*p == '0');
270278 while (*p == '.');
271279
272 /* Adjust the specified exponent for any decimal point. */
280 /* Adjust the exponents for any decimal point. */
273281 D->exponent += (dot - p) - (dot > p);
282 D->normalizedExponent = (D->exponent + (p - D->firstSigDigit)
283 - (dot > D->firstSigDigit && dot < p));
274284 }
275285
276286 D->lastSigDigit = p;
20782088 /* Scan the text. */
20792089 interpretDecimal(p, &D);
20802090
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
20812108 if (*D.firstSigDigit == '0') {
20822109 category = fcZero;
20832110 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);
20842120 } else {
20852121 integerPart *decSignificand;
20862122 unsigned int partCount;
20872123
20882124 /* 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
20902126 to hold the full significand, and an extra part required by
20912127 tcMultiplyPart. */
20922128 partCount = (D.lastSigDigit - D.firstSigDigit) + 1;
2093 partCount = partCountForBits(1 + 256 * partCount / 77);
2129 partCount = partCountForBits(1 + 196 * partCount / 59);
20942130 decSignificand = new integerPart[partCount + 1];
20952131 partCount = 0;
20962132