Newsgroup: it.comp.lang.c
Titolo: limite superiore numeri casuali (RAND_MAX)

Salve a tutti,
 avrei la necessita' di generare numeri pseudo-casuali tra 0 e N con N
molto elevato (decine di milioni).
Sotto Linux non ho problemi perche' vedo che RAND_MAX=
2147483647
, ma
sotto Win trovo RAND_MAX circa 32767. ( 0x7FFF).
Questo guardando negli stdlib.h sia di VC++ del DevC.
Possibile ?
Come potrei risolvere ?
Grazie.
P.S. Se e' vero quello che ho detto (spero di aver sbagliato
qualcosa), mi piacerebbe anche "semplicemente" sapere come mai questa
differenza tra i due SO.

 Come potrei risolvere ?
Non ho sottomano i vari compilatori per win/dos che citi,
Comunque mi stupirei che non ci fosse sotto devc o vc qualcosa
per generare numeri piu' grossi.
Credo che solo le librerie accluse ai compilatori piu' vecchi usassero
dei rand cosi' corti.
Prova a cercare col help random() o lrand48() per vedere
se li hai e se sul tuo compilatore fanno qualcosa di diverso.
In ogni caso, se vuoi generare numeri piu' grossi (diciamo
fino a 2^30  puoi fare cosi'
usi il tuo rand azzoppato 3 volte, ogni volta generi
quindi 15 bit e prendi quelli piu' o meno in mezzo per evitare eventuali
problemi sui bit bassi e poi moltiplichi:
#define Dieci() ((rand()>>3)&1023)
int MyRand() { return Dieci()+(Dieci()<<10)+(Dieci()<<20); }
ciao,
g.


Non dipende dal sistema operativo ma dal compilatore. Ad esempio, nel
file STDLIB.H del GCC trovo
#define RAND_MAX 
2147483647
mentre in quello del Borland
#define RAND_MAX 0x7FFFU
ma poi dice che si può utilizzare la funzione (non standard) _lrand() (o
la macro random()) per ottenere
#define LRAND_MAX 0x7FFFFFFFU
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 Come potrei risolvere ?
Cito a memoria, potrei sbagliarmi:
double d = (rand()/(duoble)RAND_MAX-1)
Se non ho fatto errori stupidi, cosi' ottieni un numero casuale tra 0 e 1, 
dopo di che generi quanti numeri casuali vuoi e con una distribuzione 
uniforme, nel limite della dimensione massima dei tipi che hai a 
disposizione ovviamente.
Ccontrolla il tipo intero piu' grande e la parte intera rappresentabile con 
un double per scoprire il massimo, ora come ora non ho voglia di 
controllare per te, c'e' gia' calcolo numerico che mi opprime :P
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 disposizione ovviamente.
La soluzione che suggerisci e' sbagliata per 2 ragioni.
(Qui stiamo supponendo che RAND_MAX sia 0x7fff cioe' 32767)
1) le parentesi sono messe male e devi fare +1 non -1,
    quindi caso mai dovresti fare qualcosa tipo
    rand()/(RAND_MAX+1.0) e comunque ottieni un numero casuale tra 0 e 1
    (escluso 1, questo e' importante in molte applicazioni,
     ed e' il motivo del +1)
2) il numero che ottieni in questo modo e' casuale, ma per come e'
    ottenuto non puo' avere piu' di 15 bit casuali. Quindi quando
    l'autore del post originario lo moltiplica per un numero grosso
   (decine di milioni, quindi numeri con almeno 23 bit) ottiene un numero
    i cui ultimi bit non sono affatto casuali. (e in particolare, siccome
    abbiamo al massimo 32767 numeri tra 0 e 1 ottenuti in questo modo al
    massimo otterreno 32767 numeri tra 0 e, supponiamo, 10 milioni, il
    che' e' un po' pochino.
ciao,
g.
Per esempio, supponi che

     che' e' un po' pochino.
Su questo non ci avevo pensato, comunque e' un buon punto di partenza :)
Mi pare che ci siano algoritmi comunque migliori da utilizzare, magari qui 
puo' trovare spunto 
http://www.library.cornell.edu/nr/bookcpdf.html
