2014-10-05 19 views
15

W rand() considered harmful wskazuje się, że srand(time(NULL)) jest złe, ponieważ srand pobiera unsigned int, ale dla kompilatora Microsoftu domyślnie time_t jest liczbą 64-bitową, dlatego następuje konwersja zawężająca. Jednak time_t jest zdefiniowany przez implementację.Czy srand (time (NULL)) jest zły?

Od kiedy widzę srand(time(NULL)) tak rozpowszechniony (nawet na tej stronie), czy należy go zniechęcać?

+1

Są lepsze sposoby randomizacji, dlaczego nie skorzystać z nich? –

+7

Chodzi o najlepsze, co możesz zrobić w C, a nawet w C++ 98/03. C++ 11 dodał nowy nagłówek '' z nowymi możliwościami generowania liczb losowych znacznie poprawia sytuację. –

+0

Chociaż prawda, Boost ma lepsze PRNG, które działają w C++ 98. – chris

Odpowiedz

10

Ponieważ widzę srand (czas (NULL)) tak powszechne (nawet na tej stronie), czy należy go zniechęcać?

To zależy od sposobu użycia wyjścia z generatora (w tym przypadku wyjście z rand()).

Jeśli potrzebujesz tylko jednolitego rozkładu dla pojedynczych przebiegów twojego programu, wtedy srand(time(NULL)) jest w porządku. Byłoby to dopuszczalne w symulacji, w której potrzebny jest tylko jednolity podział liczb.

Jeśli chcesz przesłać zadanie wsadowe, aby wiele wystąpień programu zostało uruchomionych w tym samym czasie (i które zostały skutecznie uruchomione w tym samym czasie), to prawdopodobnie srand(time(NULL)) spowoduje, że jedno lub więcej wystąpień wygeneruje ten sam losowy strumień .

Jeśli potrzebujesz bezpiecznego wyjścia, powinieneś nie użyć srand(time(NULL)), ponieważ często jest to Linear Congruential Generator (LCG). Joan Boyar nauczył nas, jak je łamać lata temu. Zobacz Inferring sequences produced by a linear congruential generator missing low-order bits.

Jeśli chodzi o problem z time_t, po prostu złóż go, aby dopasować argument do oczekiwanego przez srand, jeśli time_t jest zbyt duży. Możesz nawet złożyć PID procesu, aby zadania symulacji wsadowej działały zgodnie z założeniami/oczekiwaniami.

+2

Gdy '/ dev/urandom' nie jest dostępny, aby uczynić ziarno trudniejszym do odgadnięcia i uniknąć kolizji, Perl miesza identyfikator procesu, wskaźnik stosu i czas (najlepiej sekundy + mikrosekundy od gettimeofday). http://perl5.git.perl.org/perl.git/blob/v5.20.1:/util.c#l4409 – Schwern

Powiązane problemy