Why doesn't rand ($ val) warn when $ val> 2 ** randbits?

I use to create some fake data using callbacks . After I was a bit puzzled, I found that since my perl , the above expression returns only or possible values.Strawberry Perl v5.16.2int rand 1_000_000randbits=152**1532768

>perl -V:randbits
randbits='15';

My questions:

  • Why use warnings;doesn't it return a warning when someone tries to use rand $valwhere $val > 2 ** randbits?
  • Why perldoc randdoesn't he mention this problem at all? There is an addition on how "rand() is not cryptographically secure". I believe that this also deserves to be added with the proposed alternative solutions.

Customization

I am trying to create some fake data in order to test the algorithm for sorting large amounts of data with an average of 20 duplicates. This worked great for 1,000 and 10,000 records, but when I jumped to 1 million, I found that I lacked unique values.

It seemed statistical improbability. The likelihood pthat a particular integer less than 1 million will not be selected in 20 million extrusions is (999_999/1_000_000) ** 20_000_000or 2.06e-9. Therefore, the probability that any integer will not be selected is equal .2%.

I quickly hacked another script to confirm that there were no flaws in my fake data generator:

use strict;
use warnings;

use List::Util qw(sum max min);

our $max_count = 1_000;

my %count;

while (1) {
    my $val = int rand 1_000_000;
    last if ++$count{$val} > $max_count;
}

my $sum = sum values %count;
my $max = max values %count;
my $min = min values %count;
my $count = scalar keys %count;

print "$sum interations.  $count integers of expected 1mil with min $min, max $max\n";

Outputs:

28,958,579 interations.  32768 integers of expected 1mil with min 772, max 1001

, 32,768 , 2, google "perl rand does maximum 32768 integers" :

rand use Math::Random::MT qw(rand); use Math::Random::MT::Auto qw(rand);.

SO an answer, , , rand .

use Config;
use constant RANDBITS => $Config{randbits};
use constant RAND_MAX => 2**RANDBITS;

sub double_rand {
    my $max = shift || 1;
    my $iv  =
          int rand(RAND_MAX) << RANDBITS
        | int rand(RAND_MAX);
    return $max * ($iv / 2**(2*RANDBITS));
}

, . , ...

  • rand?
  • perldoc rand?
  • warnings , 2**randbits? - , no warnings 'rand' rand : val * rand.
  • Strawberry Perl , randbits? ? ?

.

+4
3

perl.

perl v5.20 - perldelta

  • rand

    perl , , libc rand(), random() drand48().

    , perl , 15 rand() Windows 48 POSIX, Linux drand48().

    Perl drand48() . perl rand. [perl # 115928]

, perl rand, , 2 ** randbits, , .

- Windows , use Math::Random::MT qw(rand);, .

0

CPAN, , . Math:: BigInt:: Random .

0

For non-cryptographic purposes, use Math :: Random :: MT . Mersenne Twister PRNG has nice properties.

You can use the functional interface as a replacement for randbuiltin:

Feature Oriented Interface:

use Math::Random::MT qw(srand rand irand);
# now use srand() and rand() as you usually do in Perl
0
source

Source: https://habr.com/ru/post/1534329/


All Articles