Может ли точность чисел с плавающей запятой в Javascript быть источником не детерминизма?

Может ли одна и та же математическая операция возвращать разные результаты в разных архитектурах или браузерах?

Ответ 1

Хотя в редакторе спецификации языка ECMAScript 5.1 указано, что числа являются примитивными значениями, соответствующими поплавкам IEEE 754, что означает, что вычисления должны быть согласованными:

http://www.ecma-international.org/publications/files/ecma-st/ECMA-262.pdf

4.3.19 Числовое значение

примитивное значение, соответствующее 64-битовому двоичному формату двойной точности IEEE 754 значение

Примечание     Значение Number является членом типа Number и является прямым представлением числа.

Как отмечает BlueRaja, в разделе 15.8.2 есть своего рода предостережение:

Поведение функций acos, asin, atan, atan2, cos, exp, log, pow, sin, sqrt и tan точно не указаны здесь...

Значение, это, по крайней мере, некоторые случаи, когда результат операций над числами зависит от реализации и поэтому может быть непоследовательным.

Ответ 2

Другие ответы неверны. Согласно спецификации ECMAScript 5.1 (раздел 15.8.2)

ПРИМЕЧАНИЕ. Поведение функций acos, asin, atan, atan2, cos, exp, log, pow, sin, sqrt и tan точно не указаны здесь, кроме требовать конкретные результаты для определенных значений аргументов, которые представляют представляющих интерес.

...

Хотя выбор алгоритмов оставляется для реализации, рекомендуется (но не указывается этот стандарт), что в реализациях используются алгоритмы аппроксимации для арифметики IEEE 754, содержащейся в fdlibm, свободно распространяемой математическая библиотека от Sun Microsystems


Однако, даже если реализации были указаны, точные результаты операций all с плавающей запятой все равно будут зависеть от браузера/архитектуры. Это включает в себя простые операции, такие как умножение и деление.

Причина в том, что IEEE-754 позволяет системам выполнять 64-битные вычисления с плавающей запятой при более высокой точности, чем результат, что приводит к разным результатам округления, чем к системам, которые используют ту же точность, что и результат. Это именно то, что делает x86 (Intel) архитектура, поэтому в C (и javascript) иногда может быть cos(x) != cos(y), хотя x == y, даже на том же компьютере!

Это большая проблема для сетевых одноранговых игр, так как это означает, что если вычисления с более высокой точностью не могут быть отключены (как и case for С#), эти игры в значительной степени не могут использовать вычисления с плавающей запятой. Однако, как правило, это не проблема для игр с Javascript, поскольку они обычно являются клиент-серверами.

Ответ 3

Если мы предположим, что каждый поставщик браузера следует стандартам IEEE + ECMA, и во время реализации нет человеческой ошибки, нет никакой разницы.

Ответ 4

Мои два цента - примечания @goldilocks и другие ссылаются на то, что вы не должны использовать == или!= числа с плавающей запятой. Итак, что вы подразумеваете под "детерминированным"? Что поведение всегда одно и то же на разных машинах? Очевидно, это зависит от того, что вы подразумеваете под "тем же поведением".

Ну, на одном глупом буквальном уровне "того же", конечно, нет, физические биты будут разными, например. 32 бит и 64-битные машины. Так что интерпретация отсутствует.

Хорошо, так будет ли любая программа работать с тем же выходом на двух разных машинах? В общем случае нет, потому что программа C может что-то делать с памятью undefined, например, читать из неинициализированного бита.

Хорошо, так будет ли любая действительная программа делать то же самое на разных машинах? Ну, я бы сказал, что программа, которая использует == и!= Для чисел с плавающей запятой, недействительна, как программа, которая читает неинициализированную память. Я лично не знаю, может ли стандарт Javascript вызывать поведение == и!= На поплавках до такой степени, что он четко определен, если не запутан, так что если это ваш точный вопрос, вам придется увидеть другие ответы, Можете ли вы написать код javascript, который имеет undefined выход по отношению к стандарту? Никогда не читайте стандарт (другие ответы покрывают это несколько), но мой интерес это спорный вопрос, потому что программы, которые производят бы, что вы называете undeterministic поведение, являются недействительными с самого начала.