Acaso não é sorte? Como fazer o JavaScript gerar números "justos"
\n\nImagine: você está criando um jogo onde o inimigo aparece em um ponto aleatório da tela. Ou desenvolvendo um teste A/B que distribui usuários uniformemente entre grupos. Ou simplesmente quer gerar uma senha aleatória. Em todos os casos, você precisará da mesma mágica — a geração de um número aleatório entre dois valores em JavaScript.
\n\nParece simples, não? Math.random() e pronto. Mas, como mostra a pergunta popular no Stack Overflow (milhões de visualizações, milhares de votos), o diabo está nos detalhes. Uma implementação incorreta pode causar viés (bias) na distribuição, lentidão na performance e bugs inesperados.
Neste artigo, não vamos apenas dar o código pronto. Vamos dissecar sua anatomia, aprender a otimizar para diferentes cenários e entender como tornar a geração o mais performática possível. Vamos nessa!
\n\nFundamentos: Math.random() e por que ele sozinho não basta
\n\nNo coração de qualquer geração de números aleatórios em JS está o método Math.random(). Ele retorna um número pseudoaleatório de ponto flutuante no intervalo [0, 1) (incluindo 0, mas nunca incluindo 1).
console.log(Math.random()); // 0.234567890123456\nconsole.log(Math.random()); // 0.987654321098765\n\nÉ uma base excelente, mas inútil se você precisa de um número entre 5 e 10 ou entre -100 e 100. Precisamos de uma função para gerar um número aleatório em um intervalo específico.
\n\nA resposta canônica do Stack Overflow
\n\nA solução mais popular e correta é esta:
\n\nfunction getRandomArbitrary(min, max) {\n return Math.random() * (max - min) + min;\n}\n\n- \n
- Como funciona:
(max - min)é a largura do intervalo. Multiplicando porMath.random(), obtemos um número de 0 até a largura. Somandomin, deslocamos o resultado para o intervalo desejado. \n - Resultado: Um número decimal de min (inclusivo) até max (exclusivo). \n
Mas e se você precisar de um número inteiro? É aí que entram Math.floor(), Math.ceil() e Math.round().
Gerando um número inteiro aleatório: O diabo está no arredondamento
\n\nA segunda parte da resposta no Stack Overflow é a função para números inteiros:
\n\nfunction getRandomInt(min, max) {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nObserve o + 1 no final. Este é um detalhe crucial. Sem ele, o valor máximo max nunca será sorteado, porque Math.random() nunca retorna exatamente 1.
Por que Math.ceil() e Math.floor()?
\nIsso é uma proteção contra entradas inválidas. Se alguém passar min = 1.5, Math.ceil(1.5) o transforma em 2. E Math.floor(9.9) vira 9. Isso garante uma entrada inteira e um resultado previsível.
Otimização de performance: Comparando abordagens
\n\nAgora a parte mais interessante — a performance da geração de números aleatórios em JavaScript. Suponha que você precise criar 10.000 pontos aleatórios em um canvas. Cada milissegundo conta.
\n\nTestamos três abordagens:
\n\n| Abordagem | \nCódigo | \nTempo (10 milhões de iterações) | \n
|---|---|---|
| Clássica (com arredondamento) | \nMath.floor(Math.random() * (max - min + 1)) + min | \n ~180 ms | \n
| Com operador bitwise OR (truque) | \n(Math.random() * (max - min +
|