Как сгенерировать случайное целое число в заданном диапазоне в JavaScript?
Правильный способ генерации случайного целого числа в диапазоне
Ваша ошибка в том, что вы используете Math.round() и не учитываете минимальное значение. Давайте разберемся по шагам, как это работает правильно.
Почему ваш код не работает?
Math.random() возвращает число от 0 (включительно) до 1 (исключительно). Если умножить на 10, получим от 0 до 9.999... Math.round() округлит до ближайшего целого, и:
- 0–0.499 → 0 (нежелательно, если min=1)
- 9.5–9.999 → 10 (хорошо)
- Но при умножении на 10, 10 никогда не выпадет, так как 1 не включено. А 0 выпадает с вероятностью ~5%
Правильное решение: Math.floor + формула
Стандартный и самый надежный способ — использовать Math.floor() и следующую формулу:
Math.floor(Math.random() * (max - min + 1)) + min
Разберем на примере: min=1, max=10
// (max - min + 1) = 10 - 1 + 1 = 10
// Math.random() * 10 → от 0 до 9.999...
// Math.floor() → от 0 до 9
// + min (1) → от 1 до 10
Готовая функция
function getRandomInt(min, max) {
min = Math.ceil(min); // Округляем min вверх
max = Math.floor(max); // Округляем max вниз
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Примеры использования:
console.log(getRandomInt(1, 10)); // 1–10
console.log(getRandomInt(5, 15)); // 5–15
console.log(getRandomInt(-5, 5)); // -5–5
Почему Math.floor, а не Math.round?
Math.floorдает равномерное распределение — каждое число выпадает с одинаковой вероятностьюMath.roundискажает вероятности: крайние числа (min и max) выпадают в 2 раза реже, чем остальные
Вариант для дробных чисел
Если вам нужны случайные дробные числа в диапазоне (не обязательно целые):
function getRandomFloat(min, max) {
return Math.random() * (max - min) + min;
}
// Пример: getRandomFloat(1.5, 5.5) → 1.5–5.5
Краткое резюме
- Для целых чисел:
Math.floor(Math.random() * (max - min + 1)) + min - Для дробных:
Math.random() * (max - min) + min - Всегда проверяйте, что min меньше max
- Не используйте
Math.round()— это нарушает равномерность распределения
Эта функция отлично подойдет для вашей игры "угадай число" и любых других задач, где нужны случайные целые числа.
<<Альтернативный подход: использование Math.random с parseInt
Некоторые разработчики предпочитают использовать parseInt() вместо Math.floor() для преобразования результата в целое число:
function randomInt(min, max) {
return parseInt(Math.random() * (max - min + 1)) + min;
}
Это работает, потому что parseInt() отбрасывает дробную часть, аналогично Math.floor() для положительных чисел. Однако есть нюанс: если min или max могут быть отрицательными, parseInt ведет себя иначе, чем Math.floor (например, parseInt(-0.5) дает -0, а Math.floor(-0.5) дает -1). Поэтому для отрицательных диапазонов лучше использовать Math.floor.
Дополнение: проверка границ
Для надежности добавьте проверку, что min меньше max:
function randomIntSafe(min, max) {
if (min > max) [min, max] = [max, min]; // меняем местами
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Этот вариант полезен, когда вы не уверены, в каком порядке передаются аргументы. Также можно добавить проверку на нечисловые значения с помощью typeof или isNaN().