Разная математика в разных js-движках

Том МакРайт — разработчик Mapbox и OpenStreetMap — недавно опубликовал статью про отличия реализаций математических функций в JavaScript-движках — "Math keeps changing".

Однажды Том столкнулся с падающими тестами в своей библиотеке для работы со статистическими функциями. Тесты падали в 12-ой версии Node, в 10-ой всё было ок. Его это заинтересовало, и он пошёл смотреть реализации движков и читать спецификацию.

В спецификации ECMAScript сказано, что в ней нет точного описания поведения математических функций (sin, cos, exp, pow, random, sqrt и т,п,). Разработчики стандарта пошли на такой шаг, чтобы в JavaScript-движках можно было использовать все преимущества нижележащей платформы, например, специфичные команды CPU для работы с тригонометрией. Именно из-за этого падали тесты Тома. Исторически V8 использовал свою собственную библиотеку для математических функций, затем использовал JavaScript-порт fdblibm, сейчас там используется C-версия fdblibm.

Для того чтобы предотвратить подобные ошибки, результат вычислений сравнивают относительно малой величины "эпсилон" — Math.abs(result - expected) < epsilon. Можно также использовать функции из библиотеки stdlib-js, но они работают не так быстро как их соседи из библиотек, скомилированных в нативный код.

В общем, мне статья очень понравилась. Рекомендую почитать.

https://macwright.org/2020/02/14/math-keeps-changing.html

← На главную