Генерация случайных целых чисел в JavaScript в определенном диапазоне?

1955

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

zacharyliu
источник
1
вот полезная суть: gist.github.com/kerimdzhanov/7529623
Дан К.К.
9
В качестве примечания: для тех, кто использует npm и ищет быстрое, надежное и готовое решение, есть lodash.random, который можно легко потребовать с очень маленьким размером (он импортирует только сам метод, а не весь lodash).
Нобита
если он должен быть криптобезопасным developer.mozilla.org/en-US/docs/Web/API/RandomSource/…
счастливого

Ответы:

3835

На странице 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результат.

Ionuț G. Stan
источник
10
Он делает это только потому, что звонит floor, округляя.
Джош Стодола
4
@ thezachperson31 Вы могли бы использовать round, но тогда и то, minи другое, и maxтолько половина шансов катиться, как и другие числа. Вы также можете вычесть один и взять ceil. Это, однако, оставляет maxчисло с минимальным шансом на бросок из-за [0,1)интервала.
Кристоф
12
Я создал JSFiddle, если кто-то хочет протестировать распространение этого метода: jsfiddle.net/F9UTG/1
Ahren
8
@JackFrost, да, все верно. Ты не тупой, ты только учишься :)
Ionuț G. Stan
3
Этот вопрос старый, но понимание этого ответа у меня ушло слишком много времени , Оо, я думаю , что расширение Math.random на следующей версии JavaScript будет полезен вид
Jonathan Ortega
527
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
Дарин димитров
источник
19
Я знаю, что это ОЧЕНЬ старый ответ, но использование (Math.random() * (maximum - minimum + 1) ) << 0быстрее.
Исмаэль Мигель
11
@IsmaelMiguel Использование бинарных операторов ( x << 0, x | 0, ~~x) вместо Math.floor()обращенных xв два-комплемента с гораздо меньшим диапазоном , чем Number.MAX_SAFE_INTEGER(2³²⁻¹ против 2⁵³), таким образом , вы должны использовать его с осторожностью!
le_m
@IsmaelMiguel Yo Я только что попробовал ваш метод в консоли и случайно получил отрицательное значение! Math.randRange = (минимум, максимум) => (Math.random () * (максимум - минимум + 1)) << 0 Math.randRange (2,657348096152) -1407373159
bluejayke
@bluejayke Потому что 657348096152 (1001100100001100111111111111000010011000 в двоичном формате) имеет 40 бит, в то время как побитовая арифметика использует 32 бита. Если вы 657348096152|0получите 218099864 (1100111111111111000010011000 в двоичном формате).
Исмаэль Мигель
1
Это умный ответ. Внутренний диапазон [min, max + 1) фактически дает желаемый результат, когда [min, max] включительно. Спасибо! :)
Младен Б.
135

Math.random ()

Возвращает случайное целое число между min ( включенным ) и max ( включенным ):

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

Или любое случайное число между min ( включено ) и max ( не включено ):

function randomNumber(min, max) {
  return Math.random() * (max - min) + 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;

** И всегда приятно напоминать (Мозилла):

Math.random () не предоставляет криптографически безопасных случайных чисел. Не используйте их для чего-либо, связанного с безопасностью. Вместо этого используйте API Web Crypto, а точнее метод window.crypto.getRandomValues ​​().

Лиор Элром
источник
56
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) так мы можем округлить и получить Int в диапазоне 0доtop-bottom

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

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


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

Гордон Густафсон
источник
1
Я понимаю, что это примерно через 2,5 года, но с входными данными 1 и 6 ваша функция возвращает значения 1,2,3,4 и 5, но никогда не 6, как это было бы, если бы оно было «включительно».
некоторые
9
@ Иногда, могло быть и хуже, мне 2,5 года + 1 день спустя ^^
ajax333221
+1, я проверил ваш код, похоже, для создания правильного значения. Креативная структура для обработки фиксированных сценариев, которые могут многократно повторяться в коде.
Крис
Почему у вас есть функция внутри функции для этого?
Alph.Dev
1
@ Alph.Dev Чтобы отделить логику, которая использует генератор случайных чисел, от логики, которая решает, какое именно распределение случайных чисел использовать. Когда код, использующий генератор случайных чисел, принимает его в качестве параметра (функция с 0 аргументами, которая всегда возвращает новое случайное число), он может работать с любым видом генератора случайных чисел.
Гордон Густафсон
31
function randomRange(min, max) {
  return ~~(Math.random() * (max - min + 1)) + min
}

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

_.random(min, max)
Codler
источник
1
Underscore фактически предоставляет _.uniqueId()функцию, которую вы можете вызывать для моделей на стороне клиента.
Обфк
Использование бинарных операторов ( x << 0, x | 0, ~~x) вместо Math.floor()обращенных xв два-комплемент с гораздо меньшим диапазоном , чем Number.MAX_SAFE_INTEGER(2³²⁻¹ против 2⁵³), таким образом , вы должны использовать его с осторожностью!
le_m
31

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

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

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

Math.floor((Math.random()*100) + 1)
Prasobh.Kollattu
источник
ваше "между" включительно или эксклюзивно? то есть это [1,10], [1,10), (1,10] или (1,10)?
evandrix
1
Частично включительно: [1, *)
Иван З
зачем нужен +1 в конце функции? Это прекрасно работает, я думаю.
Шачи
18

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

Math.floor(Math.random() *  max);
Станислав Винсент
источник
Максимально включено или эксклюзивно>?
Дерево
2
@Tree с использованием Math.floor max является эксклюзивным. Если вы хотите, чтобы max был включительно, вы можете использовать Math.round.
Лука
14

Другие ответы не учитывают вполне разумные параметры 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
помешанный
источник
1
Ваш ответ верен, но я думаю, что ваш пример неверен. console.log(randomNumber(5,6)); # 9 6 6 5 7 79 и 7 находятся между 5 и 6? ...... Вы должны исправить это или объяснить ..
Сачин
12

Вот реализация MS DotNet случайного класса в 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
Бешеный ислам
источник
Класс MS DotNet Random находится под лицензией Ms-RSL , что означает, что он защищен авторским правом. Поэтому будьте осторожны при использовании этого производного кода, так как он может стать основанием для случаев нарушения авторских прав.
JohannesB
12

Используйте эту функцию, чтобы получить случайные числа между заданным диапазоном

function rnd(min,max){
    return Math.floor(Math.random()*(max-min+1)+min );
}
оборота Айлиан Краспа
источник
10

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

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

Генерация случайного числа с помощью 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, чтобы открыть консоль)

Джанака Р Раджапакша
источник
3
«случайный» не обязательно означает «равномерно распределенный». «предвзятый» не означает «неслучайный». случайные средства, взятые из распределения вероятностей.
syzygy
6
Едва могу сказать, что этот ответ пытается сказать. Однако, если вам нужны случайные числа для таких целей, как номера лотереи и азартных игр. Во-первых, вы, вероятно, не должны генерировать их на клиенте. Во-вторых, вам нужен криптографически безопасный генератор случайных чисел, и предоставленного алгоритма недостаточно. Повторный вызов random не делает результат «более случайным». Автор, похоже, обеспокоен предвзятостью, но не дает хорошего алгоритма для его предотвращения. Фактически, другие короткие ответы дают непредвзятые случайные числа (при условии, что основной генератор случайных чисел несмещен).
Джефф Уокер Код Рейнджер
@JeffWalkerCodeRanger Я думаю, что он имел в виду, что при «нормальном» алгоритме [т.е. Math.floor(Math.random() * (6 - 1 + 1) + 1)] числа 1 и 6 обязательно будут прокручиваться меньше, чем 2, 3, 4 и 5. Однако разница в принципе незначительна.
oldboy
10

Для случайного целого числа с диапазоном попробуйте:

function random(minimum, maximum) {
  var bool = true;

  while (bool) {
    var number = (Math.floor(Math.random() * maximum + 1) + minimum);
    if (number > 20) {
      bool = true;
    } else {
      bool = false;
    }
  }

  return number;
}
user1764199
источник
8
function getRandomInt(lower, upper)
{
    //to create an even sample distribution
    return Math.floor(lower + (Math.random() * (upper - lower + 1)));

    //to produce an uneven sample distribution
    //return Math.round(lower + (Math.random() * (upper - lower)));

    //to exclude the max value from the possible values
    //return Math.floor(lower + (Math.random() * (upper - lower)));
}

Чтобы проверить эту функцию и ее варианты, сохраните приведенный ниже HTML / JavaScript в файл и откройте его в браузере. Код создаст график, показывающий распределение одного миллиона вызовов функций. Код также будет записывать крайние случаи, поэтому, если функция выдает значение, превышающее максимальное или меньшее, чем минимальное, you.will.know.about.it.

<html>
    <head>
        <script type="text/javascript">
        function getRandomInt(lower, upper)
        {
            //to create an even sample distribution
            return Math.floor(lower + (Math.random() * (upper - lower + 1)));

            //to produce an uneven sample distribution
            //return Math.round(lower + (Math.random() * (upper - lower)));

            //to exclude the max value from the possible values
            //return Math.floor(lower + (Math.random() * (upper - lower)));
        }

        var min = -5;
        var max = 5;

        var array = new Array();

        for(var i = 0; i <= (max - min) + 2; i++) {
          array.push(0);
        }

        for(var i = 0; i < 1000000; i++) {
            var random = getRandomInt(min, max);
            array[random - min + 1]++;
        }

        var maxSample = 0;
        for(var i = 0; i < max - min; i++) {
            maxSample = Math.max(maxSample, array[i]);
        }

        //create a bar graph to show the sample distribution
        var maxHeight = 500;
        for(var i = 0; i <= (max - min) + 2; i++) {
            var sampleHeight = (array[i]/maxSample) * maxHeight;

            document.write('<span style="display:inline-block;color:'+(sampleHeight == 0 ? 'black' : 'white')+';background-color:black;height:'+sampleHeight+'px">&nbsp;[' + (i + min - 1) + ']:&nbsp;'+array[i]+'</span>&nbsp;&nbsp;');
        }
        document.write('<hr/>');
        </script>
    </head>
    <body>

    </body>
</html>
Крис
источник
7

Чтобы получить случайное число, скажем, от 1 до 6, сначала выполните:

    0.5 + (Math.random() * ((6 - 1) + 1))

Это умножает случайное число на 6, а затем добавляет к нему 0,5. Затем округлите число до положительного целого числа, выполнив:

    Math.round(0.5 + (Math.random() * ((6 - 1) + 1))

Это округляет число до ближайшего целого числа.

Или, чтобы сделать это более понятным, сделайте это:

    var value = 0.5 + (Math.random() * ((6 - 1) + 1))
    var roll = Math.round(value);
    return roll;

В общем, код для этого с использованием переменных:

    var value = (Min - 0.5) + (Math.random() * ((Max - Min) + 1))
    var roll = Math.round(value);
    return roll;

Причина удаления 0,5 от минимального значения состоит в том, что использование только минимального значения позволит вам получить целое число, которое на единицу больше вашего максимального значения. Убирая 0,5 от минимального значения, вы существенно препятствуете округлению максимального значения.

Надеюсь, это поможет.

Learner.js
источник
Имеет смысл, если вы исключаете 0 , тогда нет необходимости «округлять» диапазон от 0 до 0,5.
ILMostro_7
7

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

function genRandomNumber(how_many_number,min,max) {

            // parameters
            // how_many_number : how many numbers you want to generate. For example it is 5.
            // min(inclusive) : minimum/low value of a range. it must be any positive integer but less than max. i.e 4
            // max(inclusive) : maximun value of a range. it must be any positive integer. i.e 50
            // return type: array

            var random_number = [];
            for (var i = 0; i < how_many_number; i++) {
                var gen_num = parseInt((Math.random() * (max-min+1)) + min);
                do {
                    var is_exist = random_number.indexOf(gen_num);
                    if (is_exist >= 0) {
                        gen_num = parseInt((Math.random() * (max-min+1)) + min);
                    }
                    else {
                        random_number.push(gen_num);
                        is_exist = -2;
                    }
                }
                while (is_exist > -1);
            }
            document.getElementById('box').innerHTML = random_number;
        }
Юсуф
источник
7

Я знаю, что на этот вопрос уже дан ответ, но мой ответ может кому-то помочь.

Я нашел этот простой метод в W3Schools:

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

Надеюсь, это поможет кому-то.

Щелкунчик
источник
1
Math.floor ((Math.random () * 1) + 0); всегда дает 0
madprops
1
@madprops Потому что максимальное количество является эксклюзивным. Чтобы получить 0 или 1, вы должны установить 2 как максимальное число.
NutCracker
1
или вы просто добавляете +1 в функцию, которая вызывает этот метод
Пьетро Коэльо
6

Случайное целое число между самым низким и самым высоким:

function randomRange(l,h){
  var range = (h-l);
  var random = Math.floor(Math.random()*range);
  if (random === 0){random+=1;}
  return l+random;
}

Не самое элегантное решение .. но что-то быстрое.

brooklynsweb
источник
5

Вот что я использую для генерации случайных чисел.

function random(high,low) {
    high++;
    return Math.floor((Math.random())*(high-low))+low;
}

Мы выполняем, high++потому что Math.random()генерирует случайное число от 0 (включительно) до 1 (исключая). Исключение означает, что мы должны увеличить максимум на единицу перед выполнением любой математики. Затем мы вычитаем низкий из высокого, давая нам наибольшее число для генерации - низкий, затем + низкий, возвращая высокий уровень к норме и делая самое низкое число по крайней мере низким. тогда мы возвращаем полученное число

random(7,3) мог вернуться 3,4,5,6, or 7

Travis
источник
2
Так highкак он используется только один раз, вы можете использовать high-low+1вместо него отдельный оператор приращения. Кроме того, большинство пользователей ожидают, что lowпараметр будет первым.
Крис Уолш
4
    <!DOCTYPE html>
<html>
    <head>
            <meta charset="utf-8" />
    </head>
    <body>
        <script>
            /*

                assuming that window.crypto.getRandomValues is available
                the real range would be fron 0 to 1,998 instead of 0 to 2,000
                See javascript documentation for explanation
                https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues
            */
            var array = new Uint8Array(2);
            window.crypto.getRandomValues(array);
            console.log(array[0] + array[1]);

        </script>
    </body>
</html>

Uint8Array создайте массив, заполненный числом до 3 цифр, которое будет максимум 999. Этот код очень короткий.

счастливый
источник
4

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

    function genRandom(length)
    {
     const t1 = new Date().getMilliseconds();
     var min = "1",max = "9";
     var result;
     var numLength = length;
     if (numLength != 0)
     {
        for (var i = 1; i < numLength; i++)
        {
           min = min.toString() + "0";
           max = max.toString() + "9";
        }
     } 
     else
     {
        min = 0;
        max = 0;
        return; 
     }

      for (var i = min; i <= max; i++)
      {
           //Empty Loop
      }

      const t2 = new Date().getMilliseconds();
      console.log(t2);
      result = ((max - min)*t1)/t2;
      console.log(result);
      return result;
    }
Нилеш Павар
источник
t1 / t2 всегда очень близко к 1. и, следовательно, ваша функция возвращает одно и то же число при повторном вызове
Sunil BN
проверьте URL-адрес jsbin .. вы сами увидите результат
Sunil BN
Он отлично работает, когда длина составляет от 4 до 10 (как я проверял на моей машине), потому что значения констант T1 и T2 должны иметь соответствующее расстояние.
Нилеш Павар
3

это мое взятие случайного числа в диапазоне, так как я хотел получить случайное число в диапазоне от основания до показателя степени. например, base = 10, exponent = 2, дает случайное число от 0 до 100, в идеале и так далее.

если это помогает использовать это, вот оно:

// get random number within provided base + exponent
// by Goran Biljetina --> 2012

function isEmpty(value){
    return (typeof value === "undefined" || value === null);
}
var numSeq = new Array();
function add(num,seq){
    var toAdd = new Object();
     toAdd.num = num;
     toAdd.seq = seq;
     numSeq[numSeq.length] = toAdd;
}
function fillNumSeq (num,seq){
    var n;
    for(i=0;i<=seq;i++){
        n = Math.pow(num,i);
        add(n,i);
    }
}
function getRandNum(base,exp){
    if (isEmpty(base)){
        console.log("Specify value for base parameter");
    }
    if (isEmpty(exp)){
        console.log("Specify value for exponent parameter");
    }
    fillNumSeq(base,exp);
    var emax;
    var eseq;
    var nseed;
    var nspan;
    emax = (numSeq.length);
    eseq = Math.floor(Math.random()*emax)+1;
    nseed = numSeq[eseq].num;
    nspan = Math.floor((Math.random())*(Math.random()*nseed))+1;
    return Math.floor(Math.random()*nspan)+1;
}

console.log(getRandNum(10,20),numSeq);
//testing:
//getRandNum(-10,20);
//console.log(getRandNum(-10,20),numSeq);
//console.log(numSeq);
Горан Б.
источник
3

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-разрядное целое число, поскольку это самый большой общий целочисленный размер, который может быть представлен стандартным numberтипом JavaScript . (Это можно изменить, чтобы использовать BigInts, если вам нужен больший диапазон.) Независимо от выбранного диапазона, доля сгенерированных значений, которые отклоняются, всегда будет меньше 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]

Джереми Бэнкс
источник
3

Crypto-Strong

Чтобы получить крипто-сильное случайное целое число в ragne [x, y], попробуйте

let cs= (x,y)=>x+(y-x+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0

console.log(cs(4,8))

Камил Келчевски
источник
4
этот увлекателен
Akin Hwan,
1

Вы можете этот фрагмент кода,

let randomNumber = function(first,second){
let number = Math.floor(Math.random()*Math.floor(second));
while(number<first){

    number = Math.floor(Math.random()*Math.floor(second));
}
return number;
}
Ахинта Исуру
источник
1
Здесь есть ненужная дублирующаяся строка. Просто используйте do - whileвместоwhile
Хави Марзан
1

Пусть Г. Стэн написал отличный ответ, но он был слишком сложным для меня, чтобы понять. Итак, я нашел еще более простое объяснение тех же понятий на https://teamtreehouse.com/community/mathfloor-mathrandom-max-min-1-min-explanation Джейсоном Анелло.

ПРИМЕЧАНИЕ . Единственная важная вещь, которую вы должны знать, прежде чем читать объяснение Джейсона, - это определение «усечь». Он использует этот термин при описании Math.floor(). Оксфордский словарь определяет «усечение» как:

Укоротить (что-то), отрезав верх или конец.

Дани Амсалем
источник
0

Это может обрабатывать генерацию до 20 цифр уникального случайного числа

JS

var generatedNumbers = [];

function generateRandomNumber(precision) { // precision --> number precision in integer 
    if (precision <= 20) {
        var randomNum = Math.round(Math.random().toFixed(precision) * Math.pow(10, precision));
        if (generatedNumbers.indexOf(randomNum) > -1) {
            if (generatedNumbers.length == Math.pow(10, precision))
                return "Generated all values with this precision";
                return generateRandomNumber(precision);
        } else {
            generatedNumbers.push(randomNum);
            return randomNum;
        }
    } else
       return "Number Precision shoould not exceed 20";
}
generateRandomNumber(1);

введите описание изображения здесь

JsFiddle

NOFI
источник
Я голосую за это только потому, что.
Тейлор Экли
1
@TaylorAckley Этот ответ не касается вопроса.
RomainValeri
0

/ * Написать функцию с именем, randUpToкоторая принимает число и возвращает случайное целое число от 0 до этого числа? * /

var randUpTo = function(num) {
    return Math.floor(Math.random() * (num - 1) + 0);
};

/ * Напишите вызываемую функцию, randBetweenкоторая принимает два числа, представляющих диапазон, и возвращает случайное целое число между этими двумя числами. * /

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

/ * Напишите вызываемую функцию, randFromTillкоторая принимает два числа, представляющих диапазон, и возвращает случайное число между min (включительно) и max (эксклюзивом). * /

var randFromTill = function (min, max) {
    return Math.random() * (max - min) + min;
};

/ * Напишите вызываемую функцию, randFromToкоторая принимает два числа, представляющих диапазон, и возвращает случайное целое число между min (включительно) и max (включительно) * /

var randFromTo = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};
Прахар Миттал
источник
1
Прекрасно, не могли бы вы также заметить, что randBetween является (эксклюзивным) (эксклюзивным)?
pfdint
0

Я сделал эту функцию, которая учитывает такие параметры, как min, max, exclude (список целых чисел, которые нужно исключить) и seed (на случай, если вам нужен генератор случайных чисел с семенами).

get_random_int = function(args={})
{
    let def_args =
    {
        min: 0,
        max: 1,
        exclude: false,
        seed: Math.random
    }

    args = Object.assign(def_args, args)

    let num = Math.floor(args.seed() * (args.max - args.min + 1) + args.min)

    if(args.exclude)
    {
        let diff = args.max - args.min
        let n = num

        for(let i=0; i<diff*2; i++)
        {
            if(args.exclude.includes(n))
            {
                if(n + 1 <= args.max)
                {
                    n += 1
                }

                else
                {
                    n = args.min
                }
            }

            else
            {
                num = n
                break
            }
        }
    }

    return num
}

Может использоваться как:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1,
        exclude: [3, 6, 5],
        seed: my_seed_function
    }
)

Или проще:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1
    }
)

Тогда вы можете сделать:

let item = some_list[n]

Суть: https://gist.github.com/madprops/757deb000bdec25776d5036dae58ee6e

madprops
источник
0
  • random (min, max) генерирует случайное число от min (включительно) до max (исключая)
  • Math.floor округляет число до ближайшего целого

    function generateRandomInteger (min, max) { 
        return Math.floor(random(min,max)) 
    }`

Таким образом, чтобы сгенерировать случайное целое число от 4 до 8 включительно, вызовите вышеуказанную функцию со следующими аргументами:

generateRandomInteger (4,9)
Normajean
источник
0

Мой метод генерации случайного числа от 0 до n, где n <= 10 (n исключено):

Math.floor((Math.random() * 10) % n)
Нитин Джадхав
источник