diff options
-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) |