Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

rand() function on Windows systems

by bakiperl (Beadle)
on Dec 30, 2016 at 19:06 UTC ( [id://1178671]=perlquestion: print w/replies, xml ) Need Help??

bakiperl has asked for the wisdom of the Perl Monks concerning the following question:

Is there a way the rand function on the new Perl versions (5.20 and later) can replicate the same result as older Perl versions.

using the script below, older versions of Perl output a number of 56 (52) and the new versions output 466 I want the new versions to match the same result obtained using the older versions. I simply need to have access to some old data generated using the old versions. Thank you.

srand(555); my $range = 1000; my $number = int(rand($range)); print $number,"\n";

Replies are listed 'Best First'.
Re: rand() function on Windows systems
by BrowserUk (Patriarch) on Dec 30, 2016 at 20:32 UTC

    If you install Inline::C you can access the MS CRT rand() & srand() and wrap them in your own wrappers.

    The following code produces 56 (which is the same as I get from Perl's built-ins for 5.10). You might try it on your system and see how it compares:

    #! perl -slw use strict; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'END_C', NAME => 'junk1_IC', CLEAN_AFTER_BUILD => 0 +; int osrand( SV *seed ) { srand( (unsigned int)SvIV( seed ) ); return 1; } double orand( SV *max ) { return (double)rand() / 32767.0 * SvNV( max ); } END_C osrand( 555 ); print int orand( 1000 );

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Yes. That did the trick.

      Thank you BrowserUk

        Just for completeness, this pure perl version should also work:

        { my $seed; sub ppSrand{ $seed = int( $_[ 0 ] & 32767 ); } sub ppRand{ my $max = shift // 1; $seed = ( $seed * 214013 + 2531011 ); return ( ( $seed >> 16 ) & 32767 ) / 32768 * $max; ## Amend +ed per post below. } } ppSrand( 555 ); print int ppRand( 1000 );

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: rand() function on Windows systems
by LanX (Saint) on Dec 30, 2016 at 19:58 UTC
    From perl5200delta#rand-now-uses-a-consistent-random-number-generator

    • rand now uses a consistent random number generator
    Previously perl would use a platform specific random number generator, varying between the libc rand(), random() or drand48(). This meant that the quality of perl's random numbers would vary from platform to platform, from the 15 bits of rand() on Windows to 48-bits on POSIX platforms such as Linux with drand48(). Perl now uses its own internal drand48() implementation on all platforms. This does not make perl's rand cryptographically secure. perl #115928

    If you are desperate enough, try calling the original 15 bits windows version.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

Re: rand() function on Windows systems
by Laurent_R (Canon) on Dec 30, 2016 at 20:28 UTC
    So, in essence, you want your random numbers not to be random, that's a kind of oxymoron.

    Running your code on my Windows box, with ActiveState Perl v5.16.3, I get 56:

    C:\Users\Laurent>perl -e "srand(555); my $range = 1000; my $number = i +nt(rand($range)); print $number ;" 56
    On the same Windows platform, running Perl v5.14.4 under Cygwin, I get 466:
    Laurent@Laurent-HP ~ $ perl -e 'srand(555); > my $range = 1000; > my $number = int(rand($range)); > print $number,"\n";' 466
    If you really need the same pseudo-random numbers as on you old Perl version, then run your old Perl version, write the pseudo-numbers generated to a file and use the numbers in this file on your new version.

    But the bottom line is, IMHO, that you should probably not try to rely on a random number generator to give you always the same sequence of numbers.

      >  to give you always the same sequence of numbers.

      But this IS documented behavior, see srand

      The point is rather that you can't guarantee the same sequence for newer Perl versions because this would inhibit any progress.

      Progress like being OS independent.

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)
      Je suis Charlie!

        But this IS documented behavior, see srand
        Yes, Rolf, agreed. I know that if you initialize srand with a specific number, you'll be able to get repeatedly the same sequence from rand if you run it several times on the same machine with the same Perl version. This is not specific to perl, many programming languages have the same feature. And this is useful especially for some testing purposes (e.g. to be able to test the same conditions several times).

        But I said: "you should probably not try to rely on a random number generator to give you always the same sequence of numbers." The word always is important in what I meant. One should not expect the same sequence forever.

        And the possible solution I suggested relies on that: if you need the same sequence of pseudo-random integers with different Perl versions and platforms, for whatever reason,, then store that sequence somewhere and re-use it.

      I get the desired `56` on Strawberry Perl 5.10.1 Portable Edition, so if you only need a quick one-off without having to install anything, look here.

        I also got 56 on ActiveState 5.16 (and BrowserUK also, apparently), but the OP seems to be looking for 52:
        older versions of Perl output a number of 52
        I wonder which version of Perl was being used then.
Re: rand() function on Windows systems
by ikegami (Patriarch) on Jan 03, 2017 at 17:03 UTC

    If you want a specific sequence from rand, override *CORE::GLOBAL::rand with a sub that returns the series you wish to receive.

    BEGIN { my @seq = ...; *CORE::GLOBAL::rand = sub { shift(@seq) }; }
Re: rand() function on Windows systems
by LanX (Saint) on Dec 30, 2016 at 19:14 UTC
    It would surprise me if this was guaranteed behavior across Perl versions.

    > I simply need to have access to some old data generated using the old versions

    Use an old Perl version?

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1178671]
Approved by davies
Front-paged by LanX
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (11)
As of 2024-03-28 09:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found