Ignore:
Timestamp:
Apr 4, 2006, 2:03:26 AM (19 years ago)
Author:
mjs
Message:

Reviewed by Darin.


  • kjs/number_object.cpp: (intPow10): Compute integer powers of 10 using exponentiation by squaring. (NumberProtoFunc::callAsFunction): Use intPow10(n) in place of all pow(10.0, n), plus a bit of refactoring.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/number_object.cpp

    r13015 r13676  
    117117}
    118118
     119static double intPow10(int e)
     120{
     121  // This function uses the "exponentiation by squaring" algorithm and
     122  // long double to quickly and precisely calculate integer powers of 10.0.
     123
     124  // This is a handy workaround for <rdar://problem/4494756>
     125
     126  if (e == 0)
     127    return 1.0;
     128
     129  bool negative = e < 0;
     130  unsigned exp = negative ? -e : e;
     131
     132  long double result = 10.0;
     133  bool foundOne = false;
     134  for (int bit = 31; bit >= 0; bit--) {
     135    if (!foundOne) {
     136      if ((exp >> bit) & 1)
     137        foundOne = true;
     138    } else {
     139      result = result * result;
     140      if ((exp >> bit) & 1)
     141        result = result * 10.0;
     142    }
     143  }
     144
     145  if (negative)
     146    return 1.0 / result;
     147  else
     148    return result;
     149}
     150
    119151// ECMA 15.7.4.2 - 15.7.4.7
    120152JSValue *NumberProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
     
    239271          double logx = floor(log10(x));
    240272          x /= pow(10.0, logx);
    241           double fx = floor(x * pow(10.0, f)) / pow(10.0,f);
     273          double fx = floor(x * pow(10.0, f)) / pow(10.0, f);
    242274          double cx = ceil(x * pow(10.0, f)) / pow(10.0, f);
    243275         
     
    334366     
    335367      if (x != 0) {
    336           e = static_cast<int>(log10(x));
    337           double n = floor(x / pow(10.0, e - p + 1));
    338           if (n < pow(10.0, p - 1)) {
     368          e = static_cast<int>(trunc(log10(x)));
     369          double tens = intPow10(e - p + 1);
     370          double n = floor(x / tens);
     371          if (n < intPow10(p - 1)) {
    339372              e = e - 1;
    340               n = floor(x / pow(10.0, e - p + 1));
    341           }
    342          
    343           if (fabs((n + 1) * pow(10.0, e - p + 1) - x) < fabs(n * pow(10.0, e - p + 1) - x))
    344               n++;
    345           assert(pow(10.0, p - 1) <= n);
    346           assert(n < pow(10.0, p));
     373              tens = intPow10(e - p + 1);
     374              n = floor(x / tens);
     375          }
     376         
     377          if (fabs((n + 1.0) * tens - x) <= fabs(n * tens - x))
     378            ++n;
     379          assert(intPow10(p - 1) <= n);
     380          assert(n < intPow10(p));
    347381         
    348382          m = integer_part_noexp(n);
Note: See TracChangeset for help on using the changeset viewer.