2011-01-22 15 views
11

Vorrei passare al modo in cui le funzioni rand() e srand() sono implementate e vorrei modificare il codice per modificarlo in base alle mie esigenze. Dove posso trovare il codice sorgente di rand() e srand().Implementazione di Rand

risposta

9

Si prende un seme come argomento di input, di solito come segue: -

double result = srand(time(NULL)); 

e restituisce un numero casuale che aderisce alla probabilità e quindi al numero previsto di occorrenze.

da CodeGuru forums: -

void __cdecl srand (unsigned int seed) 
{ 
    #ifdef _MT 
     _getptd()->_holdrand = (unsigned long)seed; 
    #else /* _MT */ 
     holdrand = (long)seed; 
    #endif /* _MT */ 
} 

int __cdecl rand (void) 
{ 
    #ifdef _MT 
    _ptiddata ptd = _getptd(); 
    return(((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) & 
    0x7fff); 
    #else /* _MT */ 
    return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff); 
    #endif /* _MT */ 
} 

Spero che questo aiuti.

+0

Grazie a ... ma cos'è _MT ?? – nikhil

+0

Secondo questo codice 'holdrand' crescerebbe rapidamente e presto causerebbe un trabocco. 'holdrand = holdrand * 214013L + 2531011L' – orlp

+1

Informazioni su' double result = srand (time (NULL)); ': perché mai hai quel' double result'? 'srand' non ha un valore di ritorno ... –

20

rand e srand sono generalmente implementato come un semplice LCG, si può facilmente scrivere il proprio (è poche righe di codice) senza cercare le fonti di rand e srand. Nota che, se hai bisogno di numeri casuali per scopi "seri" (ad es. Crittografia), ci sono RNG molto migliori di LCG.

proposito, il C standard stesso include un esempio di implementazione rand e srand:

static unsigned long int next = 1; 

int rand(void) // RAND_MAX assumed to be 32767 
{ 
    next = next * 1103515245 + 12345; 
    return (unsigned int)(next/65536) % 32768; 
} 

void srand(unsigned int seed) 
{ 
    next = seed; 
} 
4

Quello glibc (usato da gcc) è la semplice formula:

x = 1103515245 * x + 12345 

d'involucro intorno al 2 , come mostrato here. Puoi semplicemente impostare x come seme, quindi continuare a chiamare una funzione per valutare quell'espressione (e aggiornare il seme).

Ma si dovrebbe essere consapevoli che i generatori lineari congruenti come questo sono considerati adeguati ma non ideali.

Mentre l'unico generatore di numeri casuali ideale sarebbe perfettamente casuale, il Mersenne Twister probabilmente si avvicina.

+0

s/adeguato/mediocre /, direi. –