PDA

View Full Version : [C] numeri random pari


ArtX
11-01-2009, 16:32
ciao,
premetto che non sò quasi nulla del c, ma volevo sapere come si generano numeri random pari.
Per i numeri random per ora ho fatto così:

int main ()
int main ()
{
int aggiungi;
srand(time(NULL));
aggiungi = rand() % 20;
aggiungi++;


però vorrei che mi "randomizzasse" :D solo i numeri pari e non lo 0.
che devo fare?
grazie

blu_eye4
11-01-2009, 18:38
semplice soluzione.... generi un numero random e poi con un if-else vedi se il numero generato è pari. Per vedere se un numero è pari basta vedere se il numero random modulo di 2 dà 0 (variabile % 2 intendo...), altrimenti è dispari :D

Mi sono fatto capire? :stordita:

variabilepippo
11-01-2009, 18:45
come si generano numeri random pari.



int numeri_pari_casuali(int M) {
return 2*(rand() % M + 1);
}

ArtX
11-01-2009, 21:32
grazie ora provo :D

DanieleC88
12-01-2009, 13:06
int numeri_pari_casuali(int M) {
return 2*(rand() % M + 1);
}


int numeri_pari_casuali(int M)
{
return (rand() % M + 1) << 1;
}


:Prrr:

variabilepippo
12-01-2009, 13:12
int numeri_pari_casuali(int M)
{
return (rand() % M + 1) << 1;
}


Qualsiasi compilatore decente ottimizza il codice trasformando automaticamente la moltiplicazione per 2 in uno shift. Il codice con la moltiplicazione per 2 in compenso è più leggibile (e come detto poco fa viene comunque compilato con uno shift)... :Prrr:

DanieleC88
12-01-2009, 13:15
Lo so, ma lo shift mi piace di più. :D (graficamente intendo, nel codice)

variabilepippo
12-01-2009, 13:20
Lo so, ma lo shift mi piace di più.

Lo dico sempre che per programmare in C bisogna essere dei pervertiti... :D

DanieleC88
12-01-2009, 13:23
:asd:

ArtX
22-01-2009, 18:52
Lo dico sempre che per programmare in C bisogna essere dei pervertiti... :D

hahahahaha :D

gugoXX
22-01-2009, 19:21
Il codice funziona, ma penso che non mi piaccia.
Mi sa che i valori restituti non siano uniformemente distribuiti.

Provate un po' a calcolare la distribuzione dei valori casuali quando M vale 30000, tirando a caso una milionata di valori.
Ho idea che i valori tra 0 e 2767*2 compaiano molto piu' di frequente che gli altri.

astorcas
23-01-2009, 14:42
Il codice funziona, ma penso che non mi piaccia.
Mi sa che i valori restituti non siano uniformemente distribuiti.

Provate un po' a calcolare la distribuzione dei valori casuali quando M vale 30000, tirando a caso una milionata di valori.
Ho idea che i valori tra 0 e 2767*2 compaiano molto piu' di frequente che gli altri.

Hai qualche prova matematica? Che è 2767*2? (Te lo chiedo non per critica ma per curiosità :P)

gugoXX
23-01-2009, 15:14
Hai qualche prova matematica? Che è 2767*2? (Te lo chiedo non per critica ma per curiosità :P)

Certo. Detta cosi' e' un po' criptica ammetto.

la funzione rand() genera un valore intero casuale, il cui dominio e' tra 0 e il valore contenuto nella costante RAND_MAX
Tale costante vale, per la maggior parte dei compilatori, 32767 (che e' (2^15) -1)

Ebbene, con il codice sopra scritto, ovvero giocando solo con i moduli,
se io volessi tirare a caso valori tra 0 e 30.000, capiterebbe che i valori che la rand() restituisse tra 30000 e 32767 verrebbero riportati dal modulo a valere di nuovo 0->2767
Quindi i valori compresi tra 0->2767 sarebbero il doppio piu' frequenti dei valori 2768->29999

Il *2 che manca alla formula di cui e' quello dell'effetto della moltiplicazione per due dovuta alla volonta' di avere solo numeri pari.
Otterremmo quindi che i numeri pari 0->(2767*2) sarebbero il doppio piu' frequenti degli altri.

Riducendo il dominio magari ai valori tra 0 e 10, l'effetto si ridurrebbe, ma non sparirebbe.
I valori tra 0->7 saebber leggermente piu' frequenti dei valori 8->9 (3276 contro 3275)

Una formula quindi piu' corretta per la generazione di un numero casuale in un range di distribuzione uniforme implica la presenza di una divisione e non di un modulo.
(rand() * dominio) / RAND_MAX

astorcas
23-01-2009, 15:54
Certo. Detta cosi' e' un po' criptica ammetto.

la funzione rand() genera un valore intero casuale, il cui dominio e' tra 0 e il valore contenuto nella costante RAND_MAX
Tale costante vale, per la maggior parte dei compilatori, 32767 (che e' (2^15) -1)

Ebbene, con il codice sopra scritto, ovvero giocando solo con i moduli,
se io volessi tirare a caso valori tra 0 e 30.000, capiterebbe che i valori che la rand() restituisse tra 30000 e 32767 verrebbero riportati dal modulo a valere di nuovo 0->2767
Quindi i valori compresi tra 0->2767 sarebbero il doppio piu' frequenti dei valori 2768->29999

Il *2 che manca alla formula di cui e' quello dell'effetto della moltiplicazione per due dovuta alla volonta' di avere solo numeri pari.
Otterremmo quindi che i numeri pari 0->(2767*2) sarebbero il doppio piu' frequenti degli altri.

Riducendo il dominio magari ai valori tra 0 e 10, l'effetto si ridurrebbe, ma non sparirebbe.
I valori tra 0->7 saebber leggermente piu' frequenti dei valori 8->9 (3276 contro 3275)

Una formula quindi piu' corretta per la generazione di un numero casuale in un range di distribuzione uniforme implica la presenza di una divisione e non di un modulo.
(rand() * dominio) / RAND_MAX

chiarissimo come sempre! Grazie