Revision: 19701
Author:   [email protected]
Date:     Fri Mar  7 08:42:10 2014 UTC
Log: Harmony: move implementation of Math.log1p and Math.expm1 to Javascript.

[email protected]

Review URL: https://codereview.chromium.org/179533003
http://code.google.com/p/v8/source/detail?r=19701

Modified:
 /branches/bleeding_edge/src/harmony-math.js
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h

=======================================
--- /branches/bleeding_edge/src/harmony-math.js Wed Feb 19 13:49:59 2014 UTC
+++ /branches/bleeding_edge/src/harmony-math.js Fri Mar  7 08:42:10 2014 UTC
@@ -174,21 +174,51 @@
 }


-//ES6 draft 09-27-13, section 20.2.2.9.
+// ES6 draft 09-27-13, section 20.2.2.9.
 function MathCbrt(x) {
   return %Math_cbrt(TO_NUMBER_INLINE(x));
 }


-//ES6 draft 09-27-13, section 20.2.2.14.
+// ES6 draft 09-27-13, section 20.2.2.14.
+// Use Taylor series to approximate.
+// exp(x) - 1 at 0 == -1 + exp(0) + exp'(0)*x/1! + exp''(0)*x^2/2! + ...
+//                 == x/1! + x^2/2! + x^3/3! + ...
+// The closer x is to 0, the fewer terms are required.
 function MathExpm1(x) {
-  return %Math_expm1(TO_NUMBER_INLINE(x));
+  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
+  var xabs = MathAbs(x);
+  if (xabs < 2E-7) {
+    return x * (1 + x * (1/2));
+  } else if (xabs < 6E-5) {
+    return x * (1 + x * (1/2 + x * (1/6)));
+  } else if (xabs < 2E-2) {
+    return x * (1 + x * (1/2 + x * (1/6 +
+           x * (1/24 + x * (1/120 + x * (1/720))))));
+  } else {  // Use regular exp if not close enough to 0.
+    return MathExp(x) - 1;
+  }
 }


-//ES6 draft 09-27-13, section 20.2.2.20.
+// ES6 draft 09-27-13, section 20.2.2.20.
+// Use Taylor series to approximate. With y = x + 1;
+// log(y) at 1 == log(1) + log'(1)(y-1)/1! + log''(1)(y-1)^2/2! + ...
+//             == 0 + x - x^2/2 + x^3/3 ...
+// The closer x is to 0, the fewer terms are required.
 function MathLog1p(x) {
-  return %Math_log1p(TO_NUMBER_INLINE(x));
+  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
+  var xabs = MathAbs(x);
+  if (xabs < 1E-7) {
+    return x * (1 - x * (1/2));
+  } else if (xabs < 3E-5) {
+    return x * (1 - x * (1/2 - x * (1/3)));
+  } else if (xabs < 7E-3) {
+    return x * (1 - x * (1/2 - x * (1/3 - x * (1/4 -
+           x * (1/5 - x * (1/6 - x * (1/7)))))));
+  } else {  // Use regular log if not close enough to 0.
+    return MathLog(1 + x);
+  }
 }


=======================================
--- /branches/bleeding_edge/src/runtime.cc      Fri Mar  7 08:36:18 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Fri Mar  7 08:42:10 2014 UTC
@@ -7692,67 +7692,6 @@
   double result = (x > 0) ? CubeRoot(x) : -CubeRoot(-x);
   return isolate->heap()->AllocateHeapNumber(result);
 }
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log1p) {
-  SealHandleScope shs(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-
-  double x_abs = std::fabs(x);
-  // Use Taylor series to approximate. With y = x + 1;
-  // log(y) at 1 == log(1) + log'(1)(y-1)/1! + log''(1)(y-1)^2/2! + ...
-  //             == 0 + x - x^2/2 + x^3/3 ...
-  // The closer x is to 0, the fewer terms are required.
-  static const double threshold_2 = 1.0 / 0x00800000;
-  static const double threshold_3 = 1.0 / 0x00008000;
-  static const double threshold_7 = 1.0 / 0x00000080;
-
-  double result;
-  if (x_abs < threshold_2) {
-    result = x * (1.0/1.0 - x * 1.0/2.0);
-  } else if (x_abs < threshold_3) {
-    result = x * (1.0/1.0 - x * (1.0/2.0 - x * (1.0/3.0)));
-  } else if (x_abs < threshold_7) {
-    result = x * (1.0/1.0 - x * (1.0/2.0 - x * (
-                  1.0/3.0 - x * (1.0/4.0 - x * (
-                  1.0/5.0 - x * (1.0/6.0 - x * (
-                  1.0/7.0)))))));
-  } else {  // Use regular log if not close enough to 0.
-    result = std::log(1.0 + x);
-  }
-  return isolate->heap()->AllocateHeapNumber(result);
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_expm1) {
-  SealHandleScope shs(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-
-  double x_abs = std::fabs(x);
-  // Use Taylor series to approximate.
-  // exp(x) - 1 at 0 == -1 + exp(0) + exp'(0)*x/1! + exp''(0)*x^2/2! + ...
-  //                 == x/1! + x^2/2! + x^3/3! + ...
-  // The closer x is to 0, the fewer terms are required.
-  static const double threshold_2 = 1.0 / 0x00400000;
-  static const double threshold_3 = 1.0 / 0x00004000;
-  static const double threshold_6 = 1.0 / 0x00000040;
-
-  double result;
-  if (x_abs < threshold_2) {
-    result = x * (1.0/1.0 + x * (1.0/2.0));
-  } else if (x_abs < threshold_3) {
-    result = x * (1.0/1.0 + x * (1.0/2.0 + x * (1.0/6.0)));
-  } else if (x_abs < threshold_6) {
-    result = x * (1.0/1.0 + x * (1.0/2.0 + x * (
-                  1.0/6.0 + x * (1.0/24.0 + x * (
-                  1.0/120.0 + x * (1.0/720.0))))));
-  } else {  // Use regular exp if not close enough to 0.
-    result = std::exp(x) - 1.0;
-  }
-  return isolate->heap()->AllocateHeapNumber(result);
-}


 static const double kPiDividedBy4 = 0.78539816339744830962;
=======================================
--- /branches/bleeding_edge/src/runtime.h       Tue Mar  4 12:43:05 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h       Fri Mar  7 08:42:10 2014 UTC
@@ -179,8 +179,6 @@
   F(Math_atan, 1, 1) \
   F(Math_log, 1, 1) \
   F(Math_cbrt, 1, 1) \
-  F(Math_log1p, 1, 1) \
-  F(Math_expm1, 1, 1) \
   F(Math_sqrt, 1, 1) \
   F(Math_exp, 1, 1) \
   F(Math_floor, 1, 1) \

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to