为什么Math.pow()(有时)不等于JavaScript中的**? [英] Why is Math.pow() (sometimes) not equal to ** in JavaScript?

查看:168
本文介绍了为什么Math.pow()(有时)不等于JavaScript中的**?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚发现了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

到目前为止,可以这么说,它只是另一个实现,但是将它封装到一个函数中会有不同的表现:

 函数diff(x){
return Math.pow(x,x) - x ** x;

调用 diff(99)返回 0



为什么会这样?

正如 xszaboj 所指出的那样,这可以归结为这个问题:

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


解决方案

99 ** 99 在编译时评估为时间(常量折叠)和编译器的 pow 例程不同于运行时间。在运行时评估 ** 时,结果与 Math.pow 相同 - 难怪因为 ** 实际上是编译 Math.pow 调用:

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

其实$
$ b

99 99 = 369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899



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



这种行为看起来像V8中的一个错误。它已被举报,并希望很快得到解决。


I've just discovered the ECMAScript 7 feature a**b as an alternative for Math.pow(a,b) (MDN Reference) and came across a discussion in that post, in which they apparently behave differently. I've tested it in Chrome 55 and can confirm that the results differ.

Math.pow(99,99) returns 3.697296376497263e+197

whereas

99**99 returns 3.697296376497268e+197

So logging the difference Math.pow(99,99) - 99**99 results in -5.311379928167671e+182.

So far it could be said, that it's simply another implementation, but wrapping it in a function behaves different again:

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

calling diff(99) returns 0.

Why is that happening?

As xszaboj pointed out, this can be narrowed down to this problem:

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

解决方案

99**99 is evaluated at compile time ("constant folding"), and the compiler's pow routine is different from the runtime one. When evaluating ** at run time, results are identical with Math.pow — no wonder since ** is actually compiled to a Math.pow call:

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

Actually

9999=369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899

so the first result is a better approximation, still such a discrepancy between constant- and dynamic expressions shouldn't take place.

This behavior looks like a bug in V8. It has been reported and will hopefully get fixed soon.

这篇关于为什么Math.pow()(有时)不等于JavaScript中的**?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆