为什么在 JavaScript 中 Math.pow()(有时)不等于 * * ?

我刚刚发现 ECMAScript 7的特性 a**bMath.pow(a,b)(MDN 参考资料)的替代品,并在 that post中遇到了一个讨论,在这个讨论中,它们的表现明显不同。我已经在 Chrome55中测试过了,可以确认结果是不同的。

返回 3.697296376497263e+197

然而呢

返回 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
11520 次浏览

99**99evaluated at compile time(“常数折叠”) ,编译器的 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 = 369729637649726772657187905628805440595687642817411024302599724235525704552775234214106500101282327279409789548326540119429967694359451621570193644014418071060665930138499977999915920049989999

所以第一个结果是一个更好的近似,但是在常量表达式和动态表达式之间不应该发生这样的差异。

这种行为看起来像 V8中的一个 bug。它是 已经被报道了,希望很快就能修复。