Come generare numeri casuali in C#

Giorgio Borelli

Comm generare un numero casuale in C#Nel .net framework non poteva di certo mancare una classe per gestire i numeri random (casuali), questa è la classe System.Random, la quale ci permette di generare numeri casuali interi, double o riempire array di byte. Possiamo specificare anche un valore massimo, o un range di valori nel quale il nostro numero casuale deve ricadere.

Tramite la classe Random generare numeri casuali in C# è davvero un gioco da ragazzi, dobbiamo porre però attenzione a questo argomento, poichè nasconde un'insidia, infatti è bene sapere che la classe Random permette di generare numeri pseudo-casuali, i numeri generati non sono completamente casuali, poiché sono generati da un'algoritmo matematico (algoritmo sottrattivo) che per sua natura stessa non può essere casuale.

La genereazione di un numero casuale avviene partendo da un valore d'inizializzazione, detto seme, scegliendo sempre lo stesso seme si otterrà sempre la stessa sequenza di numeri pseudo-casuali, proprio perchè generati da un'algoritmo matematico. Per ottenere dei numeri veramente casuali è necessario variare il valore del seme in base ad un qualche fattore, molto utile potrebbe essere il fattore tempo, affidandoci magari al clock di sistema.

Andiamo a vedere come usare la classe Random per generare numeri casuali in C#, facendo bene distinzione tra quelli pseudo-casuali e quelli casuali puri.

Generari numeri pseudo-casuali

Generare un numero pseudo-casuale in C# è davvero facilissimo, basta instanziare la classe Random e richiamare gli opportuni metodi, come illustrato nelle righe di codice sottostante:

//creo l'ogetto random (costruttore senza parametri)
Random random = new Random();

//ritorna un numero casuale non negativo
int nun = random.Next();

//ritorna un numero casuale compreso tra zero e novanta
int num2 = random.Next(90);

//ritorna un numero casuale compreso tra 1 e 10
int num3 = random.Next(1, 10);

l'oggetto random viene creato invocando il costruttore di default (senza parametri), in questo caso il .net framework come seme iniziale userà un valore ricavato dal clock di sistema, se l'intervallo temporale è troppo breve, la sequenza di numeri casuali generata sarà la stessa, provate ad esempio ad invocare il metodo Next di random dentro un breve ciclo for, vi accorgerete che la sequenza di numeri generata è identica, proprio perchè il clock di sistema è limitato, e nel "breve" arco di tempo in cui si ripete il ciclo for restituirà sempre lo stesso valore del seme iniziale. Ecco perchè i numeri generati in questo modo vengono detti pseudo-casuali e non casuali, poichè dipendono da un'algoritmo matematico e da un valore seme d'inizializzazione. Il loro uso è comunque accettabile nella stragrande maggioranza dei casi in cui si voglia generare un numero (o più di uno), da un insieme finito di elementi che abbia la stessa probabilità di uscita di tutti gli altri.

 

Generari numeri pseudo-casuali

Allora come fare per generare numeri casuali puri? La classe Random oltre al costruttore di default senza parametri, ne possiede un'altro che accetta come parametro un intero con segno che non è altro che il valore del seme, possiamo quindi andare ad agire sul seme d'inizializzazione instanziando l'ogetto random con un valore fornito nel modo più casuale possibile, e per far ciò abbiamo due strade, la prima è quella di generare il seme in modo casuale a sua volta, la seconda è quella di generare il seme basandoci su un fattore temporale che sia il più breve possibile, e cosa c'è di meglio se non sfruttare i millisecondi del clock di sistema, faremo in questo modo:

Random random = new Random((int)DateTime.Now.Millisecond);

basandoci su un'arco temporale così ristretto possiamo stare ragionevolmente certi che la generazione del seme sia diverso di volta in volta, generando pertanto numeri casuali abbastanza puri.

NOTA: Ovviamente stiamo considerando un caso potenzialmente reale, dove il seme viene ricreato al verificarsi magari di un click esterno, se invece come prima lo inseriamo dentro un ciclo for anche i millisencondi risultano troppo lunghi per generare un seme che porti a numeri casuali affidabili.

Oltre al classico metodo Next, la classe Random prevede altri due metodi per generare sequenze di numeri casuali in virgola o per riempire (fill) array di byte, richiamarli è semplicissimo, basta scrivere:

//ritorna un double compreso tra 0.0 ed 1.0
double num4 = random.NextDouble();

//riempie un array di byte di 100 elementi con dei numeri casuali
byte[] arrayNum = newbyte[100];
random.NextBytes(arrayNum);

Il primo genera un numero casuale in virgola compreso tra zero ed uno, il secondo, dopo aver dichiarato l'array di bytes, riempie i suoi elementi con dei numeri casuali compresi tra 0 e 256.

 

Conclusioni

Sulla classe Random per generare numeri casuali col .net framework non c'è molto altro d'aggiungere, desidero lasciarvi con una piccolissima applicanzioncina windows per la generazione di un numero casuale scritta in tutta fretta in C#, che potete divertirvi a modificare per provare i concetti descritti in questo articolo.

Provate e sperimentate, e se vi và fatemi sapere i vostri pareri tramite i commenti, invece se dovreste prendere un bel terno con i numeri generati dall'esempio fatemi un fischio, come minimo merito una cena.

Categorie: .NET framework | C#

Tags: ,

Commenti (10) -

Clingonboy
Clingonboy says:

Grazie per questo articolo, è stato molto interessante.
Spero di leggerne ancora molti ....

Rispondi

Prego, sono contento che ti sia piaciuto, questi commenti sono piccole soddisfazioni che gratificano il mio lavoro.

Spero anche io in futuro di poterne scrivere molti altri "interessanti".

Ciao e alla prossima.

Rispondi

questo programma l'hai copiato da un altro forum birbante

Rispondi

Caro Antonio,
dal tuo commento non si può che evincere la tua totale ignoranza in materia, ti spiego.

La classe Random del .NET Framework non appartiene a nessuno (se non a Microsoft, ne trovi ampia documentazione su msdn) ed è liberamente usabile e studiabile, i concetti esposti invece sui numeri casuali e pseudo-casuali che richiedono l'inserimento di un valore seme, sono risaputi e conosciuti da chi opera in questo campo a prescindere dal linguaggio di programmazione usato (io l'ho esposto in C#).
Infine il programmino di esempio scaricabile, l'ho scritto io personalmente a manina, posso dartene prova dove e quando vuoi, se ne hai vista o scaricata una versione identica vuol dire che loro lo hanno copiato da me, in tal caso ti prego di segnalarmi dove.

Detto questo, se altri hanno trattato lo stesso argomento non significa che io lo abbia copiato o loro abbiano copiato da me, ti ripeto è un argomento noto e ne hanno parlati in tanti fuori e dentro il web, io ne ho dato solo la mia versione con un mio programmino di esempio, tutto qua. Ah, e proprio per volermi togliere un sassolino dalla scarpa, ti correggo un'altra volta, questo è un blog e non un forum, sai (ma forse no) c'è un pò di differenza.

Ricordati, io scrivo di polso tutti i miei articoli, può capitare a volte d'ispirarmi ad argomenti già trattati, ma non copio da nessuno, ne dò sempre la mia versione, documentandomi e facendo le mie prove, ogni mio articolo mi costa un grosso sacrificio in termini di tempo che sottraggo al mio lavoro ed alla mia famiglia, quindi gentilmente la prossima volta prima di lanciare accuse pensa bene ed informati prima di scrivere.

Sono aperto ad ascoltare ogni tua replica, saluti Giorgio Borelli.

Rispondi

Salve!!
Io sono un iniziato in programmazione e devo dire che i tuoi articoli sono molti interessanti e utili complimenti.
Mi domandavo come riesco a risultarmi piu numeri e non solo uno ,nell’ tuo esempio scaricabile, mi potesti dare un suggerimento con parole povere??

Rispondi

Cosimo Meli
Cosimo Meli says:

Ciao,
se ho capito bene cosa vuoi dire basta che imposti un ciclo for con il numero di iterazioni che ti interessano e all'interno calcoli i numeri random che ti servono con _rdm.Next(), ovviamente volta per volta dovrai visualizzarli, conservarli in un array o farci quel che vuoi.
Ad esempio puoi modificare una parte del codice così per generare 10 numeri casuali consecutivamente compresi tra min e max:

int[] numeri=new int[10];
            if (_min != 0)
            {
                if (_max != 0)
                {
                    label3.Text = "";
                    for (int i = 0; i < 10; i++)
                    {
                        numeri[i]= _rdm.Next(_min, _max);
                        label3.Text += numeri[i].ToString();
                        if (i < 9) label3.Text += " - ";
                    }
                }

Rispondi

Era esattamente quello che intendevo ti ringrazio tanto sei un mito!!^^

Rispondi

il codice si poteva scrivere leggermente più compatto, ma direi che Cosimo ha risposto alla grande, ti fà pure il controllo sul penultimo elemento per non aggiungere più lo spazio ed il trattino che separano i numeri casuali generati rappresentati poi nella stringa Text della Label (che non c'era bisogno d'inizializzare).

OTTIMO!!!

Una miglioria potrebbe essere la possibilità d'inserire i numeri per il range, min e max da input.

Rispondi

  Si infatti, a me mi dava sempre  numeri doppi credo che mi mancava l’array (ho iniziato da pochissimo a giocarne con c# e programmazione in generale).
  Pero ragazzi devo dire che questo sito e fortissimo, scritto per poter capire tutti non solo per avanzati, sembra quasi scritto da un docente.
  Ancora una volta COMPLIMENTI e alla prossima^^.

Rispondi

Grazie x i complimenti, troppo buono, se ti và continua a seguirci.

Rispondi

Aggiungi Commento

biuquote
Loading