Reviewers: Raymond Toy,

Description:
Port fdlibm implementation for Math.cosh.

[email protected]
BUG=v8:3494

Please review this at https://codereview.chromium.org/522723002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+75, -9 lines):
  M src/math.js
  M test/mjsunit/es6/math-hyperbolic.js
  M third_party/fdlibm/fdlibm.js
  M tools/generate-runtime-tests.py


Index: src/math.js
diff --git a/src/math.js b/src/math.js
index 008a41ee55b2db74f7a522957e471f38990204d2..f06249d2521fc8447b7eda8aab8b1b171c2b0cd8 100644
--- a/src/math.js
+++ b/src/math.js
@@ -186,13 +186,6 @@ function MathTrunc(x) {
   return x;
 }

-// ES6 draft 09-27-13, section 20.2.2.12.
-function MathCosh(x) {
-  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
-  if (!NUMBER_IS_FINITE(x)) return MathAbs(x);
-  return (MathExp(x) + MathExp(-x)) / 2;
-}
-
 // ES6 draft 09-27-13, section 20.2.2.33.
 function MathTanh(x) {
   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
@@ -369,7 +362,7 @@ function SetUpMath() {
     "sign", MathSign,
     "trunc", MathTrunc,
     "sinh", MathSinh,     // implemented by third_party/fdlibm
-    "cosh", MathCosh,
+    "cosh", MathCosh,     // implemented by third_party/fdlibm
     "tanh", MathTanh,
     "asinh", MathAsinh,
     "acosh", MathAcosh,
Index: test/mjsunit/es6/math-hyperbolic.js
diff --git a/test/mjsunit/es6/math-hyperbolic.js b/test/mjsunit/es6/math-hyperbolic.js index 1632e00b222c5ff277bd385ec1e4d2d15795c59d..8f7164dfef02afeb713014e0818c74e5d9cd4849 100644
--- a/test/mjsunit/es6/math-hyperbolic.js
+++ b/test/mjsunit/es6/math-hyperbolic.js
@@ -166,3 +166,23 @@ assertEquals(Infinity, Math.sinh(710.475860073944));
 assertEquals(-Infinity, Math.sinh(-710.475860073944));
 assertEquals(Infinity, Math.sinh(1000));
 assertEquals(-Infinity, Math.sinh(-1000));
+
+// Implementation-specific tests for cosh.
+// Case |x| < 2^-55
+assertEquals(1, Math.cosh(Math.pow(2, -55)));
+assertEquals(1, Math.cosh(-Math.pow(2, -55)));
+// Case |x| < 1/2*log(2). cosh(Math.LN2/4) = (sqrt(2)+1)/2^(5/4)
+assertEquals(1.0150517651282178, Math.cosh(Math.LN2/4));
+assertEquals(1.0150517651282178, Math.cosh(-Math.LN2/4));
+// Case 1/2*log(2) < |x| < 22. cosh(10*Math.LN2) = 1048577/2048
+assertEquals(512.00048828125, Math.cosh(10*Math.LN2));
+assertEquals(512.00048828125, Math.cosh(-10*Math.LN2));
+// Case 22 <= |x| < log(maxdouble)
+assertEquals(2.1474836479999983e9, Math.cosh(32*Math.LN2));
+assertEquals(2.1474836479999983e9, Math.cosh(-32*Math.LN2));
+// Case log(maxdouble) <= |x| <= overflowthreshold
+assertEquals(1.7976931348621744e308, Math.cosh(710.4758600739439));
+assertEquals(1.7976931348621744e308, Math.cosh(-710.4758600739439));
+// Overflow.
+assertEquals(Infinity, Math.cosh(710.475860073944));
+assertEquals(Infinity, Math.cosh(-710.475860073944));
Index: third_party/fdlibm/fdlibm.js
diff --git a/third_party/fdlibm/fdlibm.js b/third_party/fdlibm/fdlibm.js
index 95ea5f442f034e7226d3fc803c459bd0345b634f..08c6f5e7207112ac80c5f420f98990e56b7468b0 100644
--- a/third_party/fdlibm/fdlibm.js
+++ b/third_party/fdlibm/fdlibm.js
@@ -759,3 +759,56 @@ function MathSinh(x) {
   // Return Infinity of the appropriate sign or NaN.
   return x * INFINITY;
 }
+
+
+// ES6 draft 09-27-13, section 20.2.2.12.
+// Math.cosh
+// Method :
+// mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+//      1. Replace x by |x| (cosh(x) = cosh(-x)).
+//      2.
+//                                                      [ exp(x) - 1 ]^2
+//          0        <= x <= ln2/2  :  cosh(x) := 1 + -------------------
+//                                                         2*exp(x)
+//
+//                                                 exp(x) + 1/exp(x)
+//          ln2/2    <= x <= 22     :  cosh(x) := -------------------
+//                                                        2
+//          22       <= x <= lnovft :  cosh(x) := exp(x)/2
+//          lnovft   <= x <= ln2ovft:  cosh(x) := exp(x/2)/2 * exp(x/2)
+//          ln2ovft  <  x           :  cosh(x) := huge*huge (overflow)
+//
+// Special cases:
+//      cosh(x) is |x| if x is +INF, -INF, or NaN.
+//      only cosh(0)=1 is exact for finite x.
+//
+const KCOSH_OVERFLOW = kMath[52];
+
+function MathCosh(x) {
+  x = x * 1;  // Convert to number.
+  var ix = %_DoubleHi(x) & 0x7fffffff;
+  // |x| in [0,0.5*log2], return 1+expm1(|x|)^2/(2*exp(|x|))
+  if (ix < 0x3fd62e43) {
+    var t = MathExpm1(MathAbs(x));
+    var w = 1 + t;
+    // For |x| < 2^-55, cosh(x) = 1
+    if (ix < 0x3c800000) return w;
+    return 1 + (t * t) / (w + w);
+  }
+  // |x| in [0.5*log2, 22], return (exp(|x|)+1/exp(|x|)/2
+  if (ix < 0x40360000) {
+    var t = MathExp(MathAbs(x));
+    return 0.5 * t + 0.5 / t;
+  }
+  // |x| in [22, log(maxdouble)], return half*exp(|x|)
+  if (ix < 0x40862e42) return 0.5 * MathExp(MathAbs(x));
+  // |x| in [log(maxdouble), overflowthreshold]
+  if (MathAbs(x) <= KCOSH_OVERFLOW) {
+    var w = MathExp(0.5 * MathAbs(x));
+    var t = 0.5 * w;
+    return t * w;
+  }
+  if (NUMBER_IS_NAN(x)) return x;
+  // |x| > overflowthreshold.
+  return INFINITY;
+}
Index: tools/generate-runtime-tests.py
diff --git a/tools/generate-runtime-tests.py b/tools/generate-runtime-tests.py index 7efcf8c65d1b3e5d813b39e12207753c1574ddc2..638c4aedcd72780b32a07524ca15ddc0ec9bf7fe 100755
--- a/tools/generate-runtime-tests.py
+++ b/tools/generate-runtime-tests.py
@@ -51,7 +51,7 @@ EXPECTED_FUNCTION_COUNT = 431
 EXPECTED_FUZZABLE_COUNT = 332
 EXPECTED_CCTEST_COUNT = 7
 EXPECTED_UNKNOWN_COUNT = 17
-EXPECTED_BUILTINS_COUNT = 807
+EXPECTED_BUILTINS_COUNT = 806


 # 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