Gerando números inteiros aleatórios em JavaScript em um intervalo específico?


1955

Como posso gerar números inteiros aleatórios entre duas variáveis ​​especificadas em JavaScript, por exemplo, x = 4e y = 8produziria alguma 4, 5, 6, 7, 8?


1
Aqui está uma lista útil: gist.github.com/kerimdzhanov/7529623 #
Dan KK

9
Como uma observação lateral: para aqueles que usam o npm e procuram uma solução rápida, confiável e pronta, existe o lodash.random que pode ser facilmente necessário com uma pegada super pequena (ele importará apenas o método em si e não o lodash inteiro).
Nobita

se ele precisa ser seguro com criptografia developer.mozilla.org/pt-BR/docs/Web/API/RandomSource/…
happy

Respostas:


3834

Existem alguns exemplos na página 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;
}

Aqui está a lógica por trás disso. É uma regra simples de três:

Math.random()retorna um Numberentre 0 (inclusive) e 1 (exclusivo). Portanto, temos um intervalo como este:

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

Agora, gostaríamos de um número entre min(inclusive) e max(exclusivo):

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

Podemos usar o Math.randompara obter o correspondente no intervalo [min, max). Mas, primeiro, devemos fatorar um pouco o problema subtraindo mindo segundo intervalo:

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

Isto dá:

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

Agora podemos aplicar Math.randome calcular o correspondente. Vamos escolher um número aleatório:

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

Então, para encontrar x, faríamos:

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

Não se esqueça de adicionar minnovamente, para que possamos obter um número no intervalo [min, max):

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

Essa foi a primeira função do MDN. O segundo, retorna um número inteiro entre minemax , inclusive.

Agora, para obter números inteiros, você pode usar round, ceilou floor.

Você pode usar Math.round(Math.random() * (max - min)) + min, no entanto, isso fornece uma distribuição não uniforme. Ambos mine maxapenas têm aproximadamente metade da chance de rolar:

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

Com maxexcluídos do intervalo, há uma chance ainda menor de rolar do que min.

Com Math.floor(Math.random() * (max - min +1)) + minvocê tem uma distribuição perfeitamente uniforme.

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

Você não pode usar ceil()e -1nessa equação, porque maxagora tinha um pouco menos chance de rolo, mas você pode rolar o (indesejada) min-1resultar também.


10
Só está fazendo isso porque está chamando floor, que termina.
21139 Josh Stodola

4
@ thezachperson31 Você poderia usar round, mas depois os dois, mine maxsó tinha metade da chance de rolar como os outros números. Você também pode subtrair um e pegar ceil. No entanto, isso deixa o maxnúmero com uma chance mínima menor de rolar devido ao [0,1)intervalo.
Christoph

12
Eu criei um jsFiddle se alguém quiser testar a distribuição deste método: jsfiddle.net/F9UTG/1
Ahren

8
@JackFrost sim, está certo. Você não é burro, você está começando a aprender :)
Ionuţ G. Stan

3
Esta questão é antiga, mas compreender esta resposta me pegou de forma demasiada Oo tempo, eu acho expansão math.random na próxima versão JavaScript seria tipo de útil
Jonathan Ortega

527
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;

19
Eu sei que essa é uma resposta MUITO antiga, mas o uso (Math.random() * (maximum - minimum + 1) ) << 0é mais rápido.
Ismael Miguel

11
@IsmaelMiguel Usando operadores binários ( x << 0, x | 0, ~~x) em vez de Math.floor()convertidos xem um de dois complemento com alcance muito menor do que Number.MAX_SAFE_INTEGER(2³²⁻¹ vs. 2⁵³), assim você tem que usá-lo com cuidado!
le_m

@IsmaelMiguel Yo Acabei de experimentar seu método no console e recebi aleatoriamente um valor negativo! Math.randRange = (mínimo, máximo) => (Math.random () * (máximo - mínimo + 1)) << 0 Math.randRange (2,657348096152) -1407373159
bluejayke

@bluejayke Como 657348096152 (1001100100001100111111111111000010011000 em binário) possui 40 bits, enquanto a aritmética bit a bit usa 32 bits. Se você 657348096152|0receber 218099864 (1100111111111111000010011000 em binário).
Ismael Miguel

1
Esta é uma resposta inteligente. Fazer o intervalo internamente [min, max + 1) alcança o resultado desejado de [min, max], sendo ambos inclusivos. Obrigado! :)
Mladen B.

135

Math.random ()

Retorna um número aleatório inteiro entre min ( incluído ) e max ( incluído ):

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

Ou qualquer número aleatório entre min ( incluído ) e max ( não incluído ):

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

Exemplos úteis (números inteiros):

// 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;

** E sempre bom ser lembrado (Mozilla):

Math.random () não fornece números aleatórios criptograficamente seguros. Não os use para qualquer coisa relacionada à segurança. Use a API Web Crypto e, mais precisamente, o método window.crypto.getRandomValues ​​().


56
function getRandomizer(bottom, top) {
    return function() {
        return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
    }
}

uso:

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.
}

demolir:

Estamos retornando uma função (emprestada da programação funcional) que, quando chamada, retornará um número inteiro aleatório entre os valores bottome top, inclusive. Dizemos 'inclusivo' porque queremos incluir tanto a parte inferior como a parte superior no intervalo de números que podem ser retornados. Por aqui,getRandomizer( 1, 6 ) retornará 1, 2, 3, 4, 5 ou 6.

(o número inferior é inferior, o número superior é maior)

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

Math.random()retorna um duplo aleatório entre 0 e 1, e se o multiplicarmos por um mais a diferença entre tope bottom, obteremos um dobro em algum lugar entre 0e 1+b-a.

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

Math.floorarredonda o número para o número inteiro mais próximo. Portanto, agora temos todos os números inteiros entre 0e top-bottom. O 1 parece confuso, mas precisa estar lá porque estamos sempre arredondando para baixo, para que o número superior nunca seja realmente alcançado sem ele. O decimal aleatório que geramos precisa estar no intervalo 0para (1+top-bottom)que possamos arredondar para baixo e obter um int no intervalo 0paratop-bottom

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

O código no exemplo anterior nos deu um número inteiro no intervalo 0e top-bottom, portanto, tudo o que precisamos fazer agora é adicionar bottomesse resultado para obter um número inteiro no intervalo bottome topinclusive. : D


NOTA: Se você passar um valor não inteiro ou o número maior primeiro, obterá um comportamento indesejável, mas, a menos que alguém solicite, não vou me aprofundar no código de verificação de argumentos, pois está longe da intenção da pergunta original. .


1
Sei que isso ocorre cerca de 2 anos e meio depois, mas com as entradas 1 e 6 sua função retorna valores 1,2,3,4 e 5, mas nunca um 6, como faria se fosse "inclusivo".
alguns

9
@some, Poderia ser pior, eu sou 2 anos e meio + 1 dia depois ^^
ajax333221

+1, testei seu código, ele parece criar um valor correto. Estrutura criativa para lidar com cenários fixos que podem ser repetidos muito no código.
21412 Chris

Por que você tem uma função dentro de uma função para isso?
Alph.Dev

1
@ Alph.Dev Para separar a lógica que usa o gerador de números aleatórios da lógica que decide exatamente qual distribuição de números aleatórios usar. Quando o código que usa o gerador de números aleatórios o aceita como parâmetro (uma função de 0 argumentos que sempre retorna um novo número aleatório), ele pode trabalhar com qualquer tipo de gerador de números aleatórios.
Gordon Gustafson

31
function randomRange(min, max) {
  return ~~(Math.random() * (max - min + 1)) + min
}

Alternativa, se você estiver usando o Underscore.js, poderá usar

_.random(min, max)

1
O Sublinhado realmente fornece uma _.uniqueId()função que você pode chamar de modelos do lado do cliente.
obfk

Usando operadores binários ( x << 0, x | 0, ~~x) em vez de Math.floor()convertidos xem um de dois complemento com escala muito menor do que Number.MAX_SAFE_INTEGER(2³²⁻¹ vs. 2⁵³), assim você tem que usá-lo com cuidado!
le_m

31

Retorne um número aleatório entre 1 e 10:

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

Retorne um número aleatório entre 1 e 100:

Math.floor((Math.random()*100) + 1)

o seu "entre" é inclusivo ou exclusivo? ou seja, é [1,10], [1,10), (1,10] ou (1,10)?
evandrix 27/11/2015

1
É parcialmente inclusivo: [1, *)
Ivan Z

qual é a necessidade de + 1 no final da função? Funciona perfeitamente, eu acho.
Shachi 10/10

18

Se você precisar de variável entre 0 e max, poderá usar:

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

O máximo é inclusivo ou exclusivo>?
Tree

2
O @Tree usando o Math.floor max é exclusivo. Se você quiser que max seja inclusivo, você pode usar Math.round.
Lucas

14

As outras respostas não respondem pelos parâmetros perfeitamente razoáveis ​​de 0e 1. Em vez disso, você deve usar o round invés de ceilou 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
Sua resposta é verdadeira, mas acho que seu exemplo está errado. Os console.log(randomNumber(5,6)); # 9 6 6 5 7 7números 9 e 7 estão entre 5 e 6? ...... você deve corrigi-lo ou explicar ..
Sachin

12

Aqui está a classe Implementação aleatória do MS DotNet em 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;
}());

Usar:

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

A classe MS DotNet Random está sob a licença Ms-RSL , o que significa que é protegido por direitos autorais. Portanto, tenha cuidado ao usar esse código derivado, pois ele pode ser motivo para casos de violação de direitos autorais.
JohannesB

12

Use esta função para obter números aleatórios entre o intervalo especificado

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

10

Depois de gerar um número aleatório usando um programa de computador, ainda é considerado um número aleatório se o número escolhido for uma parte ou o número completo do inicial. Mas se foi alterado, os matemáticos não o aceitam como um número aleatório e podem chamá-lo de número tendencioso. Mas se você estiver desenvolvendo um programa para uma tarefa simples, esse não será um caso a ser considerado.Mas se você estiver desenvolvendo um programa para gerar um número aleatório para itens valiosos, como programa de loteria ou jogo de apostas, seu programa será rejeitado pela gerência se você não considerar o caso acima.

Então, para esse tipo de pessoa, aqui está minha sugestão:

Gere um número aleatório usando Math.random(). (Diga isso 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.

Se você sabe ler a tabela de números aleatórios para escolher um número aleatório, o processo acima (multiplicando por 1, 10, 100 e assim por diante) não viola o que eu mencionei no início (porque altera apenas o local do ponto decimal.)

Estude o exemplo a seguir e desenvolva-o de acordo com suas necessidades.

Se você precisar de uma amostra [0,9], o piso de n * 10 é a sua resposta e, se precisar de [0,99], o piso de n * 100 é a sua resposta e assim por diante.

Agora vamos entrar no seu papel:

Você pediu números entre um intervalo específico. (Nesse caso, você é tendencioso nesse intervalo. - Ao pegar um número de [1,6] ao rolar um dado, você é tendencioso para [1,6], mas ainda assim é aleatório se, e somente se, o dado for imparcial .)

Portanto, considere seu intervalo ==> [78, 247] número de elementos do intervalo = 247 - 78 + 1 = 170; (já que os dois limites são inclusivos.

/*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);

Nota: No método um, primeiro criei uma matriz que contém os números necessários e depois os coloquei aleatoriamente em outra matriz. No método dois, gere números aleatoriamente e verifique se estão no intervalo que você precisa. Em seguida, coloque-o em uma matriz. Aqui eu gerei dois números aleatórios e usei o total deles para maximizar a velocidade do programa, minimizando a taxa de falhas que obtém um número útil. No entanto, a adição de números gerados também fornecerá alguma parcialidade. Então, eu recomendaria meu primeiro método para gerar números aleatórios dentro de um intervalo específico.

Nos dois métodos, seu console mostrará o resultado (pressione f12 no Chrome para abrir o console)


3
"aleatório" não significa necessariamente "distribuído uniformemente". "tendencioso" não implica "não aleatório". meios aleatórios extraídos de uma distribuição de probabilidade.
syzygy

6
Mal posso dizer o que esta resposta está tentando dizer. No entanto, se você precisar de números aleatórios para usos como números de loteria e jogos de azar. Primeiro, você provavelmente não deveria gerá-los no cliente. Segundo, você precisa de um gerador de números aleatórios criptograficamente seguro e o algo fornecido não é suficiente. Chamar aleatoriamente repetidamente não torna o resultado "mais aleatório". O autor parece estar preocupado com o viés, mas não está fornecendo um bom elemento para evitá-lo. De fato, as outras respostas curtas fornecidas produzem números aleatórios imparciais (assumindo que o gerador aleatório subjacente seja imparcial).
Jeff Walker Code Ranger

@JeffWalkerCodeRanger Acho que o que ele quis dizer é que com o algoritmo "normal" [ie Math.floor(Math.random() * (6 - 1 + 1) + 1)] os números 1 e 6 serão necessariamente rolados menos vezes que 2, 3, 4 e 5. No entanto, a diferença é basicamente insignificante.
Oldboy #

10

Para um número inteiro aleatório com um intervalo, tente:

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;
}

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)));
}

Para testar esta função e variações dessa função, salve o HTML / JavaScript abaixo em um arquivo e abra com um navegador. O código produzirá um gráfico mostrando a distribuição de um milhão de chamadas de função. O código também registrará os casos de borda, portanto, se a função produzir um valor maior que o máximo ou menor que o mínimo, você saberá.

<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

Para obter um número aleatório, digamos entre 1 e 6, faça primeiro:

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

Isso multiplica um número aleatório por 6 e adiciona 0,5 a ele. Em seguida, arredonde o número para um número inteiro positivo, fazendo o seguinte:

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

Arredonda o número para o número inteiro mais próximo.

Ou, para torná-lo mais compreensível, faça o seguinte:

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

Em geral, o código para fazer isso usando variáveis ​​é:

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

O motivo para remover 0,5 do valor mínimo é porque o uso do valor mínimo por si só permitiria obter um número inteiro que fosse mais um que o seu valor máximo. Ao retirar 0,5 do valor mínimo, você está essencialmente impedindo que o valor máximo seja arredondado para cima.

Espero que ajude.


Faça sentido se você estiver excluindo 0 , então não há necessidade de "arredondar para baixo" no intervalo de 0 a 0,5.
ILMostro_7

7

Usando o código a seguir, você pode gerar uma matriz de números aleatórios, sem repetir, em um determinado intervalo.

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

Sei que esta pergunta já foi respondida, mas minha resposta pode ajudar alguém.

Encontrei este método simples no W3Schools:

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

Espero que isso ajude alguém.


1
Math.floor ((Math.random () * 1) + 0); sempre dá 0
madprops

1
@madprops Porque o número máximo é exclusivo. Para obter 0 ou 1, você deve definir 2 como número máximo.
precisa saber é o seguinte

1
ou você simplesmente adicionar + 1 na função que chama esse método
Pietro Coelho

6

Número inteiro aleatório entre menor e maior:

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

Não é a solução mais elegante ... mas algo rápido.


5

Aqui está o que eu uso para gerar números aleatórios.

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

Nós executamos high++porque Math.random()gera um número aleatório entre 0, (inclusive) e 1 (exclusivo). O excluído significa que devemos aumentar o valor em um antes de executar qualquer matemática. Em seguida, subtraímos baixo de alto, dando-nos o número mais alto a ser gerado - baixo, depois + baixo, trazendo alto de volta ao normal e diminuindo o número mais baixo. então retornamos o número resultante

random(7,3) poderia retornar 3,4,5,6, or 7


2
Como highé usado apenas uma vez, você também pode usar em high-low+1vez de ter a instrução de incremento separada. Além disso, a maioria dos usuários espera que o lowparâmetro seja o primeiro.
Chris Walsh

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>

O Uint8Array cria uma matriz preenchida com um número de até 3 dígitos, que seria no máximo 999. Esse código é muito curto.


4

Aqui está um exemplo de uma função javascript que pode gerar um número aleatório de qualquer tamanho especificado sem usar 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 sempre muito mais perto de 1. e, portanto, sua função retorne mesmo número quando a função é chamada repetidamente .. jsbin.com/xogufacera/edit?js,console
Sunil BN

verifique a url jsbin .. você vai ver a saída yourself
Sunil BN

Funciona muito bem quando o comprimento está entre 4-10 (como testei na minha máquina), porque os valores das constantes T1 e T2 devem ter distância adequada.
Nilesh Pawar

3

esta é a minha opinião sobre um número aleatório em um intervalo, como em eu queria obter um número aleatório dentro de um intervalo da base ao expoente. por exemplo, base = 10, expoente = 2, fornece um número aleatório de 0 a 100, idealmente, e assim por diante.

se ajudar a usá-lo, aqui está:

// 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() é rápido e adequado para muitos propósitos, mas não é apropriado se você precisar de valores criptograficamente seguros (não é seguro) ou se precisar de números inteiros de uma distribuição imparcial completamente uniforme (a abordagem de multiplicação usada em outras respostas produz determinados valores com uma frequência um pouco mais frequente do que outros).

Nesses casos, podemos usar crypto.getRandomValues() para gerar números inteiros seguros e rejeitar quaisquer valores gerados que não possamos mapear uniformemente no intervalo de destino. Isso será mais lento, mas não deve ser significativo, a menos que você esteja gerando um número extremamente grande de valores.

Para esclarecer a questão da distribuição tendenciosa, considere o caso em que queremos gerar um valor entre 1 e 5, mas temos um gerador de números aleatórios que produz valores entre 1 e 16 (um valor de 4 bits). Queremos ter o mesmo número de valores gerados mapeados para cada valor de saída, mas 16 não se divide uniformemente por 5: deixa um restante de 1. Portanto, precisamos rejeitar 1 dos possíveis valores gerados e continuar apenas quando obtivermos um dos 15 valores menores que podem ser mapeados uniformemente em nosso intervalo de segmentação. Nosso comportamento pode se parecer com este pseudocódigo:

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.

O código a seguir usa lógica semelhante, mas gera um número inteiro de 32 bits, porque esse é o maior tamanho inteiro comum que pode ser representado pelo numbertipo padrão do JavaScript . (Isso pode ser modificado para usar BigInts, se você precisar de um intervalo maior.) Independentemente do intervalo escolhido, a fração dos valores gerados que são rejeitados será sempre menor que 0,5, portanto, o número esperado de rejeições sempre será menor que 1,0 e geralmente perto de 0,0; você não precisa se preocupar com isso para sempre.

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]



1

Você pode esse snippet de código,

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
Há uma linha duplicada desnecessária aqui. Basta usar em do - whilevez dewhile
Javi Marzán 28/11

1

Ionuț G. Stan escreveu uma ótima resposta, mas era um pouco complexa demais para eu entender. Portanto, encontrei uma explicação ainda mais simples dos mesmos conceitos em https://teamtreehouse.com/community/mathfloor-mathrandom-max-min-1-min-explanation de Jason Anello.

NOTA: A única coisa importante que você deve saber antes de ler a explicação de Jason é uma definição de "truncar". Ele usa esse termo ao descrever Math.floor(). O dicionário Oxford define "truncado" como:

Encurte (algo) cortando a parte superior ou a extremidade.


0

Pode lidar com a geração de números aleatórios UNIQUE de até 20 dígitos

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);

insira a descrição da imagem aqui

JsFiddle


Estou votando nisso apenas porque.
Taylor Ackley

1
@TaylorAckley Esta resposta não aborda a questão.
RomainValeri

0

/ * Escreva uma função chamada randUpToque aceite um número e retorne um número inteiro aleatório entre 0 e esse número? * /

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

/ * Escreva uma função chamada randBetweenque aceite dois números representando um intervalo e retorne um número inteiro aleatório entre esses dois números. * /

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

/ * Escreva uma função chamada randFromTillque aceite dois números representando um intervalo e retorne um número aleatório entre min (inclusive) e max (exclusivo). * /

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

/ * Escreva uma função chamada randFromToque aceite dois números representando um intervalo e retorne um número inteiro aleatório entre min (inclusive) e max (inclusive) * /

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

1
Bonito, você também pode notar que randBetween é (exclusivo) (exclusivo)?
Pfdint

0

Eu criei essa função que leva em conta opções como min, max, excluir (uma lista de entradas a serem excluídas) e semente (caso você queira um gerador aleatório semeado).

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
}

Pode ser usado como:

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

Ou, mais simplesmente:

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

Então você pode fazer:

let item = some_list[n]

Gist: https://gist.github.com/madprops/757deb000bdec25776d5036dae58ee6e


0
  • random (min, max) gera um número aleatório entre min (inclusive) e max (exclusivo)
  • Math.floor arredonda um número para o número inteiro mais próximo

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

Portanto, para gerar um número inteiro aleatório entre 4 e 8, inclusive, chame a função acima com os seguintes argumentos:

generateRandomInteger (4,9)

0

Meu método de gerar número aleatório entre 0 e n, em que n <= 10 (n excluído):

Math.floor((Math.random() * 10) % n)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.