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

时间:2017-01-16 14:57:37

标签: javascript google-chrome v8 ecmascript-7

我刚刚发现了ECMAScript 7功能a**b作为Math.pow(a,b)MDN Reference)的替代方案,并在that post中遇到了一个讨论,其中他们显然表现得很好不同。我已在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

1 个答案:

答案 0 :(得分:121)

99**99evaluated at compile time(“常量折叠”),编译器的pow routineruntime one不同。在运行时评估**时,结果与Math.pow相同 - 难怪**实际上是compiledMath.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中的错误。它has been reported并希望很快得到解决。