Генерация случайных целых чисел в JavaScript в определенном диапазоне? - PullRequest
1735 голосов
/ 07 октября 2009

Как я могу генерировать случайные целые числа между двумя указанными переменными в JavaScript, например x = 4 и y = 8 будут выводить любой из 4, 5, 6, 7, 8?

Ответы [ 29 ]

3490 голосов
/ 07 октября 2009

На странице Mozilla Developer Network есть несколько примеров:

/**
 * Returns a random number between min (inclusive) and max (exclusive)
 */
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive).
 * The value is no lower than min (or the next integer greater than min
 * if min isn't an integer) and no greater than max (or the next integer
 * lower than max if max isn't an integer).
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

Вот логика, стоящая за этим. Это простое правило трех:

Math.random() возвращает Number между 0 (включительно) и 1 (не включительно). Итак, у нас есть такой интервал:

[0 .................................... 1)

Теперь нам нужно число от min (включительно) до max (исключая):

[0 .................................... 1)
[min .................................. max)

Мы можем использовать Math.random, чтобы получить корреспондента в интервале [min, max). Но сначала мы должны немного учесть проблему, вычтя min из второго интервала:

[0 .................................... 1)
[min - min ............................ max - min)

Это дает:

[0 .................................... 1)
[0 .................................... max - min)

Теперь мы можем подать заявку Math.random и затем рассчитать корреспондента. Давайте выберем случайное число:

                Math.random()
                    |
[0 .................................... 1)
[0 .................................... max - min)
                    |
                    x (what we need)

Итак, чтобы найти x, мы сделаем:

x = Math.random() * (max - min);

Не забудьте добавить min назад, чтобы мы получили число в интервале [min, max):

x = Math.random() * (max - min) + min;

Это была первая функция из MDN. Второй возвращает целое число от min до max, оба включительно.

Теперь для получения целых чисел вы можете использовать round, ceil или floor.

Вы можете использовать Math.round(Math.random() * (max - min)) + min, однако это дает неравномерное распределение. И у min, и max есть только примерно половина шансов на бросок:

min...min+0.5...min+1...min+1.5   ...    max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘   ← Math.round()
   min          min+1                          max

Если исключить max из интервала, у него даже меньше шансов бросить, чем min.

С Math.floor(Math.random() * (max - min +1)) + min вы получаете идеально ровное распределение.

min.... min+1... min+2 ... max-1... max.... max+1 (is excluded from interval)
|        |        |         |        |        |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘   ← Math.floor()
   min     min+1               max-1    max

Вы не можете использовать ceil() и -1 в этом уравнении, потому что max теперь имел немного меньший шанс бросить, но вы также можете бросить (нежелательный) результат min-1.

494 голосов
/ 07 октября 2009
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
103 голосов
/ 25 марта 2015

Math.random ()

Из документации Mozilla для разработчиков:

// Returns a random integer between min (include) and max (include)

Math.floor(Math.random() * (max - min + 1)) + min;

Полезные примеры:

// 0 - 10
Math.floor(Math.random() * 11);

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

// 5 - 20
Math.floor(Math.random() * 16) + 5;

// -10 - (-2)
Math.floor(Math.random() * 9) - 10;
53 голосов
/ 07 октября 2009
function getRandomizer(bottom, top) {
    return function() {
        return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
    }
}

использование:

var rollDie = getRandomizer( 1, 6 );

var results = ""
for ( var i = 0; i<1000; i++ ) {
    results += rollDie() + " ";    //make a string filled with 1000 random numbers in the range 1-6.
}

разбивка:

Мы возвращаем функцию (заимствованную из функционального программирования), которая при вызове возвращает случайное целое число между значениями bottom и top включительно. Мы говорим «включительно», потому что хотим включить как нижнюю, так и верхнюю в диапазон чисел, которые могут быть возвращены. Таким образом, getRandomizer( 1, 6 ) вернет 1, 2, 3, 4, 5 или 6.

(нижнее - нижнее число, верхнее - большее число)

Math.random() * ( 1 + top - bottom )

Math.random() возвращает случайное двойное число от 0 до 1, и если мы умножим его на единицу плюс разница между top и bottom, мы получим двойное значение где-то между 0 и 1+b-a.

Math.floor( Math.random() * ( 1 + top - bottom ) )

Math.floor округляет число до ближайшего целого числа. Теперь у нас есть все целые числа от 0 до top-bottom. 1 выглядит сбивающим с толку, но он должен быть там, потому что мы всегда округляем, поэтому на самом деле верхнее число никогда не будет достигнуто без него. Случайный десятичный разряд, который мы генерируем, должен находиться в диапазоне от 0 до (1+top-bottom), чтобы мы могли округлить и получить целое число в диапазоне от 0 до top-bottom

Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom

Код в предыдущем примере дал нам целое число в диапазоне 0 и top-bottom, поэтому все, что нам нужно сделать сейчас, это добавить bottom к этому результату, чтобы получить целое число в диапазоне bottom и top включительно. : D


ПРИМЕЧАНИЕ. Если вы сначала передадите нецелое значение или большее число, вы получите нежелательное поведение, но если кто-то его не попросит, я не собираюсь углубляться в код проверки аргументов, поскольку он довольно далек от цели оригинальный вопрос.

29 голосов
/ 09 февраля 2013
function randomRange(min, max) {
  return ~~(Math.random() * (max - min + 1)) + min
}

Альтернатива, если вы используете Underscore.js вы можете использовать

_.random(min, max)
29 голосов
/ 28 марта 2014

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

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

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

Math.floor((Math.random()*100) + 1)
15 голосов
/ 02 октября 2017

Если вам нужна переменная от 0 до макс, вы можете использовать:

Math.floor(Math.random() *  max);
14 голосов
/ 21 июля 2014

Другие ответы не учитывают вполне разумные параметры 0 и 1. Вместо этого вы должны использовать round вместо из ceil или floor:

function randomNumber(minimum, maximum){
    return Math.round( Math.random() * (maximum - minimum) + minimum);
}

console.log(randomNumber(0,1));  # 0 1 1 0 1 0
console.log(randomNumber(5,6));  # 5 6 6 5 5 6
console.log(randomNumber(3,-1)); # 1 3 1 -1 -1 -1
11 голосов
/ 10 февраля 2013

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

Так что для таких людей вот мое предложение:

Генерация случайного числа с использованием Math.random(). (Произнесите это n)

Now for [0,10) ==>  n*10 (i.e. one digit) and for[10,100) ==> n*100 (i.e. two digits) and so on. Here squire bracket indicates that boundary is inclusive and round bracket indicates boundary is exclusive.
Then remove the rest after the decimal point. (i.e. get floor) - using Math.floor(), this can be done.

Если вы знаете, как читать таблицу случайных чисел, чтобы выбрать случайное число, вы знаете, что описанный выше процесс (умножение на 1, 10, 100 и т. Д.) Не нарушает тот, который я упоминал в начале (потому что он меняет только место десятичной точки.)

Изучите следующий пример и разработайте его для своих нужд.

Если вам нужен образец [0,9], то пол n * 10 - это ваш ответ, а если нужно [0,99], пол n * 100 - ваш ответ и т. Д.

Теперь позвольте войти в вашу роль:

Вы задали номера среди определенного диапазона. (В этом случае вы смещены в этом диапазоне. - Если взять число из [1,6], бросив кубик, то вы смещаетесь в [1,6], но все же это случайное значение, если и только если умирание непредвзято .)

Так что рассмотрите ваш диапазон ==> [78, 247] количество элементов диапазона = 247 - 78 + 1 = 170; (поскольку обе границы включительно.

/*Mthod 1:*/
    var i = 78, j = 247, k = 170, a = [], b = [], c, d, e, f, l = 0;
    for(; i <= j; i++){ a.push(i); }
    while(l < 170){
        c = Math.random()*100; c = Math.floor(c);
        d = Math.random()*100; d = Math.floor(d);
        b.push(a[c]); e = c + d;
        if((b.length != k) && (e < k)){  b.push(a[e]); }
        l = b.length;
    }
    console.log('Method 1:');
    console.log(b);
/*Method 2:*/

    var a, b, c, d = [], l = 0;
    while(l < 170){
        a = Math.random()*100; a = Math.floor(a);
        b = Math.random()*100; b = Math.floor(b);
        c = a + b;
        if(c <= 247 || c >= 78){ d.push(c); }else{ d.push(a); }
        l = d.length;
    }
    console.log('Method 2:');
    console.log(d);

Примечание. В первом методе я сначала создал массив, в котором содержатся нужные вам числа, а затем случайно поместил их в другой массив. Во втором методе генерируйте числа случайным образом и проверяйте, находятся ли они в нужном вам диапазоне. Затем поместите его в массив. Здесь я сгенерировал два случайных числа и использовал их общее количество, чтобы максимизировать скорость программы, сводя к минимуму частоту отказов при получении полезного числа. Однако добавление сгенерированных чисел также даст некоторую необъективность. Поэтому я бы порекомендовал мой первый метод для генерации случайных чисел в определенном диапазоне.

В обоих методах ваша консоль покажет результат. (Нажмите f12 в Chrome, чтобы открыть консоль)

11 голосов
/ 15 ноября 2016

Вот реализация MS DotNet класса Random в javascript-

var Random = (function () {
function Random(Seed) {
    if (!Seed) {
        Seed = this.milliseconds();
    }
    this.SeedArray = [];
    for (var i = 0; i < 56; i++)
        this.SeedArray.push(0);
    var num = (Seed == -2147483648) ? 2147483647 : Math.abs(Seed);
    var num2 = 161803398 - num;
    this.SeedArray[55] = num2;
    var num3 = 1;
    for (var i_1 = 1; i_1 < 55; i_1++) {
        var num4 = 21 * i_1 % 55;
        this.SeedArray[num4] = num3;
        num3 = num2 - num3;
        if (num3 < 0) {
            num3 += 2147483647;
        }
        num2 = this.SeedArray[num4];
    }
    for (var j = 1; j < 5; j++) {
        for (var k = 1; k < 56; k++) {
            this.SeedArray[k] -= this.SeedArray[1 + (k + 30) % 55];
            if (this.SeedArray[k] < 0) {
                this.SeedArray[k] += 2147483647;
            }
        }
    }
    this.inext = 0;
    this.inextp = 21;
    Seed = 1;
}
Random.prototype.milliseconds = function () {
    var str = new Date().valueOf().toString();
    return parseInt(str.substr(str.length - 6));
};
Random.prototype.InternalSample = function () {
    var num = this.inext;
    var num2 = this.inextp;
    if (++num >= 56) {
        num = 1;
    }
    if (++num2 >= 56) {
        num2 = 1;
    }
    var num3 = this.SeedArray[num] - this.SeedArray[num2];
    if (num3 == 2147483647) {
        num3--;
    }
    if (num3 < 0) {
        num3 += 2147483647;
    }
    this.SeedArray[num] = num3;
    this.inext = num;
    this.inextp = num2;
    return num3;
};
Random.prototype.Sample = function () {
    return this.InternalSample() * 4.6566128752457969E-10;
};
Random.prototype.GetSampleForLargeRange = function () {
    var num = this.InternalSample();
    var flag = this.InternalSample() % 2 == 0;
    if (flag) {
        num = -num;
    }
    var num2 = num;
    num2 += 2147483646.0;
    return num2 / 4294967293.0;
};
Random.prototype.Next = function (minValue, maxValue) {
    if (!minValue && !maxValue)
        return this.InternalSample();
    var num = maxValue - minValue;
    if (num <= 2147483647) {
        return parseInt((this.Sample() * num + minValue).toFixed(0));
    }
    return this.GetSampleForLargeRange() * num + minValue;
};
Random.prototype.NextDouble = function () {
    return this.Sample();
};
Random.prototype.NextBytes = function (buffer) {
    for (var i = 0; i < buffer.length; i++) {
        buffer[i] = this.InternalSample() % 256;
    }
};
return Random;
}());

Использование:

        var r = new Random();
        var nextInt = r.Next(1, 100); //returns an integer between range
        var nextDbl = r.NextDouble(); //returns a random decimal
...