1. ホーム
  2. javascript

[解決済み] JavaScriptでMath.pow()が**と等しくない(ことがある)のはなぜですか?

2022-08-31 02:09:18

質問

ECMAScript 7 の機能を発見しました。 a**b の代わりとして Math.pow(a,b) ( MDN リファレンス ) の中で議論されているのを発見しました。 その投稿 で、どうやら挙動が異なるようです。私は Chrome 55 でテストし、結果が異なることを確認できました。

Math.pow(99,99) 戻る 3.697296376497263e+197

ここで

99**99 は返す 3.697296376497268e+197

というわけで、差分をロギングすると Math.pow(99,99) - 99**99 の結果は -5.311379928167671e+182 .

ここまでは単に別の実装と言えますが、これを関数で包むとまた違う挙動をします。

function diff(x) {
  return Math.pow(x,x) - x**x;
}

呼び出し diff(99) が返す 0 .

なぜそうなるのでしょうか?

として xszaboj が指摘したように、この問題に絞ることができます。

var x = 99;
x**x - 99**99; // Returns -5.311379928167671e+182

どのように解決するのですか?

99**99 はコンパイル時に評価されます。 ("constant folding")、そしてコンパイラの pow ルーチン とは異なり ランタイムのもの . を評価するとき ** を実行時に評価した場合、結果は Math.pow - と同じになるのは不思議ではありません。 ** は実際には コンパイルされた Math.pow を呼び出します。

console.log(99**99);           // 3.697296376497268e+197
a = 99, b = 99;
console.log(a**b);             // 3.697296376497263e+197
console.log(Math.pow(99, 99)); // 3.697296376497263e+197

実際に

99 99 =369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899

というわけで、最初の結果はより良い近似値ですが、それでも定数式と動的式の間でこのような不一致が起こるべきではありません。

この動作は、V8のバグのように見えます。それは は報告されています。 と報告されており、うまくいけばすぐに修正されるでしょう。