Различаются ли в браузере последние цифры математической функции JavaScript (atan2) в пределах спецификации? - PullRequest
28 голосов
/ 07 июня 2019

Я вижу различия между Firefox и Safari в последней цифре вывода из Math#atan2.

Мой код:

Math.atan2(-0.49999999999999994, 0.8660254037844387)

Safari (12.1.1) дает -0.5235987755982988, но Firefox (Mac / 67.0) дает -0.5235987755982987.

Это, конечно, небольшая разница.Однако, похоже, что все реализации должны давать одинаковые выходные данные для всех входных данных.Подобное отличие может, например, привести к тому, что оператор if будет следовать разным путям в зависимости от браузера.

Может ли то, что я вижу, нарушать какую-либо версию спецификации ECMAScript?

Ответы [ 3 ]

33 голосов
/ 07 июня 2019

В спецификации ECMAScript 2015 сказано следующее:

Поведение функций acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, cos, cosh, exp, expm1, hypot, log, log1p, log2, log10, pow, random, sin, sinh, sqrt, tan и tanh здесь точно не указаны, за исключением того, что требуются конкретные результаты для определенных значений аргументов, представляющих интересующие нас граничные случаи. Для других значений аргументов эти функции предназначены для вычисления приближений к результатам знакомых математических функций, но допускается некоторая широта в выборе алгоритмов аппроксимации. Общее намерение состоит в том, чтобы исполнитель мог использовать ту же математическую библиотеку для ECMAScript на данной аппаратной платформе, доступной для программистов на этой платформе.

Хотя выбор алгоритмов оставлен на усмотрение реализации, рекомендуется (но не указано в этом стандарте), чтобы реализации использовали алгоритмы аппроксимации для арифметики IEEE 754-2008, содержащейся в свободно распространяемой математической библиотеке fdlibm от Sun Microsystems ( http://www.netlib.org/fdlibm).

Спецификация 5.1 имеет похожий язык.

Так что я думаю, можно с уверенностью сказать, что это поведение не нарушает спецификации.

9 голосов
/ 07 июня 2019

Подобные различия с плавающей точкой будут происходить на разных CPU / FPU и разных математических библиотеках на любом языке или платформе. Если вы зависите от правильного уровня точности, у вас будут проблемы. Вы всегда должны рассматривать значения с плавающей запятой как "нечеткие".

Спецификация ECMA не определяет точность:

Функция Math.atan2 () возвращает угол на плоскости (в радианах) между положительной осью х и лучом от (0,0) до точки (х, у), для Math.atan2 (у, х).

0 голосов
/ 07 июня 2019

должно быть плавающей точкой.Я предлагаю добавить некоторую пороговую проверку вместо использования равных в условиях.

...