Странный результат для Math.pow () в JavaScript в разных браузерах - PullRequest
2 голосов
/ 02 мая 2019

Возможно, это происходит только в последней версии Chrome.

Некоторое странное поведение для отрицательного показателя только в браузере Chrome .

Я уже проверил с различными браузерами и нахожу это действительно странным.Так как FireFox & Chromium покажет точно такой же результат, в то время как Последняя версия Chrome покажет другой результат для некоторых примеров.И я не знаю, что происходит?

Вот мои выводы для разных браузеров ...

FireFox

enter image description here

Хром

enter image description here

Хром

enter image description here

Странная вещь!!

Для Math.pow(10,-4) и Math.pow(10,-5) ответ должен быть 0.0001 и 0.00001 соответственно, но почему последняя версия Chrome показывает 0.00009999999999999999 и 0.000009999999999999999 соответственно !!

Может у кого-нибудь есть объяснение вышеприведенному сценарию, почему Chrome так работает?

FYI - Все версии браузера, уже упомянутые в изображениях.

1 Ответ

2 голосов
/ 02 мая 2019

Возвращает зависящее от реализации приближение результата повышения base до степени экспоненты .

https://tc39.github.io/ecma262/#sec-applying-the-exp-operator

0,0001 является следующим представимым числом выше 0,00009999999999999999. (Результаты отличаются на одну единицу наименьшей точности .)

Похоже, что это изменилось в 74.0.3700.0 ( changelog ), что соответствует V8 roll до 7.4.113, включая этот коммит:

https://chromium.googlesource.com/v8/v8/+/98453126c109016c9d32c6ebd89dd83f69dd8efb

[встроенные] [турбовентилятор] Refactor Float64Pow для использования одной реализации

Удалите зависящие от платформы реализации Float64Pow и утилиты Pow in в пользу реализации base :: ieee754 :: pow.

Это объединяет реализацию pow для компилятора, wasm и во время выполнения.

Поэтому они переключили реализацию Pow на что-то другое.

Чтобы продемонстрировать, что мы получаем другое число , и оно не связано с преобразованием с плавающей запятой в десятичное:

> 10**-4 == 1e-4

Или, если вы не уверены и хотите исследовать поплавки на низком уровне, сбросьте число в шестнадцатеричном виде:

(Требуется Firefox 67.)

from_bits = b => new Float64Array(new BigUint64Array([b]).buffer)[0]
to_bits = f => new BigUint64Array(new Float64Array([f]).buffer)[0]

console.log(to_bits(Math.pow(10,-4)).toString(16))

Я получаю 3f1a36e2eb1c432d в Firefox и 3f1a36e2eb1c432c в Chrome.

...