Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Math.pow() (sometimes) not equal to ** in JavaScript?

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
like image 851
Thomas Altmann Avatar asked Sep 27 '22 05:09

Thomas Altmann


People also ask

How does Math POW work in Javascript?

The Math. pow() function returns the base to the exponent power, as in base exponent , the base and the exponent are in decimal numeral system. Because pow() is a static method of Math , use it as Math.

What is the value of Math POW?

pow() is used to calculate a number raise to the power of some other number. This function accepts two parameters and returns the value of first parameter raised to the second parameter.

Is Math POW a value returning method?

pow() is used to return the value of first argument raised to the power of the second argument.

How is built in function pow () function different from function Math pow () explain with an example?

The built-in pow(x,y [,z]) function has an optional third parameter as modulo to compute x raised to the power of y and optionally do a modulo (% z) on the result. It is same as the mathematical operation: (x ^ y) % z. Whereas, math. pow() function does not have modulo functionality.


1 Answers

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.

like image 128
georg Avatar answered Oct 19 '22 20:10

georg