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.