Преобразование JavaScript по умолчанию Number
в строку дает достаточно десятичных цифр, чтобы однозначно отличить Number
.(Это вытекает из шага 5 в п. 7.1.12.1 спецификации языка ECMAScript 2018 , которую я немного объясняю здесь .) Форматирование с помощью console.log
не рассматривается в ECMAScriptспецификации, но, скорее всего, Number
преобразуется в строку с использованием тех же правил, что и для NumberToString
.
Поскольку остановка на десятичной цифре, производящая 131621703842267140, достаточна для того, чтобы отличить число с плавающей запятой от егодва соседних представимых значения, 131621703842267120 и 131621703842267152, на этом JavaScript останавливается.
Вы можете запросить дополнительные цифры с помощью toPrecision
;следующее производит «131621703842267136.000»:
var x = 131621703842267136;
console.log(x.toPrecision(21))
(Обратите внимание, что 131621703842267136 точно представлен в базовом 64-битном двоичном формате IEEE-754, который JavaScript использует для Number
, а многие реализации C используют для double
Таким образом, в этом вопросе нет ошибок округления из-за формата с плавающей запятой. Все изменения являются результатом преобразований между десятичной и плавающей запятой.)
Стандарт C не отвечает требованиям к форматированию с плавающей запятой,но производство «131621703737409536.000000» для 131621703842267136 нарушает их.Это регулируется этим предложением в C 2018 (и 2011) 7.21.6.1 13:
В противном случае исходное значение ограничено двумя соседними десятичными строками L <<em>U , оба имеют DECIMAL_DIG
значащих цифр;значение результирующей десятичной строки D должно удовлетворять L ≤ D ≤ U с дополнительным условием, что ошибка должна иметьправильный знак для текущего направления округления.
DECIMAL_DIG
должно быть не менее десяти, согласно 5.2.4.2.2 12. Число 131621703 8 42267136 (жирным шрифтом отмечен десятыйцифра) ограничивается двумя смежными десятизначными строками «131621703 8 00000000» и «131621703 9 00000000».Строка «131621703 7 37409536.000000» не находится между ними.
Это также не может быть результатом реализации C, использующей другой формат с плавающей запятой для double
, как 5.2.4.2..2 требует, чтобы формат был достаточным для преобразования не менее десяти десятичных цифр в double
и обратно в десятичную без изменения значения.