diff options
author | Karl Williamson <khw@khw-desktop.(none)> | 2010-07-27 08:18:25 -0600 |
---|---|---|
committer | Rafael Garcia-Suarez <rgs@consttype.org> | 2010-07-28 10:07:23 +0200 |
commit | 83832992940e343002e924b1307988d2604ee165 (patch) | |
tree | 6ead241b56a400abd516361b20cf2236859d75c4 | |
parent | 401a9b146916c60dc9bbd897355c3c83888d61f3 (diff) | |
download | perl-83832992940e343002e924b1307988d2604ee165.tar.gz |
srand: change to return its seed
This commit changes srand to to return the seed instead of always
returning 1. The motivation behind this is to allow applications to not
have to come up with their own pseudo-random generator if they want
repeatable results.
The previous return behavior has never been documented. Note that it is
possible, but very unlikely, for the seed to end up being 0, which means
that if someone were relying on the undocumented previous behavior of
srand returning true, that in very rare instances it would return 0,
failing, and the next time they ran it, it would succeed, possibly
leading to puzzlement and very rare unexplained failures.
-rw-r--r-- | opcode.h | 2 | ||||
-rwxr-xr-x | opcode.pl | 2 | ||||
-rw-r--r-- | pod/perl5134delta.pod | 10 | ||||
-rw-r--r-- | pod/perlfunc.pod | 51 | ||||
-rw-r--r-- | pp.c | 6 |
5 files changed, 43 insertions, 28 deletions
@@ -1658,7 +1658,7 @@ EXTCONST U32 PL_opargs[] = { 0x0001378e, /* sin */ 0x0001378e, /* cos */ 0x0001370c, /* rand */ - 0x00013604, /* srand */ + 0x0001370c, /* srand */ 0x0001378e, /* exp */ 0x0001378e, /* log */ 0x0001378e, /* sqrt */ @@ -757,7 +757,7 @@ atan2 atan2 ck_fun fsT@ S S sin sin ck_fun fsTu% S? cos cos ck_fun fsTu% S? rand rand ck_fun sT% S? -srand srand ck_fun s% S? +srand srand ck_fun sT% S? exp exp ck_fun fsTu% S? log log ck_fun fsTu% S? sqrt sqrt ck_fun fsTu% S? diff --git a/pod/perl5134delta.pod b/pod/perl5134delta.pod index 356a247e01..f7e76bd923 100644 --- a/pod/perl5134delta.pod +++ b/pod/perl5134delta.pod @@ -38,6 +38,16 @@ C<\N{}>, C<charnames::vianame>, C<charnames::viacode> now know about every character in Unicode. Previously, they didn't know about the Hangul syllables nor a number of CJK (Chinese/Japanese/Korean) characters. +=head2 C<srand()> now returns the seed + +This allows programs which need to have repeatable results to not have to come +up with their own seed generating mechanism. Instead, they can use C<srand()> +and somehow stash the return for future use. Typical is a test program which +has too many combinations to test comprehensively in the time available to it +each run. It can test a random subset each time, and should there be a +failure, log the seed used for that run so that it can later be used to +reproduce the exact results. + =head1 Security XXX Any security-related notices go here. In particular, any security diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index 42095a0a25..affd834fe0 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -6157,34 +6157,34 @@ X<srand> X<seed> X<randseed> =item srand -Sets the random number seed for the C<rand> operator. +Sets and returns the random number seed for the C<rand> operator. The point of the function is to "seed" the C<rand> function so that C<rand> can produce a different sequence each time you run your -program. - -If srand() is not called explicitly, it is called implicitly at the -first use of the C<rand> operator. However, this was not true of -versions of Perl before 5.004, so if your script will run under older -Perl versions, it should call C<srand>. - -Most programs won't even call srand() at all, except those that -need a cryptographically-strong starting point rather than the -generally acceptable default, which is based on time of day, -process ID, and memory allocation, or the F</dev/urandom> device -if available. You may also want to call srand() after a fork() to -avoid child processes sharing the same seed value as the parent (and -consequently each other). - -You can call srand($seed) with the same $seed to reproduce the -I<same> sequence from rand(), but this is usually reserved for -generating predictable results for testing or debugging. -Otherwise, don't call srand() more than once in your program. - -Do B<not> call srand() (i.e., without an argument) more than once per +program. When called with a parameter, C<srand> uses that for the seed; +otherwise it (semi-)randomly chooses a seed. In either case, starting with +Perl 5.14, it returns the seed. + +If C<srand()> is not called explicitly, it is called implicitly without a +parameter at the first use of the C<rand> operator. However, this was not true +of versions of Perl before 5.004, so if your script will run under older +Perl versions, it should call C<srand>; otherwise most programs won't call +C<srand()> at all. + +But there are a few situations in recent Perls where programs are likely to +want to call C<srand>. One is for generating predictable results generally for +testing or debugging. There, you use C<srand($seed)>, with the same C<$seed> +each time. Another other case is where you need a cryptographically-strong +starting point rather than the generally acceptable default, which is based on +time of day, process ID, and memory allocation, or the F</dev/urandom> device +if available. And still another case is that you may want to call C<srand()> +after a C<fork()> to avoid child processes sharing the same seed value as the +parent (and consequently each other). + +Do B<not> call C<srand()> (i.e., without an argument) more than once per process. The internal state of the random number generator should contain more entropy than can be provided by any seed, so calling -srand() again actually I<loses> randomness. +C<srand()> again actually I<loses> randomness. Most implementations of C<srand> take an integer and will silently truncate decimal numbers. This means C<srand(42)> will usually @@ -6216,6 +6216,11 @@ for a seed can fall prey to the mathematical property that one-third of the time. So don't do that. +A typical use of the returned seed is for a test program which has too many +combinations to test comprehensively in the time available to it each run. It +can test a random subset each time, and should there be a failure, log the seed +used for that run so that it can later be used to reproduce the exact results. + =item stat FILEHANDLE X<stat> X<file, status> X<ctime> @@ -2950,12 +2950,12 @@ PP(pp_rand) PP(pp_srand) { - dVAR; dSP; + dVAR; dSP; dTARGET; const UV anum = (MAXARG < 1) ? seed() : POPu; (void)seedDrand01((Rand_seed_t)anum); PL_srand_called = TRUE; - EXTEND(SP, 1); - RETPUSHYES; + XPUSHu(anum); + RETURN; } PP(pp_int) |