Генерация случайного числа между двумя числами в JavaScript - PullRequest
1541 голосов
/ 10 февраля 2011

Есть ли способ создать случайное число в указанном диапазоне (например, от 1 до 6: 1, 2, 3, 4, 5 или 6) в JavaScript?

Ответы [ 16 ]

6 голосов
/ 30 апреля 2016

Пример

Возвращает случайное число от 1 до 10:

Math.floor((Math.random() * 10) + 1);

Результат может быть: 3

Попробуйте сами: здесь

-

или с использованием lodash / undescore:

_.random(min, max)

Документы: - lodash - undescore

5 голосов
/ 15 января 2017

Несмотря на множество ответов и почти одинаковый результат.Я хотел бы добавить свой ответ и объяснить его работу.Потому что важно понимать его работу, а не копировать вставку однострочного кода.Генерация случайных чисел - не что иное, как простая математика.

КОД:

function getR(lower, upper) {

  var percent = (Math.random() * 100);
  // this will return number between 0-99 because Math.random returns decimal number from 0-0.9929292 something like that
  //now you have a percentage, use it find out the number between your INTERVAL :upper-lower 
  var num = ((percent * (upper - lower) / 100));
  //num will now have a number that falls in your INTERVAL simple maths
  num += lower;
  //add lower to make it fall in your INTERVAL
  //but num is still in decimal
  //use Math.floor>downward to its nearest integer you won't get upper value ever
  //use Math.ceil>upward to its nearest integer upper value is possible
  //Math.round>to its nearest integer 2.4>2 2.5>3   both lower and upper value possible
  console.log(Math.floor(num), Math.ceil(num), Math.round(num));
}
4 голосов
/ 07 сентября 2014

Я искал генератор случайных чисел, написанный на TypeScript, и написал это после прочтения всех ответов, надеюсь, он будет работать для кодировщиков TypeScript.

    Rand(min: number, max: number): number {
        return (Math.random() * (max - min + 1) | 0) + min;
    }   
3 голосов
/ 13 февраля 2019

Добавление float с версией фиксированной точности на основе версии int в ответе @ Francisc:

function randomFloatFromInterval (min, max, fractionDigits) {
  const fractionMultiplier = Math.pow(10, fractionDigits)
  return Math.round(
    (Math.random() * (max - min) + min) * fractionMultiplier,
  ) / fractionMultiplier
}

так:

randomFloatFromInterval(1,3,4) // => 2.2679, 1.509, 1.8863, 2.9741, ...

и для ответа int

randomFloatFromInterval(1,3,0) // => 1, 2, 3
1 голос
/ 10 апреля 2016

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

В таких случаях мы можем использовать crypto.getRandomValues() для генерации безопасных целых чисел и отклонения любых сгенерированных значений, которые мы не можем равномерно отобразить в целевой диапазон. Это будет медленнее, но не должно быть значительным, если вы не генерируете очень большое количество значений.

Чтобы прояснить проблему смещения распределения, рассмотрим случай, когда мы хотим сгенерировать значение от 1 до 5, но у нас есть генератор случайных чисел, который выдает значения от 1 до 16 (4-битное значение). Мы хотим иметь одинаковое количество сгенерированных значений, сопоставляемых с каждым выходным значением, но 16 не делится поровну на 5: остается остаток от 1. Поэтому нам нужно отклонить 1 из возможных сгенерированных значений и продолжить только тогда, когда мы получим одно из 15 меньших значений, которые могут быть равномерно отображены в нашем целевом диапазоне. Наше поведение может выглядеть следующим образом:

Generate a 4-bit integer in the range 1-16.
If we generated  1,  6, or 11 then output 1.
If we generated  2,  7, or 12 then output 2.
If we generated  3,  8, or 13 then output 3.
If we generated  4,  9, or 14 then output 4.
If we generated  5, 10, or 15 then output 5.
If we generated 16 then reject it and try again.

В следующем коде используется аналогичная логика, но вместо этого генерируется 32-разрядное целое число, поскольку это самый большой общий размер целого числа, который может быть представлен стандартным типом JavaScript number. (Это можно изменить, чтобы использовать BigInt s, если вам нужен больший диапазон.) Независимо от выбранного диапазона, доля сгенерированных значений, которые отклоняются, всегда будет меньше 0,5, поэтому ожидаемое количество отклонений всегда будет меньше чем 1,0 и обычно близко к 0,0; вам не нужно беспокоиться о том, что оно зациклится навсегда.

const randomInteger = (min, max) => {
  const range = max - min;
  const maxGeneratedValue = 0xFFFFFFFF;
  const possibleResultValues = range + 1;
  const possibleGeneratedValues = maxGeneratedValue + 1;
  const remainder = possibleGeneratedValues % possibleResultValues;
  const maxUnbiased = maxGeneratedValue - remainder;

  if (!Number.isInteger(min) || !Number.isInteger(max) ||
       max > Number.MAX_SAFE_INTEGER || min < Number.MIN_SAFE_INTEGER) {
    throw new Error('Arguments must be safe integers.');
  } else if (range > maxGeneratedValue) {
    throw new Error(`Range of ${range} (from ${min} to ${max}) > ${maxGeneratedValue}.`);
  } else if (max < min) {
    throw new Error(`max (${max}) must be >= min (${min}).`);
  } else if (min === max) {
    return min;
  } 

  let generated;
  do {
    generated = crypto.getRandomValues(new Uint32Array(1))[0];
  } while (generated > maxUnbiased);

  return min + (generated % possibleResultValues);
};

console.log(randomInteger(-8, 8));          // -2
console.log(randomInteger(0, 0));           // 0
console.log(randomInteger(0, 0xFFFFFFFF));  // 944450079
console.log(randomInteger(-1, 0xFFFFFFFF));
// Error: Range of 4294967296 covering -1 to 4294967295 is > 4294967295.
console.log(new Array(12).fill().map(n => randomInteger(8, 12)));
// [11, 8, 8, 11, 10, 8, 8, 12, 12, 12, 9, 9]
0 голосов
/ 22 февраля 2014

Я обнаружил, что вышеупомянутое решение Франциска не включает в результаты число min или max, поэтому я изменил его следующим образом:

function randomInt(min,max)
{
    return Math.floor(Math.random()*(max-(min+1))+(min+1));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...