Tanh 为大输入返回 NaN?

Tanh returning NaN for large input?

在我的 node.js 程序中,我 运行 这个代码

console.log(Math.tanh(-858.625086043538));

它 return 编辑了 NaN。然而,tanh(双曲正切)http://mathworld.wolfram.com/HyperbolicTangent.html 是为所有 x 定义的。它应该只是 return -1,但它给出了 NaN。有谁知道怎么了?

谢谢

Node.js (v5.4.1) version of V8 (4.6.85.31) 中看起来是一个糟糕的实现,它采用 e^(+/-x),对于更大的输入,导致 return of (-Infinity / Infinity ) 进一步,它是 NaN.

好消息是这个问题已在 V8 version v4.8.87 with a commit that moved to a js fdlibm port 中修复。这就是它在您的 current-version Chrome DevTools 中工作的原因。

如果您不能等到 Node.js 引入最新的 V8,您可以移植 current V8 implementation into your own code (which is based on this port of fdlibm),这似乎工作正常。您只是运行 真正的 V8 Math.tanh 将来可能发生的任何修复或更改的风险。这是 V8/fdlibm 端口:

Math.tanh = function (x) {
  x = x * 1;  // Convert to number.
  // x is Infinity or NaN
  if (!Math.abs(x) === Infinity) {
    if (x > 0) return 1;
    if (x < 0) return -1;
    return x;
  }
  var ax = Math.abs(x);
  var z;
  // |x| < 22
  if (ax < 22) {
    var twoM55 = 2.77555756156289135105e-17; // 2^-55, empty lower half
    if (ax < twoM55) {
      // |x| < 2^-55, tanh(small) = small.
      return x;
    }
    if (ax >= 1) {
      // |x| >= 1
      var t = Math.exp(2 * ax);
      z = 1 - 2 / (t + 2);
    } else {
      var t = Math.exp(-2 * ax);
      z = -t / (t + 2);
    }
  } else {
    // |x| > 22, return +/- 1
    z = 1;
  }
  return (x >= 0) ? z : -z;
};