Revision: 23512
Author:   [email protected]
Date:     Fri Aug 29 09:32:51 2014 UTC
Log:      Port fdlibm implementation for Math.sinh.

[email protected]
BUG=v8:3493
LOG=N

Review URL: https://codereview.chromium.org/488003005
https://code.google.com/p/v8/source/detail?r=23512

Modified:
 /branches/bleeding_edge/src/math.js
 /branches/bleeding_edge/test/mjsunit/es6/math-hyperbolic.js
 /branches/bleeding_edge/third_party/fdlibm/fdlibm.cc
 /branches/bleeding_edge/third_party/fdlibm/fdlibm.h
 /branches/bleeding_edge/third_party/fdlibm/fdlibm.js
 /branches/bleeding_edge/tools/generate-runtime-tests.py

=======================================
--- /branches/bleeding_edge/src/math.js Wed Aug 27 09:49:38 2014 UTC
+++ /branches/bleeding_edge/src/math.js Fri Aug 29 09:32:51 2014 UTC
@@ -185,14 +185,6 @@
   // -0, 0 or NaN.
   return x;
 }
-
-// ES6 draft 09-27-13, section 20.2.2.30.
-function MathSinh(x) {
-  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
-  // Idempotent for NaN, +/-0 and +/-Infinity.
-  if (x === 0 || !NUMBER_IS_FINITE(x)) return x;
-  return (MathExp(x) - MathExp(-x)) / 2;
-}

 // ES6 draft 09-27-13, section 20.2.2.12.
 function MathCosh(x) {
@@ -376,7 +368,7 @@
     "imul", MathImul,
     "sign", MathSign,
     "trunc", MathTrunc,
-    "sinh", MathSinh,
+    "sinh", MathSinh,     // implemented by third_party/fdlibm
     "cosh", MathCosh,
     "tanh", MathTanh,
     "asinh", MathAsinh,
=======================================
--- /branches/bleeding_edge/test/mjsunit/es6/math-hyperbolic.js Wed Jul 16 14:00:15 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/es6/math-hyperbolic.js Fri Aug 29 09:32:51 2014 UTC
@@ -25,6 +25,9 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+// TODO(3468): we rely on a precise Math.exp.
+// Flags: --no-fast-math
+
 [Math.sinh, Math.cosh, Math.tanh, Math.asinh, Math.acosh, Math.atanh].
     forEach(function(fun) {
   assertTrue(isNaN(fun(NaN)));
@@ -66,14 +69,14 @@
 });


-assertEquals("Infinity", String(Math.cosh(-Infinity)));
-assertEquals("Infinity", String(Math.cosh(Infinity)));
-assertEquals("Infinity", String(Math.cosh("-Infinity")));
-assertEquals("Infinity", String(Math.cosh("Infinity")));
+assertEquals(Infinity, Math.cosh(-Infinity));
+assertEquals(Infinity, Math.cosh(Infinity));
+assertEquals(Infinity, Math.cosh("-Infinity"));
+assertEquals(Infinity, Math.cosh("Infinity"));


-assertEquals("-Infinity", String(Math.atanh(-1)));
-assertEquals("Infinity", String(Math.atanh(1)));
+assertEquals(-Infinity, Math.atanh(-1));
+assertEquals(Infinity, Math.atanh(1));

 // Math.atanh(x) is NaN for |x| > 1 and NaN
 [1.000000000001, Math.PI, 10000000, 2, Infinity, NaN].forEach(function(x) {
@@ -82,6 +85,8 @@
 });


+assertEquals(0, Math.sinh(0));
+assertEquals(-Infinity, 1/Math.sinh(-0));
 assertEquals(1, Math.tanh(Infinity));
 assertEquals(-1, Math.tanh(-Infinity));
 assertEquals(1, Math.cosh(0));
@@ -97,9 +102,7 @@


 // Some random samples.
-assertEqualsDelta(0.5210953054937, Math.sinh(0.5), 1E-12);
 assertEqualsDelta(74.203210577788, Math.sinh(5), 1E-12);
-assertEqualsDelta(-0.5210953054937, Math.sinh(-0.5), 1E-12);
 assertEqualsDelta(-74.203210577788, Math.sinh(-5), 1E-12);

 assertEqualsDelta(1.1276259652063, Math.cosh(0.5), 1E-12);
@@ -134,3 +137,32 @@
 [1-(1E-16), 0, 1E-10, 1E-50].forEach(function(x) {
   assertEqualsDelta(Math.atanh(x), -Math.atanh(-x), 1E-12);
 });
+
+
+// Implementation-specific tests for sinh.
+// Case |x| < 2^-28
+assertEquals(Math.pow(2, -29), Math.sinh(Math.pow(2, -29)));
+assertEquals(-Math.pow(2, -29), Math.sinh(-Math.pow(2, -29)));
+// Case |x| < 1
+assertEquals(0.5210953054937474, Math.sinh(0.5));
+assertEquals(-0.5210953054937474, Math.sinh(-0.5));
+// sinh(10*log(2)) = 1048575/2048, case |x| < 22
+assertEquals(1048575/2048, Math.sinh(10*Math.LN2));
+assertEquals(-1048575/2048, Math.sinh(-10*Math.LN2));
+// Case |x| < 22
+assertEquals(11013.232874703393, Math.sinh(10));
+assertEquals(-11013.232874703393, Math.sinh(-10));
+// Case |x| in [22, log(maxdouble)]
+assertEquals(2.1474836479999983e9, Math.sinh(32*Math.LN2));
+assertEquals(-2.1474836479999983e9, Math.sinh(-32*Math.LN2));
+// Case |x| in [22, log(maxdouble)]
+assertEquals(1.3440585709080678e43, Math.sinh(100));
+assertEquals(-1.3440585709080678e43, Math.sinh(-100));
+// No overflow, case |x| in [log(maxdouble), threshold]
+assertEquals(1.7976931348621744e308, Math.sinh(710.4758600739439));
+assertEquals(-1.7976931348621744e308, Math.sinh(-710.4758600739439));
+// Overflow, case |x| > threshold
+assertEquals(Infinity, Math.sinh(710.475860073944));
+assertEquals(-Infinity, Math.sinh(-710.475860073944));
+assertEquals(Infinity, Math.sinh(1000));
+assertEquals(-Infinity, Math.sinh(-1000));
=======================================
--- /branches/bleeding_edge/third_party/fdlibm/fdlibm.cc Wed Aug 20 14:24:07 2014 UTC +++ /branches/bleeding_edge/third_party/fdlibm/fdlibm.cc Fri Aug 29 09:32:51 2014 UTC
@@ -78,7 +78,8 @@
     1.58730158725481460165e-03,   //          48
     -7.93650757867487942473e-05,  //          49
     4.00821782732936239552e-06,   //          50
-    -2.01099218183624371326e-07   // Q5       51
+    -2.01099218183624371326e-07,  // Q5       51
+ 710.4758600739439 // 52 overflow threshold for sinh
 };


=======================================
--- /branches/bleeding_edge/third_party/fdlibm/fdlibm.h Wed Aug 20 14:24:07 2014 UTC +++ /branches/bleeding_edge/third_party/fdlibm/fdlibm.h Fri Aug 29 09:32:51 2014 UTC
@@ -23,7 +23,7 @@

 // Constants to be exposed to builtins via Float64Array.
 struct MathConstants {
-  static const double constants[52];
+  static const double constants[53];
 };
 }
 }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/third_party/fdlibm/fdlibm.js Wed Aug 20 14:24:07 2014 UTC +++ /branches/bleeding_edge/third_party/fdlibm/fdlibm.js Fri Aug 29 09:32:51 2014 UTC
@@ -710,3 +710,52 @@
   }
   return y;
 }
+
+
+// ES6 draft 09-27-13, section 20.2.2.30.
+// Math.sinh
+// Method :
+// mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+//      1. Replace x by |x| (sinh(-x) = -sinh(x)).
+//      2.
+//                                                  E + E/(E+1)
+// 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
+//                                                      2
+//
+//          22       <= x <= lnovft :  sinh(x) := exp(x)/2
+//          lnovft   <= x <= ln2ovft:  sinh(x) := exp(x/2)/2 * exp(x/2)
+//          ln2ovft  <  x           :  sinh(x) := x*shuge (overflow)
+//
+// Special cases:
+//      sinh(x) is |x| if x is +Infinity, -Infinity, or NaN.
+//      only sinh(0)=0 is exact for finite x.
+//
+const KSINH_OVERFLOW = kMath[52];
+const TWO_M28 = 3.725290298461914e-9;  // 2^-28, empty lower half
+const LOG_MAXD = 709.7822265625;  // 0x40862e42 00000000, empty lower half
+
+function MathSinh(x) {
+  x = x * 1;  // Convert to number.
+  var h = (x < 0) ? -0.5 : 0.5;
+  // |x| in [0, 22]. return sign(x)*0.5*(E+E/(E+1))
+  var ax = MathAbs(x);
+  if (ax < 22) {
+    // For |x| < 2^-28, sinh(x) = x
+    if (ax < TWO_M28) return x;
+    var t = MathExpm1(ax);
+    if (ax < 1) return h * (2 * t - t * t / (t + 1));
+    return h * (t + t / (t + 1));
+  }
+  // |x| in [22, log(maxdouble)], return 0.5 * exp(|x|)
+  if (ax < LOG_MAXD) return h * MathExp(ax);
+  // |x| in [log(maxdouble), overflowthreshold]
+  // overflowthreshold = 710.4758600739426
+  if (ax <= KSINH_OVERFLOW) {
+    var w = MathExp(0.5 * ax);
+    var t = h * w;
+    return t * w;
+  }
+  // |x| > overflowthreshold or is NaN.
+  // Return Infinity of the appropriate sign or NaN.
+  return x * INFINITY;
+}
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Thu Aug 21 12:39:33 2014 UTC +++ /branches/bleeding_edge/tools/generate-runtime-tests.py Fri Aug 29 09:32:51 2014 UTC
@@ -51,7 +51,7 @@
 EXPECTED_FUZZABLE_COUNT = 332
 EXPECTED_CCTEST_COUNT = 7
 EXPECTED_UNKNOWN_COUNT = 17
-EXPECTED_BUILTINS_COUNT = 808
+EXPECTED_BUILTINS_COUNT = 807


 # Don't call these at all.

--
--
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