Как сгенерировать случайное число в заданном диапазоне в JavaScript?
function getRandomNumber(min, max) {
return Math.random() * max;
}
// Возвращает число от 0 до max, но не от min
Потом я подумал добавить min:
function getRandomNumber(min, max) {
return Math.random() * max + min;
}
// Теперь числа от min до min+max, а не от min до max
В общем, ничего не работает как надо. Подскажите, как правильно сгенерировать случайное число между двумя заданными числами? Нужно, чтобы можно было указать любые min и max, и чтобы результат был целым числом (без десятичных знаков). Буду благодарен за простой пример!
<<Правильный способ генерации случайного числа в диапазоне
Ваша интуиция была близка к правильному решению, но нужно учесть одну важную деталь: Math.random() возвращает число от 0 (включительно) до 1 (исключительно). Чтобы получить число в диапазоне от min до max, сначала нужно вычислить длину этого диапазона (max - min), умножить на неё результат Math.random(), а затем прибавить min.
Базовая формула для дробных чисел
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
Эта функция вернёт случайное дробное число от min (включительно) до max (исключительно). Например, getRandomArbitrary(5, 15) может вернуть 7.3421, 12.8903 или 5.0000, но никогда не вернёт 15.0000.
Как получить целое число
Если вам нужно целое число (как в вашем примере от 5 до 15 включительно), используйте Math.floor(). Важно: нужно увеличить диапазон на 1, чтобы max тоже мог выпасть:
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Разберём по шагам на примере getRandomInt(5, 15):
- Шаг 1:
Math.random()даёт число от 0 до 0.999... - Шаг 2: Умножаем на
(15 - 5 + 1) = 11. Получаем число от 0 до 10.999... - Шаг 3:
Math.floor()округляет вниз, давая целые числа от 0 до 10. - Шаг 4: Прибавляем
min = 5. Итог: числа от 5 до 15.
Важные замечания
- Округление: Всегда используйте
Math.floor(), а неMath.round().Math.round()нарушит равномерность распределения — крайние значения будут выпадать реже. - Типы данных: Если
minилиmaxмогут быть дробными, применитеMath.ceil(min)иMath.floor(max)для корректной работы. - Проверка: Убедитесь, что
min <= max, иначе функция вернётNaN.
Полный рабочий пример
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Тестируем
console.log(getRandomInt(5, 15)); // 7
console.log(getRandomInt(5, 15)); // 15
console.log(getRandomInt(5, 15)); // 5
Эта функция — стандартное и проверенное решение, которое используется миллионами разработчиков по всему миру. Она гарантирует равномерное распределение и включение обоих границ диапазона.
<<Альтернативный подход: использование Math.round() с осторожностью
Некоторые разработчики предпочитают использовать Math.round() вместо Math.floor(). Это работает, но требует другой формулы:
function getRandomIntRound(min, max) {
return Math.round(Math.random() * (max - min)) + min;
}
Как это работает: Math.random() * (max - min) даёт число от 0 до max - min. После округления и прибавления min получаем целые числа от min до max.
Недостаток: Крайние значения (min и max) выпадают примерно в два раза реже, чем остальные числа. Это происходит из-за особенностей округления: например, чтобы получить 5, нужно, чтобы случайное число попало в диапазон от 4.5 до 5.4, а для 6 — от 5.5 до 6.4. Диапазон для крайних значений уже, поэтому они менее вероятны.
Когда использовать: Если вам не нужно строго равномерное распределение (например, для простых игр или визуальных эффектов), этот метод проще для запоминания. Для серьёзных задач (статистика, криптография) используйте первый вариант с Math.floor().
Бонус: генерация случайного числа с плавающей точкой
Если вам нужно дробное число в диапазоне (включая оба конца), используйте:
function getRandomInclusive(min, max) {
return Math.random() * (max - min) + min;
}
// Пример: getRandomInclusive(1.5, 3.5) → 2.7891
Эта функция не включает max (из-за природы Math.random()), но для практических задач это редко имеет значение.