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

为什么Math.pow()在JavaScript中(有时)不等于**?,javascript,google-chrome,v8,ecmascript-2016,Javascript,Google Chrome,V8,Ecmascript 2016,我刚刚发现了ECMAScript 7特性a**b,作为Math.pow(a,b)()的替代品,并在中遇到了一个讨论,其中它们的行为明显不同。我已经在Chrome 55上测试过,可以确认结果不同 Math.pow(99,99)返回3.697296376497263e+197 鉴于 99**99返回3.697296376497268e+197 因此,记录差异Math.pow(99,99)-99**99将导致-5.3113799281671E+182 到目前为止,可以说这只是另一个实现,但将其包装到函

我刚刚发现了ECMAScript 7特性
a**b
,作为
Math.pow(a,b)
()的替代品,并在中遇到了一个讨论,其中它们的行为明显不同。我已经在Chrome 55上测试过,可以确认结果不同

Math.pow(99,99)
返回
3.697296376497263e+197

鉴于

99**99
返回
3.697296376497268e+197

因此,记录差异
Math.pow(99,99)-99**99
将导致
-5.3113799281671E+182

到目前为止,可以说这只是另一个实现,但将其包装到函数中的行为又有所不同:

function diff(x) {
  return Math.pow(x,x) - x**x;
}
调用
diff(99)
返回
0

为什么会这样

正如所指出的,这可以缩小到这个问题:

var x = 99;
x**x - 99**99; // Returns -5.311379928167671e+182
99**99
是(“常量折叠”),编译器的不同于。在运行时计算
**
时,结果与
Math.pow
相同-难怪
**
实际上是对
Math.pow
调用的:

console.log(99**99);//3.697296376497268e+197
a=99,b=99;
控制台日志(a**b);//3.697296376497263e+197

console.log(Math.pow(99,99));//3.697296376497263e+197
听起来好像有人重写了他们使用的算法,然后找到了一个。数字很难…@krillgar听起来很合理,但为什么在函数中没有发生相同的错误呢?@AndersonPimentel MDN链接指向一个。两者之间的区别是:var x=99;x**x;和99**99。或函数diff(x){return 99**99-(x**x);};差异(99)。对不起,间距太大,注释过滤器为两颗星:(@xszaboj将代码放在背景符号中以使其可读,同时也避免了粗体/斜体问题,因此基本上是JS试图通过预先计算
99**99
来提高性能?这会被认为是一个错误吗,因为
Math.pow
为数字和变量创建相同的输出,而
**
不会吗?@ThomasAltmann:
 数学。行
始终是运行时的,常量折叠只能由操作员完成。是的,这肯定是一个bug。从OP的外观来看,这是一个bug。我使用的是MS Edge,所有3个结果都是相同的:
3.697296376497263e+197
3.697296376497263e+197
,以及
3.697296376497263e+197
。它的定义最为不完全是一个Chrome bug。@ThomasAltmann如果常数折叠产生的值比运行时impl的值差,那么它就是一个bug。如果它产生的值比运行时的值好,那么它可能被认为是bug,也可能不被认为是bug。在这种情况下,它更好-正确的值是“…26772…”,常数折叠产生“…268”(正确舍入),并且运行时生成“…263”(在最后一个位置关闭4个以上的单位)。