Вопрос:
Номера JavaScript являются причудливыми. Я понял, что дополнение не ассоциативно:
(-9999999999999999 + 1) + 1 === -9999999999999999 + (1 + 1) // false!
Как насчет коммутативности? Существуют ли номера JavaScript a, b такие, что
typeof a === ‘number’ typeof b === ‘number’ a + b !== b + a
все оцениваются до true (кроме NaN)?
Лучший ответ:
Если вы посмотрите ближе, вы увидите, что 1-9999999999999999 возвращает -10000000000000000, что не является результатом этой операции (должно быть -9999999999999998)
Вы просто достигаете предела точности с плавающей запятой.
Вы можете увидеть тот же эффект при этом: 0.0000000000000001 + 1 и 0.0000000000000002 + 1
Таким образом, спецификация ecmascript, номера должны соответствовать стандарту IEEE 754 с 64-разрядным форматом. Это соответствует 16-значной точности. Именно размер ваших чисел.
EDIT
Что касается вашего вопроса об коммутативности, вот что спецификация заявляет:
В остальных случаях, когда ни бесконечность, ни ноль, ни NaN не задействованы, а операнды имеют один и тот же знак или имеют разные величины, сумма вычисляется и округляется до ближайшего представимого значения с использованием круглого сечения IEEE 754, до ближайшего режима. Если величина слишком велика для представления, операция переполняется, а результат – бесконечность соответствующего знака. Язык ECMAScript требует поддержки постепенного переполнения, как определено в IEEE 754.
Поэтому он всегда должен быть коммутативным, так как сумма вычисляется, а затем округляется. Любое другое поведение будет ошибкой вашего браузера.
РЕДАКТИРОВАТЬ 2
Еще более ясно, что спецификация явно заявляет (раздел 11.6.3):
Дополнение является коммутативной операцией, но не всегда ассоциативной.