Come si genera un numero casuale in C#?
-
09-06-2019 - |
Domanda
Vorrei generare un numero in virgola mobile casuale tra 2 valori.Qual è il modo migliore per farlo in C#?
Soluzione
L'unica cosa che aggiungerei Ericla risposta è una spiegazione;Ritengo che conoscere il motivo per cui il codice funziona sia migliore che sapere quale codice funziona.
La spiegazione è questa:diciamo che vuoi un numero compreso tra 2,5 e 4,5.L'intervallo è 2,0 (4,5 - 2,5). NextDouble
restituisce solo un numero compreso tra 0 e 1,0, ma se lo moltiplichi per l'intervallo otterrai un numero compreso tra 0 e allineare.
Quindi, questo ci darebbe doppi casuali tra 0,0 e 2,0:
rng.NextDouble() * 2.0
Ma li vogliamo tra 2,5 e 4,5!Come facciamo questo?Aggiungi il numero più piccolo, 2,5:
2.5 + rng.NextDouble() * 2.0
Ora otteniamo un numero compreso tra 0,0 e 2,0;se aggiungi 2,5 a ciascuno di questi valori vediamo che l'intervallo è ora compreso tra 2,5 e 4,5.
All'inizio pensavo che fosse importante se b > a o a > b, ma se lo risolvi in entrambi i modi scoprirai che funziona in modo identico purché non si rovini l'ordine delle variabili utilizzate.Mi piace esprimerlo con nomi di variabili più lunghi in modo da non confondermi:
double NextDouble(Random rng, double min, double max) { return min + (rng.NextDouble() * (max - min)); }
Altri suggerimenti
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);
Per i doppi puoi sostituire Next con NextDouble
Ecco uno snippet di come ottenere numeri casuali criograficamente sicuri:Questo riempirà gli 8 byte con una sequenza crittograficamente forte di valori casuali.
byte[] salt = new byte[8];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(salt);
Per maggiori dettagli vedere Quanto è casuale la tua casualità??" (ispirato da un articolo di CodingHorror sul mescolamento dei mazzi)
Quanto casuale?Se riesci a gestire lo pseudo-casuale, semplicemente:
Random randNum = new Random();
randNum. NextDouble(Min, Max);
Se vuoi un numero casuale "migliore", probabilmente dovresti guardare l'algoritmo Mersenne Twister.Molte persone hanno già implementato per te però
Per una spiegazione del motivo per cui Longhorn è stato ridimensionato così tanto: http://msdn.microsoft.com/en-us/magazine/cc163367.aspx Cerca l'implementazione di NextDouble e la spiegazione di cos'è un doppio casuale.
Quel collegamento è anche un buon esempio di come utilizzare numeri casuali crittografici (come menzionato da Sameer) solo con output effettivamente utili invece di un flusso di bit.