Path: utzoo!mnetor!tmsoft!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!uwm.edu!psuvax1!news From: flee@cs.psu.edu (Felix Lee) Newsgroups: comp.lang.perl Subject: Re: random numbers? Message-ID: <3#3Gz8.j@cs.psu.edu> Date: 10 Feb 91 16:36:24 GMT References: <16698@venera.isi.edu> Sender: news@cs.psu.edu (Usenet) Organization: Penn State Computer Science Lines: 50 Nntp-Posting-Host: dictionopolis.cs.psu.edu >Is there some problem with perl's srand and rand functions? srand() with no arguments does srand(time), and the current time of day is not a very good seed. One problem is it doesn't change quickly enough. The following: #!/bin/csh -f repeat 10 perl -e 'srand; printf "%.3f ", rand(10);' will tend to print things like: 3.158 3.158 8.296 8.296 8.296 8.296 8.296 8.296 3.435 3.435 All the "8.296"s were produced in the same second. Another problem is the current time of day is monotonically increasing. rand() is a simple linear congruential random number generator (LCRG), typically something like this: seed = (seed * 1103515245 + 1234) & 0x7fffffff; return seed; Perl takes this result and divides it by 2**31, turning it into a floating point number between 0 and 1. A simple linear function applied to simple, monotonically increasing values will produce simple results. The following: #!/usr/bin/perl for $s (1..10) { srand $s; for (1..8) { printf "%.3f ", rand(10); } print "\n"; } will print something like: 5.139 1.757 3.087 5.345 9.476 1.717 7.022 2.264 0.277 6.963 3.125 3.941 7.885 8.269 9.148 8.504 5.416 2.169 3.163 2.537 6.293 4.821 1.274 4.743 0.555 7.375 3.202 1.133 4.702 1.372 3.399 0.983 5.693 2.581 3.240 9.728 3.111 7.924 5.525 7.223 0.832 7.787 3.278 8.324 1.519 4.475 7.651 3.462 5.971 2.993 3.317 6.920 9.928 1.027 9.776 9.702 1.109 8.199 3.355 5.515 8.336 7.579 1.902 5.941 6.248 3.404 3.393 4.111 6.745 4.130 4.027 2.181 1.386 8.610 3.432 2.707 5.154 0.682 6.153 8.421 Note how predictable each column is, especially column 3. Doing something like: srand(time + 251 * $$); rand; rand; rand; srand(rand(32767)); makes the problem less apparent. But LCRGs suffer from many flaws. Avoid rand() if you want good random numbers. -- Felix Lee flee@cs.psu.edu