Newsgroup: it.comp.lang.c
Titolo: generazione random

qualcuno sa dirmi come fare per generare numeri interi tra 0 e 1000000?
Ho provato con la rand() ma il massimo intero generato e'  32767.
Anche impostando con #define  RAND_MAX F4240 non cambia niente.
Ho guardato il sorgente rand.c :
        return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
ho provato a sostituire 7fff con un numero piu' grande ma il risultato e'
stato
che genera soltanto numeri vicini al massimo o al minimo.
grazie in anticipo a chi puo' aiutarmi
Ino

 stato che genera soltanto numeri vicini al massimo o al minimo.
0x7fff serve a mascherare il bit piů alto, quello del segno. Cambiando
il mask ottieni solo di alterare il risultato...
Potresti scalare il risultato di rand(), no? 
long res;
res = rand() * (1000000L/RAND_MAX);

 Anche impostando con #define  RAND_MAX F4240 non cambia niente.
Per forza; RAND_MAX non e' una costante che va impostata per
ridefinire il range possibile dei numeri a caso, ma una costante
prefissata che ti comunica il range stesso.  Sarebbe come se tu,
trovando INT_MAX uguale a 32767, scrivessi
#define INT_MAX 
2147483647
e ti aspettassi che il tuo compilatore usasse in conseguenza interi di
32 bits.  Prova con
int i;
i = ((double) rand() / RAND_MAX) * 1000000.0;
-- 
Maurizio Loreti                      
http://wwwcdf.pd.infn.it/~loreti/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          
lor...@padova.infn.it

 Ino
Io, usando djgpp per win/dos, ho a disposizione la funzione non standard
random() che, se non mi sbaglio ha come intervallo 0-2^32 (o 2^31); se
puoi usare questa funzione, ti basta poi fare random()%1000001 per avere
valori tra 0 e 1000000 estremi inclusi.
Spero di esserti stato utile. Ciao,Luca.
-- 
*******************************************************
  "C'e' un vecchio detto a riguardo delle reti che    
  recita: i problemi di banda possono essere risolti  
  con il denaro. I problemi di latenza sono piu' dif- 
  ficili poiche' la velocita' della luce e' una cos-  
  tante e non e' possibile corrompere Dio."           
 
                                     David Clark, MIT 
  Reply to 
bia...@maganet.net
*******************************************************

 i = ((double) rand() / RAND_MAX) * 1000000.0;
Non vorrei sbagliare, ma non mi pare una gran soluzione, dal punto di
vista matematico. La risoluzione del generatore è sempre la stessa ma
viene "sgranata" in un intervallo più grande portando una perdita di
qualità nella sequenza generata. Dico fesserie?
EMG

res = rand() * (1000000L/RAND_MAX);
Credo di no.
Ho il dubbio che questa formula crei una perdita di precisione molto forte.
La perdita di precisione deriva dal fatto che viene compiuta la seguente
divisione 1000000L/32767 = 30.
Stando cosi' le cose dovrebbero esserci 29 numeri non generati per ogni numero
generato.
Dato che il risultato di rand(), in questo caso, e' compreso tra 0 e 32767, ci
sono 29*32768 = 950272 valori non generati (!).
Andrea Laforgia
-------------------------------------
(grattatio pallarum omnia mala fugit)

 sono 29*32768 = 950272 valori non generati (!).
Infatti ho commesso una piccola (piccola si fa per dire:-))
imprecisione... un principio che non può essere proprio applicato ai
numeri casuali.
Occorre riscrivere una funzione rand() che restituisca un corretto
numero pseudocasuale a 32bit.

 qualità nella sequenza generata. Dico fesserie?
Nessuna fesseria, hai perfettamente ragione. Avevo padellato anch'io, la
cosa non puo' essere applicata nel caso dei numeri casuali.
esempio:
per rand() che restituisce 0 abbiamo:
i = 0
per rand() che restituisce 1 abbiamo:
i = 1 / 32767 * 1000000 = 31
e i numeri da 1 a 30 quando escono? :-)

 
Cosa ne dite di:
long Rand30(void)  // numeri random su 30 bits
{
  return (rand()|(rand()<<15));
}

 valori tra 0 e 1000000 estremi inclusi.
Credo che neanche questa sia una buona soluzione in quanto altera la
distribuzione dei numeri casuali generati.
EMG

Se non si deve calcolare ad intervalli regolari questo dovrebbe lavorare +
che bene:
sin(clock())*1000000;
CIAO
Alberto Chessa ha scritto nel messaggio
<01be6efb$f68dfe20$92c809c0@chessa>...


> Io, usando djgpp per win/dos, ho a disposizione la funzione non standard


Io, invece, credo che la soluzione di Bianco sia giusta.
D'altronde e' lo stesso metodo usato per rand().


}
La "libc" riporta :
"Note that the low bits of the `rand''s return value are not very random, so
`rand()%N' for small values of N could be not enough random."
Bisognerebbe vedere *quanto* random e' il numero generato.


 }
Uhm, il concetto già mi sembra molto meglio: costruire il numero casuale
finale generando separatamente le sue parti.
EMG

 Io, invece, credo che la soluzione di Bianco sia giusta.
Chiaramente posso sbagliare ma temo che quel metodo funzionerebbe bene
(cioè non altererebbe la distribuzione dei numeri casuali generati) solo
se il numero dopo il segno di modulo (%) fosse un sottomultiplo del
numero massimo generato dalla funzione random(), nel nostro caso quindi
solo se dopo il segno di modulo mettiamo una potenza di due. Qualcuno
può confermare o smentire?
EMG

 EMG


sin(clock())*1000000;
Le sequenze generate in questo modo NON sono ripetibili.

questa soluzione e' andata benissimo.
grazie a tutti.
Ino
