Gere um número aleatório entre dois números em JavaScript

1798

Existe uma maneira de gerar um número aleatório em um intervalo especificado (por exemplo, de 1 a 6: 1, 2, 3, 4, 5 ou 6) em JavaScript?

Mirgorod
fonte
12
Math.floor (Math.random () * 7)
Amjad Masad
65
Claro .. Math.floor (Math.random () * 6 + 1)
Amjad Masad
3
Nabil Kadimi também escreveu um artigo sobre como gerar números aleatórios negativos .
madc 4/04/12
aqui é uma essência útil: gist.github.com/kerimdzhanov/7529623
Dan KK
por que uma solução como essa Math.floor((Math.random()*10)+1);não pode funcionar para você, conforme especificado aqui em w3schools.com/jsref/jsref_random.asp ..?
Shashwat

Respostas:

2117

Importante

O código a seguir funciona apenas se o valor mínimo é 1. Não funciona para valores mínimos diferentes de 1.

Se você deseja obter um número inteiro aleatório entre 1 ( e apenas 1 ) e 6, calcula:

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

Onde:

  • 1 é o número inicial
  • 6 é o número de resultados possíveis (1 + início (6) - final (1) )
khr055
fonte
45
Enquanto isso funcionaria, @ Mike, seria melhor apontar a versão mais genérica, como a Francisc a possui abaixo :-).
Raymond Machira
59
-1. Após pesquisar no Google, encontrei esta pergunta: o título é "" Gerar valor aleatório entre dois números em Javascript "." Não funcionará se o valor mínimo for 0
Ydhem 8/10
18
Não funciona se você quiser um número entre dois números maiores, por exemplo. Math.floor (Math.random () * 900) + 700
Rob
15
Isso só funciona se o mínimo é 1. Se o min é de 2 e ainda utilizar Math.floor(Math.random() * 6) + 2meios que, se Math.random()os resultados em 0.99 nosso valor aleatório seria7
antitóxico
28
Este código não é bom porque, não funciona com nenhum número. O código @Francisc está correto.
Lion King
2286
function randomIntFromInterval(min, max) { // min and max included 
  return Math.floor(Math.random() * (max - min + 1) + min);
}

O que ele faz "extra" é que permite intervalos aleatórios que não começam com 1. Portanto, você pode obter um número aleatório de 10 a 15, por exemplo. Flexibilidade.

Francisc
fonte
5
isso também é ótimo, porque se alguém não incluir o toargumento, o fromargumento também é o máximo.
Jason
12
Olá. Isto é do MDN: Returns a floating-point, pseudo-random number in the range [0, 1) that is, from 0 (inclusive) up to but not including 1 (exclusive), which you can then scale to your desired range.( developer.mozilla.org/en-US/docs/JavaScript/Reference/… )
Francisc
5
Leia o comentário acima. Random está dentro de [0,1), não [0,1].
Francisc
3
Funciona muito bem se o número mais baixo é 0.
Robin Zimmermann
2
Observe que esta solução está correta somente se min e max forem números inteiros; caso contrário, você poderá obter um resultado no intervalo [min, ceil (max)]. Ou seja, você pode obter um resultado que está fora da faixa porque é superior ao máximo.
18718 collimarco
329

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 máximo ( 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 ​​().

Lior Elrom
fonte
Algo que me confundiu ... o Math.floor (..) garante que o número seja um número inteiro em que Math.round (..) daria uma distribuição desigual. Ref: developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
alikuli
1
Eu confio nesta resposta. Alguém pode dar um link ou uma explicação clara de por que isso funciona? Talvez um exemplo de como Math.round daria um viés, e por que isso significa que temos que usar essa fórmula aparentemente complexa?
Robin Andrews
6
@alikuli Para uma gama de [1,2], há 25% de chance Math.random()iria dar-lhe um número de um deles [0,0.49], [0.5,0.99], [1,1.49], [1.5,1.99]. Arredondar esses intervalos resultaria em 0, 1, 1, 2, que não é uma distribuição uniforme. Piso lhes resulta em 0, 0, 1, 1.
pishpish
1
@shuji Essa é , entre outras, a resposta correta. Eu só queria esclarecer porque o uso Math.roundexcessivo Math.floordaria resultados diferentes.
pishpish
A solução mais precisa que eu encontrei: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }
Sadik
91

Outras soluções:

  • (Math.random() * 6 | 0) + 1
  • ~~(Math.random() * 6) + 1

Experimente on-line

Vishal
fonte
6
você se importaria de explicar (ou fazer referências a) a ~~ sintaxis? Eu nunca vi isso antes! Solução elegante, mas difícil de entender.
31413 DiegoDD
27
Duplo Tilde ~~a e Bitwise OR (a | 0) são mais rápidas maneiras de escrever Math.floor (a)
edi9999
7
a | 0também é a maneira mais rápida e otimizada de converter uma string em um número inteiro. Ele funciona apenas com strings contendo números inteiros ( "444"e "-444"), ou seja, sem flutuações / frações. Produz um 0para tudo que falha. É uma das principais otimizações por trás do asm.js.
Pilau
3
Nota: se você estiver trabalhando com números realmente grandes, o til duplo não funcionará. Tente ~~(Math.random() * (50000000000000 - 0 + 1)) + 0eMath.floor(Math.random() * (50000000000000 - 0 + 1)) + 0
BrunoLM
3
"Dobro duplo e OR bit a bit / / são maneiras mais rápidas de escrever o ponto de matemática" é um belo dístico de rimas que iluminou minha manhã. Obrigado @ edi9999!
teedyay
60

TL; DR

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

Para obter o número aleatório generateRandomInteger(-20, 20);

EXPLICAÇÃO ABAIXO

Precisamos obter um número inteiro aleatório, digamos X entre min e max.

Direita?

ie min <= X <= max

Se subtrairmos min da equação, isso é equivalente a

0 <= (X - min) <= (max - min)

Agora, vamos multiplicar isso com um número aleatório r que é

0 <= (X - min) * r <= (max - min) * r

Agora, vamos adicionar de volta min à equação

min <= min + (X - min) * r <= min + (max - min) * r

Agora, vamos escolher uma função que resulte em r tal que satisfaça nosso intervalo de equações como [min, max]. Isso só é possível se 0 <= r <= 1

ESTÁ BEM. Agora, o intervalo de r, ou seja, [0,1] é muito semelhante ao resultado da função Math.random (). Não é?

A função Math.random () retorna um número pseudo-aleatório de ponto flutuante no intervalo [0, 1); ou seja, de 0 (inclusive) até mas não incluindo 1 (exclusivo)

Por exemplo,

Caso r = 0

min+ 0 * ( max- min) = min

Caso r = 1

min+ 1 * ( max- min) = máx.

Caso aleatório usando Math.random 0 <= r <1

min+ r * ( max- min) = X , em que X tem um intervalo de min <= X < max

O resultado acima X é um numérico aleatório. No entanto, devido a Math.random (), nosso limite esquerdo é inclusivo e o limite direito é exclusivo. Para incluir nosso limite direito, aumentamos o limite direito em 1 e calculamos o resultado.

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

Para obter o número aleatório

generateRandomInteger(-20, 20);

Faiz Mohamed Haneef
fonte
25

Ou, em sublinhado

_.random(min, max)
vladiim
fonte
24
var x = 6; // can be any number
var rand = Math.floor(Math.random()*x) + 1;
ryebr3ad
fonte
2
De fato. Eu esqueci que Rand tinha 0 inclusivo. Corrigido.
Ryebr3ad
3
Isso faz parte do Pseudocódigo ... alguém pode pensar que é real e tentar usá-lo dessa maneira.
gravityboy
35
@gravityboy Do que você está falando? Se alguém não puder substituir um número por [escolher um número ...], talvez não seja adequado como programador.
21411 rjjjjjjjjjjjj
7
@ ryebr3ad -1! é dito em javascript, não em pseudo-código e também nem todos os leitores são programadores talentosos. Muitos são iniciantes!
21312 Steve
3
@ ryebr3ad: Eu tive um colega de trabalho que estava ensinando estagiários sobre um ambiente de banco de dados que eles precisariam de suporte. Ele disse a eles para selecionar tudo de uma tabela e eles começaram a escrever "selecione tudo de ..." diretamente no editor de consultas SQL. Ele teve a mesma reação que você.
Ellesedil
22

jsfiddle: https://jsfiddle.net/cyGwf/477/

Número inteiro aleatório : para obter um número inteiro aleatório entre mine max, use o seguinte código

function getRandomInteger(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

Número de ponto flutuante aleatório : para obter um número de ponto flutuante aleatório entre mine max, use o seguinte código

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

Referência: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

Razan Paul
fonte
14

A matemática não é o meu ponto forte, mas tenho trabalhado em um projeto em que precisava gerar muitos números aleatórios entre positivos e negativos.

function randomBetween(min, max) {
    if (min < 0) {
        return min + Math.random() * (Math.abs(min)+max);
    }else {
        return min + Math.random() * max;
    }
}

Por exemplo

randomBetween(-10,15)//or..
randomBetween(10,20)//or...
randomBetween(-200,-100)

Obviamente, você também pode adicionar alguma validação para garantir que não faça isso com nada além de números. Verifique também se min é sempre menor ou igual ao máximo.

Petter Thowsen
fonte
5
Isto está simplesmente errado. min + Math.random() * maxfornecerá números entre min e min + max, o que não é o que você deseja. O primeiro ramo do ifestá correto, mas poderia ser simplificado para dizer return min + Math.random() * (max - min), qual é a solução correta, independentemente de min ser positivo ou negativo (veja as outras respostas). Além disso, lembre-se de que você ainda precisa calcular o resultado se não quiser frações.
Avish 23/05
10

Eu escrevi uma função mais flexível, que pode fornecer um número aleatório, mas não apenas um número inteiro.

function rand(min,max,interval)
{
    if (typeof(interval)==='undefined') interval = 1;
    var r = Math.floor(Math.random()*(max-min+interval)/interval);
    return r*interval+min;
}

var a = rand(0,10); //can be 0, 1, 2 (...) 9, 10
var b = rand(4,6,0.1); //can be 4.0, 4.1, 4.2 (...) 5.9, 6.0

Versão fixa.

ElChupacabra
fonte
Esta não é uma boa solução, pois não funcionará com zero como valor mínimo. Veja a resposta de @ Lior.
Sebastien
Claro que funciona com zero como valor mínimo. Você tentou? Não há razão para que isso não funcione. Não funcionará com 0 como intervalo, o que não é estranho (intervalo = 0? ...).
ElChupacabra
Corri várias vezes essa função com zero como valor mínimo e nunca obtive zero na saída. Ou eu não tenho a sorte ...
Sebastien
Você está certo. "+ intervalo" estava no lugar errado. Teste agora, por favor. Coisa estranha que às vezes o console.log me dá 0,300000004 em vez de 0,3 como 3 * 0,1 não seria exatamente 0,3.
ElChupacabra
9

Exemplo

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

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

O resultado pode ser: 3

Experimente você mesmo: aqui

-

ou usando lodash / undescore:

_.random(min, max)

Documentos: - lodash - undescore

Sebastián Lara
fonte
1
então você precisa de 9 ou 10, certo? Se sim: const randomNumber = Math.floor ((Math.random () * 10) + 1) const nineOrTen = randomNumber% 2 === 0? 9: 10
Sebastián Lara
7

Apesar de muitas respostas e quase o mesmo resultado. Gostaria de adicionar minha resposta e explicar seu funcionamento. Porque é importante entender o seu funcionamento em vez de copiar e colar um código de linha. Gerar números aleatórios não passa de matemática simples.

CÓDIGO:

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));
}
Arun Sharma
fonte
6

Eu estava pesquisando um gerador de números aleatórios escrito em TypeScript e escrevi isso depois de ler todas as respostas, espero que funcione para codificadores TypeScript.

    Rand(min: number, max: number): number {
        return (Math.random() * (max - min + 1) | 0) + min;
    }   
Erdi İzgi
fonte
5

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 sempre será 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]

Jeremy Banks
fonte
Agora, é isso que chamo de exagero.
2xSamurai
2
@ 2xSamurai Lá, atualizei a resposta para explicar por que você pode precisar disso e como ele funciona. Isto é melhor? : P
Jeremy Banks
Não é um exagero se você quiser números aleatórios criptograficamente seguros e uniformemente distribuídos. Gerar números aleatórios que atendam a esses requisitos é difícil. Ótima resposta, @ JeremyBanks.
thomaskonrad
4

Adicionando floatcom versão de precisão fixa com base na intversão na resposta do @ Francisc:

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

tão:

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

e para resposta int

randomFloatFromInterval(1,3,0) // => 1, 2, 3
yonatanmn
fonte
3

Número inteiro aleatório cripto-forte no intervalo [a, b] (suposição: a <b)

let rand= (a,b)=> a+(b-a+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0

console.log( rand(1,6) );

Kamil Kiełczewski
fonte
1

Isso deve funcionar:

const getRandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min
sbr_amd
fonte
1

Eu descobri uma ótima maneira nova de fazer isso usando os parâmetros padrão do ES6. É muito bacana, pois permite um ou dois argumentos. Aqui está:

function random(n, b = 0) {
    return Math.random() * (b-n) + n;
}
maburdi94
fonte
1

Isso está com cerca de nove anos de atraso, mas o randojs.com torna isso uma linha simples:

rando(1, 6)

Você só precisa adicionar isso ao cabeçalho do seu documento html e pode fazer o que quiser com aleatoriedade facilmente. Valores aleatórios de matrizes, elementos jquery aleatórios, propriedades aleatórias de objetos e até mesmo impedir repetições, se necessário.

<script src="https://randojs.com/1.0.0.js"></script>
Aaron Plocharczyk
fonte
Por que adicionar uma dependência para fazer algo que já é uma linha única? A obsessão com a adição de bibliotecas na comunidade JS é louco
Daniel Cooke
mais fácil de ler e lembrar. Eu concordo, porém
Aaron Plocharczyk
1

Isso funciona para mim e produz valores como a função de biblioteca padrão random.randint do Python :


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

console.log("Random integer: " + randint(-5, 5));
gnrfan
fonte
1

Tente usar:

function random(min, max) {
   return Math.round((Math.random() *( Math.abs(max - min))) + min);
}
console.log(random(1, 6));

AyushKatiyar
fonte
1

retornar 1-6 como um dado basicamente,

return Math.round(Math.random() * 5 + 1);
Husky931
fonte