Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Números gerados por Math.round(Math.random()*10 não tem a mesma probabilidade.

Quando utilizamos a função Math.round(Math.random()*10) para escolher onze números inteiros de 0 a 10, na realidade os números 0 e 10 tem uma chance menor de serem escolhidos em relação aos outros, pois o Math.random não gera números entre -0,5 e 0 nem números entre 10 e 10,49999...

Como resolver isso, dando a cada número uma probabilidade idêntica de serem produzidos?

5 respostas

Thales, tudo bom?

Use o range de -0.5 e 10.5 ao invés de 0 e 10.

Abraços.

solução!

Olá Thales, tudo bem com você?

Ótima observação! Inclusive aqui na Alura tivemos o Quarentena Dev e um dos desafios era como tornar essa distribuição de frequência mais justa :)

No caso o ideal é trocarmos o round para um outro tipo de arredondamento, no caso o floor ou o trunc, o primeiro irá arredondar para baixo e o segundo irá ignorar as casas decimais, dessa forma teremos uma frequência mais justa, só teremos que tomar um certo cuidado porque agora teremos que fazer o random()de 0 até 11, para que tenhamos valores 10 :)

Então poderiamos substituir para: Math.floor(Math.random () * 11)

Eu fiz alguns testes para checar a densidade, gerando 50.000.000 valores aleatórios utilizando as duas maneiras, observe o resultado

Math.round( Math.random() * 10) 
>>> 

0:  2497189, 
1: 5002923,
2: 5000173,
3: 5001413,
4: 5002810,
5: 4996090,
6: 5000412,
7: 4997944,
8: 5000706, 
9: 5001757,
10: 2498584

Como você mesmo disse, tanto o valor na posição 0 quanto na 10 são afetados, agora vamos testar com o floor:

Math.floor( Math.random() * 10)

0: 4545609, 
1: 4544578,
2:  4544557, 
3: 4544402,
4: 4543939, 
5: 4547371,
6: 4544191,
7: 4542519,
8: 4545555,
9: 4549862,
10: 4547418

E agora sim temos uma distribuição justa :)

Abraços e Bons Estudos

Muito obrigado pelas respostas! Ronald, como usar range nessa função?

Geovani, usando Math.floor(Math.random()*11 existe a possibilidade de sair 11,00? Se sim, é possível excluí-lo do resultado?

Abraços

Olá Thales,

como usar range nessa função?

Não é possível utilizar range com as funções de arredondamento, elas esperam receber apenas um único valor numérico, você pode trabalhar somando valores após pegar o resultado, ou subtraindo, mas criar uma range dessa maneira não seria viável :)

usando Math.floor(Math.random()*11 existe a possibilidade de sair 11,00? Se sim, é possível excluí-lo do resultado?

É totalmente impossível, pois a função random gera valores de 0 até 0.999..., e a única maneira de termos 11 seria se ela gerasse o valor 1, mas isso não acontece :)

Abraços!

Fantástico. Muito obrigado!