Поскольку целые числа выше 2 ^ 53 не могут быть точно представлены в двойных числах, как JS определяет их десятичное представление, когда они печатаются в виде строк?
Например, 2 ^ 55 - это 36028797018963968, и printf("%lf",(double)(1LL<<55)) в C напечатает это число правильно, поскольку в его двоичном представлении есть конечные нули, которые не вызывают потери точности при усечении.
Однако в Javascript вместо этого мы получаем 36028797018963970. Кажется, что пытается округлить числа, чтобы получить в конце 0, но не всегда - например, 2 ^ 55-4 правильно представлено с 4 в конце.
Есть ли в спецификации место, определяющее это странное поведение?
Мне не нужен обходной путь, я хочу знать, как работает поведение по умолчанию.
Это указан (не делая вид, что это простая лекция). И да, вы правы: N%10 не обязательно дает ту же цифру, что и (""+N).slice(-1).
Ах, спасибо, он ищет самое короткое (с точки зрения значащих цифр) число, которое соответствует тому же двойному значению. Интересно, почему они решили отличаться от существующих реализаций форматирования чисел.
Я не могу точно следовать алгоритму там, но мне интересно, связано ли это с Стил или Бургер-Дыбвиг
Важной частью является шаг 5, на котором ищется самый короткий номер s, который при преобразовании в Number дает такое же двоичное представление. Таким образом, число ... 70 короче, чем ... 68, потому что 0 в конце можно отрезать.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вопрос- Поскольку целые числа выше 2 ^ 53 не могут быть точно представлены в двойных числах, как JS принимает решение об их десятичном представлении, когда они печатаются в виде строк?
Числа JavaScript внутри хранятся в двоичной системе с плавающей запятой и обычно отображаются в десятичной системе.
В JavaScript используются две десятичные записи:
Фиксированное обозначение
[ "+" | "-" ] digit+ [ "." digit+ ]
Экспоненциальная запись
[ "+" | "-" ] digit [ "." digit+ ] "e" [ "+" | "-" ] digit+
Пример экспоненциальной записи - 1.2345678901234568e+21.
Правила отображения десятичных чисел:
А. Используйте экспоненциальное представление, если перед десятичной точкой более 21 цифры.
Б. Используйте экспоненциальное представление, если число начинается с «0». за которым следует более пяти нулей.
Вот подробности разд. 9.8.1 спецификации ECMAScript 5.1 описывает алгоритм отображения десятичного числа.
Учитывая число
mantissa × 10^pointPos−digitCount
The mantissa of a floating point number is an integer – the significant digits plus a sign. Leading and trailing zeros are discarded. Examples: The mantissa of 12.34 is 1234.
Дело 1.Без десятичной точки:digitCount ≤ pointPos ≤ 21
Выведите цифры (без начальных нулей), за которыми следуют нули pointPos-digitCount.
Кейс-2.Десятичная точка внутри мантиссы: 0 < pointPos ≤ 21, pointPos < digitCount
Отобразите первые цифры мантиссы pointPos, точку, а затем оставшиеся цифры digitCount-pointPos.
Кейс-3.Десятичная точка стоит перед мантиссой: −6 < pointPos ≤ 0
Отобразите 0, за которым следует точка, −pointPos, нули и мантисса.
Кейс-4.Экспоненциальная запись: pointPos ≤ -6 or pointPos > 21
Отобразите первую цифру мантиссы. Если есть больше цифр, отобразите точку и оставшиеся цифры. Затем отобразите символ e и знак плюс или минус (в зависимости от знака pointPos − 1), за которым следует абсолютное значение pointPos − 1. Таким образом, результат выглядит следующим образом.
mantissa0 [ "." mantissa1..digitCount ]
"e" signChar(pointPos−1) abs(pointPos−1)
Вопрос- Однако в Javascript вместо этого мы получаем 36028797018963970. Кажется, что пытается округлить числа, чтобы получить в конце 0, но не всегда - например, 2 ^ 55-4 правильно представлено с 4 в конце.
Есть ли в спецификации место, определяющее это странное поведение?
Проверить: Как числа кодируются в JavaScript специально ==> 5. Максимальное целое число
Дополнительная ссылка:https://medium.com/dailyjs/javascripts-number-type-8d59199db1b6
Спасибо за подробный ответ, но я думаю, что вы упустили ключевую часть, как выбирается маттисса. Если есть несколько целых чисел, соответствующих одной и той же двоичной форме, он выбирает то, у которого больше всего конечных нулей, что вызывает поведение, о котором я упоминал.
Спасибо.Я просто проверяю, что моя ссылочная ссылка неверна.Я обновила, надеюсь, все вещи покрыты ссылками. 2ality.com/2012/04/number-encoding.html
Я не знаю, что такое у меня в голове, но эта тема кажется хорошим местом для начала: stackoverflow.com/questions/30678303/…