私のnode.jsプログラムで、このコードを実行しました
console.log(Math.tanh(-858.625086043538));
そして戻ってきNaN
ました。しかし、tanh (双曲線正接) http://mathworld.wolfram.com/HyperbolicTangent.htmlはすべての に対して定義されていますx
。それは単に返す必要があります-1
が、与えNaN
ます。誰が何が悪いのか知っていますか?
ありがとう
私のnode.jsプログラムで、このコードを実行しました
console.log(Math.tanh(-858.625086043538));
そして戻ってきNaN
ました。しかし、tanh (双曲線正接) http://mathworld.wolfram.com/HyperbolicTangent.htmlはすべての に対して定義されていますx
。それは単に返す必要があります-1
が、与えNaN
ます。誰が何が悪いのか知っていますか?
ありがとう
V8 (4.6.85.31) の Node.js (v5.4.1) バージョンの不適切な実装のように見えます。これは e^(+/-x) を使用しており、これより大きな入力の場合、( -Infinity / Infinity
) が返されます。さらに、ですNaN
。
良いニュースは、これがV8 バージョン v4.8.87 で修正され、コミットが js fdlibm port に移動したことです。これが、現在のバージョンの Chrome DevTools で機能する理由です。
Node.js が最新の V8 を取り込むまで待てない場合は、現在の V8 実装を独自のコード ( 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;
};