Тан, возвращающий NaN для большого вклада?

В моей программе node.js я запустил этот код

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

и он вернулся NaN, Тем не менее, tanh (гиперболический тангенс) http://mathworld.wolfram.com/HyperbolicTangent.html определен для всех x, Должно просто вернуться -1, но его подача NaN, Кто-нибудь знает, что не так?

Спасибо

1 ответ

Решение

Выглядит как плохая реализация в Node.js (v5.4.1) версии V8 (4.6.85.31), которая принимает e^(+/-x), что при большем вводе приводит к возвращению (-Infinity / Infinity) который, кроме того, является NaN,

Хорошей новостью является то, что это было исправлено в версии V8 v4.8.87 с фиксацией, которая была перенесена в порт js fdlibm. Вот почему он работает в вашей текущей версии Chrome DevTools.

Если вы не можете ждать, пока Node.js загрузит последнюю версию V8, вы можете перенести текущую реализацию V8 в свой собственный код (который основан на этом порте fdlibm), который, кажется, работает нормально. Вы просто рискуете исправлениями или изменениями в реальном Vath 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;
};
Другие вопросы по тегам