in reply to Old random number generator
Is there a way to get the old behavior back?
From what little I can tell from this, it may still be possible to compile Perl on Windows to use the old way. But that seems overly complex.
I have a few programs that depend upon generating repeatable pseudorandom number sequences.
The new random number generator still does this, it's even more reliable because it'll be the same no matter what platform. So I suspect that's not really your point - I suspect you've got code that is depending on a certain sequence of random numbers? Note that, in general, this isn't reliable anyway, since AFAICT, Perl before 5.20 didn't guarantee a certain algorithm to be used. What you probably really want is a PRNG with a known algorithm.
Before 5.20, srand 0;print rand in Strawberry Perl always gave me 0.00115966796875.
Well, the following appears to work (after installing Microsoft Visual C++ 2010 Redistributable Package (x64); I'm not a Windows expert so maybe there's a better way*) - at least for the single value you provided. But again, you're probably better off choosing a known PRNG instead, possibly from CPAN.
use warnings; use strict; use Win32::API; my $srand = Win32::API::More->new( 'msvcr100', 'void srand(unsigned int seed)' ) or die "Error: ".Win32::FormatMessage(Win32::GetLastError()); my $rand = Win32::API::More->new( 'msvcr100', 'int rand()' ) or die "Error: ".Win32::FormatMessage(Win32::GetLastError()); $srand->Call(0); print $rand->Call()/(1<<15), "\n"; # 0.00115966796875
* Update: I can confirm that 'msvcrt' instead of 'msvcr100' works for me as well, thanks syphilis! /Update
And after a bit of digging, the Linear congruential generator that Windows uses can be reimplemented in Perl:
sub winrand { use feature 'state'; state $r = 0; # seed $r = ( 214013*$r + 2531011 ) & 0xFFFFFFFF; return ($r>>16)&0x7FFF; }
The output of this function can be used in the same way, i.e. the first call to winrand()/(1<<15) also produces 0.00115966796875, and further calls to winrand() produce the same as $rand->Call() in the above code. Note I've only tested this on a 64-bit Perl.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Old random number generator
by syphilis (Archbishop) on May 10, 2020 at 00:47 UTC | |
|
Re^2: Old random number generator
by Pascal666 (Scribe) on May 10, 2020 at 02:45 UTC | |
by syphilis (Archbishop) on May 10, 2020 at 04:26 UTC | |
by Pascal666 (Scribe) on May 10, 2020 at 04:45 UTC | |
by syphilis (Archbishop) on May 10, 2020 at 06:47 UTC | |
by bliako (Abbot) on May 10, 2020 at 09:54 UTC | |
by choroba (Cardinal) on May 11, 2020 at 22:42 UTC |