Avatar ·

Как сгенерировать случайное целое число в заданном диапазоне на JavaScript?

Всем привет! Я новичок в JavaScript и никак не могу разобраться с генерацией случайных целых чисел в определённом диапазоне. Знаю про функцию Math.random(), которая возвращает случайное число от 0 (включительно) до 1 (не включительно). Но мне нужно получать целые числа, например, от 5 до 10 включительно. Я пробовал писать такой код:
function getRandomNumber(min, max) {
  return Math.floor(Math.random() * max) + min;
}
Но он работает неправильно: иногда выдаёт числа больше max, а иногда — меньше min. Например, при вызове getRandomNumber(5, 10) я получал 14 или 3. В чём моя ошибка? Как правильно написать функцию, которая будет возвращать случайное целое число в диапазоне [min, max] (включая обе границы)? Буду благодарен за подробное объяснение с рабочими примерами. Заранее спасибо! <<>>

Правильный способ генерации случайного целого числа в диапазоне

Ваша ошибка в том, что вы умножаете Math.random() только на max, не учитывая разницу между max и min. Правильная формула выглядит так:

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

Давайте разберём, как это работает по шагам:

  • Math.random() — возвращает число от 0 (включительно) до 1 (исключительно).
  • (max - min + 1) — вычисляет количество целых чисел в диапазоне. Например, для [5, 10] это 10 - 5 + 1 = 6 чисел (5,6,7,8,9,10).
  • Math.random() * (max - min + 1) — даёт число от 0 до 5.999... (не включая 6).
  • Math.floor(...) — округляет вниз до целого, получаем 0,1,2,3,4 или 5.
  • + min — сдвигает диапазон, получаем 5,6,7,8,9 или 10.

Вот несколько примеров использования:

// Случайное число от 1 до 10
console.log(getRandomInt(1, 10)); // может вывести 3, 7, 10 и т.д.

// Случайное число от -5 до 5
console.log(getRandomInt(-5, 5)); // может вывести -2, 0, 4 и т.д.

// Бросок кубика (1-6)
function rollDice() {
  return getRandomInt(1, 6);
}
console.log(`Выпало: ${rollDice()}`);

Важное замечание: не путайте эту функцию с Math.round(). Если использовать Math.round() вместо Math.floor(), граничные значения (min и max) будут иметь вдвое меньшую вероятность выпадения, что нарушит равномерность распределения.

Для более продвинутых случаев (криптографическая стойкость) используйте crypto.getRandomValues():

function secureRandomInt(min, max) {
  const range = max - min + 1;
  const bytes = new Uint32Array(1);
  crypto.getRandomValues(bytes);
  return (bytes[0] % range) + min;
}

Эта функция подходит для генерации паролей или токенов, где важна непредсказуемость. Обычный Math.random() не является криптостойким.

<<>>

Альтернативный подход с использованием Math.round()

Хотя основной метод с Math.floor() является стандартом, некоторые разработчики предпочитают использовать Math.round() для более интуитивного кода:

function getRandomIntRound(min, max) {
  return Math.round(Math.random() * (max - min)) + min;
}

Однако у этого подхода есть существенный недостаток: граничные значения (min и max) выпадают с вероятностью в два раза меньшей, чем все остальные числа. Это происходит потому, что Math.round() округляет к ближайшему целому, и числа, попадающие в интервал [min - 0.5, min + 0.5), дают min, а для остальных чисел интервал шире.

Поэтому я рекомендую всегда использовать первый вариант с Math.floor(). Если вам нужно включить обе границы с равной вероятностью — это единственный правильный способ.

Для простых случаев (когда точное распределение не критично) можно использовать короткую запись:

const rand = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
console.log(rand(1, 100)); // случайное число от 1 до 100