2014-10-05 3 views
15

In rand() considered harmful è stato rilevato che srand(time(NULL)) è errato perché srand prende uno unsigned int, ma per il compilatore Microsoft, time_t per impostazione predefinita è un numero a 64 bit, pertanto si verifica una conversione di riduzione. Tuttavia, time_t è definito dall'implementazione.È srand (time (NULL)) non valido?

Dal momento che vedo srand(time(NULL)) così prevalente (anche su questo sito), dovrebbe essere scoraggiato?

+1

Ci sono modi migliori di randomizzare, perché non usarli? –

+7

È il meglio che puoi fare in C, o anche in C++ 98/03. C++ 11 ha aggiunto una nuova intestazione '' con nuove funzionalità di generazione di numeri casuali per migliorare la situazione in modo sostanziale. –

+0

Mentre vero, Boost ha migliori PRNG che funzionano in C++ 98. – chris

risposta

10

Dal momento che vedo srand (time (NULL)) così diffuso (anche su questo sito), dovrebbe essere scoraggiato?

Dipende da come si desidera utilizzare l'uscita dal generatore (in questo caso, l'output di rand()).

Se è necessaria una distribuzione uniforme per le singole sessioni del programma, allora srand(time(NULL)) va bene. Ciò sarebbe accettabile in una simulazione in cui è necessaria solo una distribuzione uniforme dei numeri rapidamente.

Se si desidera inviare un processo batch in modo che più istanze del programma vengano eseguite contemporaneamente (e che vengano effettivamente avviate contemporaneamente), quindi genererà probabilmente una o più istanze che producono lo stesso flusso casuale .

Se è necessaria un'uscita protetta, è necessario non utilizzare srand(time(NULL)) perché è spesso un generatore di linea lineare (LCG). Joan Boyar ci ha insegnato come rompere loro anni fa. Vedi Inferring sequences produced by a linear congruential generator missing low-order bits.

Per quanto riguarda il problema con time_t, basta piegarlo per adattarlo all'argomento previsto da srand se time_t è troppo grande. Si potrebbe persino piegare il processo PID in modo che i lavori di simulazione batch funzionino come previsto/previsto.

+2

Quando '/ dev/urandom' non è disponibile, per rendere il seed più difficile da indovinare e per evitare collisioni, Perl mischia l'ID del processo, un puntatore stack e il tempo (preferibilmente secondi + microsecondi dal gettimeofday). http://perl5.git.perl.org/perl.git/blob/v5.20.1:/util.c#l4409 – Schwern