Что означает ошибка RangeError: Array size is not a small enough positive integer

Когда попытался создать слишком большой массив

Ситуация. К разработчику одной федеральной торговой сети поступила такая задача: собрать и предварительно обработать все покупки за месяц со всех магазинов по всей стране. Разработчик выяснил стандартный среднемесячный объём данных, количество магазинов, сколько касс в магазине и количество смен.

Для обработки данных разработчик создаёт пустой массив, но хочет заранее указать, сколько элементов будет в массиве. Для этого он получает общее значение данных для обработки и объявляет новую переменную с массивом:

// получаем общее количество записей для обработки,
// исходя из средних данных, количества магазинов, касс и смен
var total = monthData * shops * boxOffice * shifts;

// организуем новый массив для данных
var data = new Array(total);

Но при запуске код выдаёт ошибку:

❌ RangeError: Array size is not a small enough positive integer

Видно, что код ругается на размер массива, но не ругается на результат умножения — но почему?

Что это значит: компьютер не смог создать массив с таким большим количеством элементов и попросил уменьшить их количество.

Когда встречается: когда мы пытаемся создать массив, где элементов больше, чем 2 32 − 1 = 4 294 967 295. Такое ограничение на размер массива появилось в 2009 году из-за внутренней команды ToUint32() — она переводит числа в 32-битный формат без использования отрицательных чисел. Максимальное число, которое попадает в этот диапазон, — 4 294 967 295.

Что делать с ошибкой RangeError: Array size is not a small enough positive integer

Решить эту ошибку можно двумя способами: указав безопасное количество элементов вручную или проверив его перед созданием массива.

В первом случае всё просто: мы создаём новый массив и сразу указываем максимальное количество элементов:

var data = new Array(4294967295);

Во втором — проверяем допустимый размер перед созданием:

// получаем общее количество записей для обработки,
// исходя из средних данных, количества магазинов, касс и смен
var total = monthData * shops * boxOffice * shifts;

// если не превысили размер
if (total <= 4294967295) {
	// организуем новый массив для данных
	var data = new Array(total);
	} else {
		//иначе выводим сообщение об ошибке
		console.log('Слишком большой размер массива')
	}

Но почему компьютер не ругался на промежуточный результат?

Когда мы перемножили числа и положили результат в переменную total, к нему применялись совсем другие требования, в том числе и на максимальный размер числа — 21024 − 1. Это в 32 раза больше, чем максимально возможное количество элементов массива. 

Получается, что очень большую переменную мы посчитать можем, а использовать её для создания массива — нет. А если интересно, как можно работать в JavaScript с очень большими числами, — почитайте, как мы научили компьютер складывать в столбик.

Текст:

Михаил Полянин

Редактор:

Максим Ильяхов

Художник:

Алексей Сухов

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Соцсети:

Виталий Вебер

Веб-разработка — это новый чёрный
На базе веб-технологий делают всё — от сложного софта до высокобюджетных игр. Изучите технологии и начните карьеру в ИТ. Старт бесплатно. Попробуйте, вдруг вам понравится.
Изучить
Веб-разработка — это новый чёрный
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Учим компьютер складывать числа любой длины
Учим компьютер складывать числа любой длины

Человек умеет складывать в столбик, а компьютер — нет

medium
Uncaught SyntaxError: Unexpected identifier — что это означает?
Uncaught SyntaxError: Unexpected identifier — что это означает?

Вредная ошибка, которую легко исправить.

medium
Делаем эффектную фотогалерею на сайте
Делаем эффектную фотогалерею на сайте

Красивый трёхмерный виджет с несложным кодом

hard
Вкладываете условия в условия? Это для вас
easy
Что означает ошибка SyntaxError: 'break' outside loop
Что означает ошибка SyntaxError: 'break' outside loop

Это значит, что мы пытаемся выйти из цикла, которого нет

easy
Задача с собеседования: как найти палиндром
Задача с собеседования: как найти палиндром

Элитная задача с сайта Leetcode

easy
Большой разбор: ИИ научился играть в динозаврика из Chrome

Тот редкий случай, когда хочешь остаться без интернета.

medium
Собираем змейку на Arduino

Это будет самая необычная змейка, в которую вы играли.

hard
Объективный таймер обратного отсчёта на PHP

Если нужно взять дату напрямую с сервера

medium
Uncaught TypeError: Cannot read property — что это означает
Uncaught TypeError: Cannot read property — что это означает

Нельзя прочитать то, чего нет.

medium
easy