Como você gera um número aleatório em C#?
-
09-06-2019 - |
Pergunta
Gostaria de gerar um número aleatório de ponto flutuante entre 2 valores.Qual é a melhor maneira de fazer isso em C#?
Solução
A única coisa que eu acrescentaria Éricoa resposta de é uma explicação;Sinto que saber por que o código funciona é melhor do que saber qual código funciona.
A explicação é esta:digamos que você queira um número entre 2,5 e 4,5.O intervalo é 2,0 (4,5 - 2,5). NextDouble
retorna apenas um número entre 0 e 1,0, mas se você multiplicar isso pelo intervalo, obterá um número entre 0 e 1,0 faixa.
Então, isso nos daria duplas aleatórias entre 0,0 e 2,0:
rng.NextDouble() * 2.0
Mas, nós os queremos entre 2,5 e 4,5!Como vamos fazer isso?Adicione o menor número, 2,5:
2.5 + rng.NextDouble() * 2.0
Agora, obtemos um número entre 0,0 e 2,0;se você adicionar 2,5 a cada um desses valores, veremos que o intervalo está agora entre 2,5 e 4,5.
A princípio pensei que importava se b > a ou a > b, mas se você resolver as duas coisas, descobrirá que funciona de forma idêntica, desde que não bagunce a ordem das variáveis usadas.Gosto de expressá-lo com nomes de variáveis mais longos para não me confundir:
double NextDouble(Random rng, double min, double max) { return min + (rng.NextDouble() * (max - min)); }
Outras dicas
System.Random r = new System.Random();
double rnd( double a, double b )
{
return a + r.NextDouble()*(b-a);
}
// generate a random number starting with 5 and less than 15
Random r = new Random();
int num = r.Next(5, 15);
Para duplas você pode substituir Next por NextDouble
Aqui está um trecho de como obter números aleatórios criograficamente seguros:Isto preencherá os 8 bytes com uma sequência criptograficamente forte de valores aleatórios.
byte[] salt = new byte[8];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(salt);
Para mais detalhes veja Quão aleatório é o seu aleatório??" (inspirado em um artigo do CodingHorror sobre embaralhamento de deck)
Quão aleatório?Se você pode lidar com pseudo-aleatório, simplesmente:
Random randNum = new Random();
randNum. NextDouble(Min, Max);
Se você deseja um número aleatório "melhor", provavelmente deveria dar uma olhada no algoritmo Mersenne Twister.Muitas pessoas têm já implementou para você embora
Para uma explicação de por que o Longhorn foi tão rebaixado: http://msdn.microsoft.com/en-us/magazine/cc163367.aspx Procure a implementação do NextDouble e a explicação do que é um duplo aleatório.
Esse link também é um bom exemplo de como usar números aleatórios criptográficos (como Sameer mencionou) apenas com saídas úteis reais em vez de um fluxo de bits.