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
は コンパイル時に評価 (「定数折りたたみ」)であり、コンパイラの 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
実は
9999= 369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899
したがって、最初の結果はより優れた近似値ですが、定数式と動的式の間でこのような矛盾は発生しません。
この動作はV8のバグのように見えます。それは 報告されている であり、うまくいけばすぐに修正されるでしょう。