Как JS преобразует большие числа (больше 2 ^ 53) в строку

Поскольку целые числа выше 2 ^ 53 не могут быть точно представлены в двойных числах, как JS определяет их десятичное представление, когда они печатаются в виде строк?

Например, 2 ^ 55 - это 36028797018963968, и printf("%lf",(double)(1LL<<55)) в C напечатает это число правильно, поскольку в его двоичном представлении есть конечные нули, которые не вызывают потери точности при усечении.

Однако в Javascript вместо этого мы получаем 36028797018963970. Кажется, что пытается округлить числа, чтобы получить в конце 0, но не всегда - например, 2 ^ 55-4 правильно представлено с 4 в конце.

Есть ли в спецификации место, определяющее это странное поведение?

Я не знаю, что такое у меня в голове, но эта тема кажется хорошим местом для начала: stackoverflow.com/questions/30678303/…

jmcgriz 24.07.2018 17:34

Мне не нужен обходной путь, я хочу знать, как работает поведение по умолчанию.

riv 24.07.2018 17:37

Это указан (не делая вид, что это простая лекция). И да, вы правы: N%10 не обязательно дает ту же цифру, что и (""+N).slice(-1).

Denys Séguret 24.07.2018 17:41

Ах, спасибо, он ищет самое короткое (с точки зрения значащих цифр) число, которое соответствует тому же двойному значению. Интересно, почему они решили отличаться от существующих реализаций форматирования чисел.

riv 24.07.2018 17:55

Я не могу точно следовать алгоритму там, но мне интересно, связано ли это с Стил или Бургер-Дыбвиг

Barmar 24.07.2018 18:07

Важной частью является шаг 5, на котором ищется самый короткий номер s, который при преобразовании в Number дает такое же двоичное представление. Таким образом, число ... 70 короче, чем ... 68, потому что 0 в конце можно отрезать.

riv 24.07.2018 18:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
6
246
1

Ответы 1


Вопрос- Поскольку целые числа выше 2 ^ 53 не могут быть точно представлены в двойных числах, как JS принимает решение об их десятичном представлении, когда они печатаются в виде строк?



1. Способ печати десятичных чисел в JS

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

В JavaScript используются две десятичные записи:

Фиксированное обозначение

[ "+" | "-" ] digit+ [ "." digit+ ]

Экспоненциальная запись

[ "+" | "-" ] digit [ "." digit+ ] "e" [ "+" | "-" ] digit+

Пример экспоненциальной записи - 1.2345678901234568e+21.

Правила отображения десятичных чисел:

А. Используйте экспоненциальное представление, если перед десятичной точкой более 21 цифры.

Б. Используйте экспоненциальное представление, если число начинается с «0». за которым следует более пяти нулей.


2. Алгоритм отображения ECMAScript 5.1

Вот подробности разд. 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

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

riv 27.07.2018 09:00

Спасибо.Я просто проверяю, что моя ссылочная ссылка неверна.Я обновила, надеюсь, все вещи покрыты ссылками. 2ality.com/2012/04/number-encoding.html

NullPointer 27.07.2018 12:56

Другие вопросы по теме