Почему математика?pow () (иногда) не равно ** в JavaScript?


Я только что обнаружил функцию ECMAScript 7 a**b в качестве альтернативы для Math.pow(a,b) (MDN Reference ) и наткнулся на дискуссию в том посте, в котором они, по-видимому, ведут себя по-разному. Я протестировал его в 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 109

1 ответ:

99**99 вычисляется во время компиляции ("постоянное сворачивание"), и компилятор pow подпрограмма отличается от среды выполнения. При оценке ** во время выполнения результаты идентичны с Math.pow - неудивительно, поскольку ** На самом деле компилируется в 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

На самом деле

9999=369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899

Таким образом, первый результат является лучшим приближением, однако такое расхождение между постоянными и динамическими выражениями не должно иметь места.

Это поведение похоже на ошибку в V8. Оно было сообщено и, надеюсь, скоро будет исправлено.