Implement Math.tanh using fdlibm port.
Contributed by Raymond Toy: http://rtoy.github.io/fdlibm-js/ R=jkummerow@chromium.org BUG=v8:3495 LOG=N Review URL: https://codereview.chromium.org/1407213002 Cr-Commit-Position: refs/heads/master@{#31335}
This commit is contained in:
parent
b7990793cf
commit
47c9e1c904
@ -182,18 +182,6 @@ function MathTrunc(x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
// ES6 draft 09-27-13, section 20.2.2.33.
|
||||
function MathTanh(x) {
|
||||
x = TO_NUMBER(x);
|
||||
// Idempotent for +/-0.
|
||||
if (x === 0) return x;
|
||||
// Returns +/-1 for +/-Infinity.
|
||||
if (!NUMBER_IS_FINITE(x)) return MathSign(x);
|
||||
var exp1 = MathExp(x);
|
||||
var exp2 = MathExp(-x);
|
||||
return (exp1 - exp2) / (exp1 + exp2);
|
||||
}
|
||||
|
||||
// ES6 draft 09-27-13, section 20.2.2.5.
|
||||
function MathAsinh(x) {
|
||||
x = TO_NUMBER(x);
|
||||
@ -329,7 +317,6 @@ utils.InstallFunctions(GlobalMath, DONT_ENUM, [
|
||||
"imul", MathImul,
|
||||
"sign", MathSign,
|
||||
"trunc", MathTrunc,
|
||||
"tanh", MathTanh,
|
||||
"asinh", MathAsinh,
|
||||
"acosh", MathAcosh,
|
||||
"atanh", MathAtanh,
|
||||
|
58
src/third_party/fdlibm/fdlibm.js
vendored
58
src/third_party/fdlibm/fdlibm.js
vendored
@ -843,6 +843,63 @@ function MathCosh(x) {
|
||||
return INFINITY;
|
||||
}
|
||||
|
||||
// ES6 draft 09-27-13, section 20.2.2.33.
|
||||
// Math.tanh(x)
|
||||
// Method :
|
||||
// x -x
|
||||
// e - e
|
||||
// 0. tanh(x) is defined to be -----------
|
||||
// x -x
|
||||
// e + e
|
||||
// 1. reduce x to non-negative by tanh(-x) = -tanh(x).
|
||||
// 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
|
||||
// -t
|
||||
// 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
|
||||
// t + 2
|
||||
// 2
|
||||
// 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t = expm1(2x)
|
||||
// t + 2
|
||||
// 22.0 < x <= INF : tanh(x) := 1.
|
||||
//
|
||||
// Special cases:
|
||||
// tanh(NaN) is NaN;
|
||||
// only tanh(0) = 0 is exact for finite argument.
|
||||
//
|
||||
|
||||
define TWO_M55 = 2.77555756156289135105e-17; // 2^-55, empty lower half
|
||||
|
||||
function MathTanh(x) {
|
||||
x = x * 1; // Convert to number.
|
||||
// x is Infinity or NaN
|
||||
if (!NUMBER_IS_FINITE(x)) {
|
||||
if (x > 0) return 1;
|
||||
if (x < 0) return -1;
|
||||
return x;
|
||||
}
|
||||
|
||||
var ax = MathAbs(x);
|
||||
var z;
|
||||
// |x| < 22
|
||||
if (ax < 22) {
|
||||
if (ax < TWO_M55) {
|
||||
// |x| < 2^-55, tanh(small) = small.
|
||||
return x;
|
||||
}
|
||||
if (ax >= 1) {
|
||||
// |x| >= 1
|
||||
var t = MathExpm1(2 * ax);
|
||||
z = 1 - 2 / (t + 2);
|
||||
} else {
|
||||
var t = MathExpm1(-2 * ax);
|
||||
z = -t / (t + 2);
|
||||
}
|
||||
} else {
|
||||
// |x| > 22, return +/- 1
|
||||
z = 1;
|
||||
}
|
||||
return (x >= 0) ? z : -z;
|
||||
}
|
||||
|
||||
// ES6 draft 09-27-13, section 20.2.2.21.
|
||||
// Return the base 10 logarithm of x
|
||||
//
|
||||
@ -1029,6 +1086,7 @@ utils.InstallFunctions(GlobalMath, DONT_ENUM, [
|
||||
"tan", MathTan,
|
||||
"sinh", MathSinh,
|
||||
"cosh", MathCosh,
|
||||
"tanh", MathTanh,
|
||||
"log10", MathLog10,
|
||||
"log2", MathLog2,
|
||||
"log1p", MathLog1p,
|
||||
|
@ -186,3 +186,21 @@ assertEquals(1.7976931348621744e308, Math.cosh(-710.4758600739439));
|
||||
// Overflow.
|
||||
assertEquals(Infinity, Math.cosh(710.475860073944));
|
||||
assertEquals(Infinity, Math.cosh(-710.475860073944));
|
||||
|
||||
// Implementation-specific tests for tanh.
|
||||
// Case |x| < 2^-55
|
||||
var two_56 = Math.pow(2, -56);
|
||||
assertEquals(two_56, Math.tanh(two_56));
|
||||
assertEquals(-two_56, Math.tanh(-two_56));
|
||||
// Case |x| < 1
|
||||
assertEquals(0.6, Math.tanh(Math.LN2));
|
||||
assertEquals(-0.6, Math.tanh(-Math.LN2));
|
||||
// Case 1 < |x| < 22
|
||||
assertEquals(15/17, Math.tanh(2 * Math.LN2));
|
||||
assertEquals(-15/17, Math.tanh(-2 * Math.LN2));
|
||||
// Case |x| > 22
|
||||
assertEquals(1, Math.tanh(100));
|
||||
assertEquals(-1, Math.tanh(-100));
|
||||
// Test against overflow
|
||||
assertEquals(1, Math.tanh(1e300));
|
||||
assertEquals(-1, Math.tanh(-1e300));
|
||||
|
Loading…
Reference in New Issue
Block a user