Номера JavaScript, одинакового размера в памяти?

Я читаю раздел типа номера книги Professional JavaScript для веб-разработчиков. Кажется, что все номера ECMAScript являются бинарными 64-мя плавающей точкой, что подтверждается этой статьей MDN. Но автор книги также говорит:

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

Я ожидал, что каждый номер будет занимать одинаковый объем памяти: 64 бит. В статье MDN говорится: "Для целых чисел нет определенного типа". Кто-нибудь знает, что имел в виду автор книги? Как целые числа занимают меньше памяти, когда они хранятся как 64-битные поплавки (если у меня есть это право)? Вы найдете весь раздел по ссылке выше (бесплатный образец книги).

Ответ 1

JavaScript не имеет другого типа номера, кроме двойной точности с плавающей запятой (кроме ECMAScript 6 типизированных массивов), но основная реализация может выбирайте, чтобы хранить номера так, как им нравится, пока код JavaScript ведет себя одинаково.

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

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

Реализация различается в разных браузерах. В настоящее время он, похоже, имеет огромное значение в MS Edge, большой разнице в Firefox, и никакой разницы в Chrome нет: http://jsperf.com/int-vs-double-implementation (Примечание: jsperf считает, что MS Edge - Chrome 42.)


Дальнейшие исследования:

JS-двигатели Spidermonkey (Firefox), V8 (Chrome, Opera), JavaScriptCore (Safari), Chakra (IE) и Rhino (и, возможно, другие, но сложнее найти детали реализации) используют разные способы использования целого типы или сохранение чисел как целых чисел, когда это возможно. Некоторые цитаты:

"Чтобы иметь эффективное представление чисел и JavaScript объекты, V8 представляет нас обоих с 32-битным значением. Он использует бит знать, является ли это объектом (флаг = 1) или целое число (флаг = 0), называемое здесь SMall Integer или SMI из-за его 31 бит."

http://thibaultlaurens.github.io/javascript/2013/04/29/how-the-v8-engine-works/

"JavaScript не имеет встроенного понятия целочисленного значения, но для эффективности JavaScriptCore будет представлять большинство целых чисел как int32 а не как двойной".

http://trac.webkit.org/wiki/JavaScriptCore

"[...] не двойные значения - это тег 32-разрядного типа и 32-разрядная полезная нагрузка, обычно это либо указатель, либо подписанное 32-битное целое число."

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals

"В Windows 10 и Microsoft Edge мы начали оптимизацию Chakras синтаксический анализатор и JIT-компилятор для идентификации неконстантной переменной объявления целых чисел, которые определены глобально и никогда измененный в течение времени выполнения программы".

https://blogs.windows.com/msedgedev/2015/05/20/delivering-fast-javascript-performance-in-microsoft-edge/

Ответ 2

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

Этот абзац - полная глупость. Игнорируйте это!

Числа - это числа. ECMAScript не делает различий между значениями с плавающей запятой и целыми числами.

Даже в течение большинства сеансов JS все числовые значения сохраняются как плавающая точка с двойной точностью.

Ответ 3

Не уверен, что я полностью понял ваш вопрос, но "There is no specific type for integers" означает, что JavaScript не распознает отдельные типы для целых чисел и float, но они оба введены как Числа. Разделение int/float происходит "за шторами", и это означает, что они означают "ECMAScript always looks for ways to convert values into integers".

Суть в том, что вам не нужно беспокоиться об этом, если только вам не нужны ваши переменные для имитации целых чисел или поплавков для использования на других языках, и в этом случае это возможно (я сказал , вероятно,?) лучше передать их как строки (потому что у вас возникли бы проблемы с передачей, скажем, 5.0 как с плавающей точкой, потому что JS немедленно преобразует ее в 5, именно из-за части "ECMAScript always looks for ways to convert values into integers").

alert(5.0); // don't expect a float from this