Pourquoi Math.pow () (parfois) n'est-il pas égal à ** en JavaScript?

Je viens de découvrir que la fonctionnalité ECMAScript 7 a**b est une alternative pour Math.pow(a,b) ( Référence MDN ) et a rencontré une discussion dans cette publication , dans laquelle elles se comportent différemment. Je l'ai testé dans Chrome 55 et je peux confirmer que les résultats diffèrent.

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

tandis que

99**99 renvoie 3.697296376497268e+197

Ainsi, enregistrez-vous la différence Math.pow(99,99) - 99**99 résultats dans -5.311379928167671e+182 .

Jusqu'à présent, on pourrait dire que c'est simplement une autre mise en œuvre, mais l'emballage dans une fonction se comporte de nouveau à nouveau:

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

Appeler diff(99) renvoie 0 .

Pourquoi cela se passe-t-il?

Comme l'a souligné xszaboj , cela peut être réduit à ce problème:

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

99**99 est évalué au moment de la compilation ("pliage constant"), et la routine de pow du compilateur est différente de celle de l' exécution . Lors de l'évaluation ** au moment de l'exécution, les résultats sont identiques à Math.pow – pas étonnant puisque ** est effectivement compilé dans un appel 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