The stupid question is the question not asked PerlMonks

### rand() precision low, looking for a fast way to get high precision rand float?

by Klaas (Initiate)
 on Oct 31, 2012 at 16:20 UTC Need Help??
Klaas has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I've got a problem with the precision of the random number generator.

I want if() to be true at a rate of 1/40.000, however, rand() is not precise enough and outputs 0 quite often (maybe a bit dept problem?). e.g.

if(rand(40.000)<1) is true ~ 100/40.000

I tried rand(n)-1>n-1, or using the Math::Random module but this does not improve the randomness enough.

Example code:
```use strict;
use warnings;

my \$time = 120;
my \$D=10000;
my \$dt=1/\$D;
my \$tt=0;
my \$rateon=1;

my \$count=0;

while(\$time>\$tt){
\$tt=\$tt+\$dt;
my \$rand = rand(\$D);
if((\$rand)<=\$rateon) {
\$count++;
printf("%f > %f\n", \$rateon, \$rand) or die \$!;
}
}
print "\$count total" or die \$!;

Thanks!

Update: This hack works, although is not ideal:

```use strict;
use warnings;

my \$time = 120;
my \$D=10000;
my \$sqrtd=sqrt(\$D);
my \$dt=1/\$D;
my \$tt=0;
my \$rateon=40;

my \$count=0;

while(\$time>\$tt){
\$tt=\$tt+\$dt;
my \$rand = rand(\$sqrtd);
my \$rand2 = rand(\$sqrtd);
if(\$rand<1 && \$rand2<1 && rand(\$rateon)<1) {
\$count++;
}
}
print "\$count total " or die \$!;

Replies are listed 'Best First'.
Re: rand() precision low, looking for a fast way to get high precision rand float?
by BrowserUk (Pope) on Oct 31, 2012 at 17:15 UTC
I want if() to be true at a rate of 1/40.000, however, rand() is not precise enough and outputs 0 quite often

That's not the way random works. It doesn't guarantee 1/40000, if it did, it would not be "random".

It only guarantees that the ratio will tend towards 1/40000 over time.

Most times it will produce 1/40000; but sometimes it will be 0/40000; sometimes 2/40000; occasionally 3/40000; very occasionally even 4/40000; but over time they will tend to balance each other out and the ratio will tend to get closer and closer to 1/40000.

Try running this for a while to see how it works:

```#! perl -slw
use strict;
use Math::Random::MT qw[ rand ];
use constant LIMIT => 1 / 40000;

\$|++;

my( \$aveTrue, \$aveFalse ) = (0,0);
while( 1 ) {
my( \$true, \$false ) = (0,0);
for( 1 .. 40000 ) {
if( rand() < LIMIT ) {
++\$true;
}
else {
++\$false;
}
}
\$aveTrue += \$true;
\$aveFalse += \$false;
printf "\rThis time: \$true/\$false; Accumulate ratio: %f / 40000",
+\$aveTrue / ( \$aveFalse / 40000 );
}

__END__
C:\test>1001701.pl
This time: 0/40000; Accumulate ratio: 0.995570 / 40000

If you need to always get one true from every 40,000, then use:

```use List::Util qw[ shuffle ];

my @numbs = shuffle 1 .. 40000;

for my \$num ( @numbs ) {
if( \$num == 1 ) {
...
}
}

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".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re: rand() precision low, looking for a fast way to get high precision rand float?
by bart (Canon) on Oct 31, 2012 at 19:53 UTC
On Windows, the random number has only 15 bits. That means that if you multiply the results with 32768, the outcome will always be an integer.

If you want something better, at least in that regard, you could pick Math::Random::MT. It's pretty fast, too.

Re: rand() precision low, looking for a fast way to get high precision rand float?
by space_monk (Chaplain) on Oct 31, 2012 at 16:37 UTC

Maybe Crypt::Random or Math::Random is the CPAN library you are looking to help you in your quest for randomness.

It's often helpful to type a few keywords into CPAN to see what libraries show up on the radar, and whether those libraries can address your problems.

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1001701]
Approved by dorko
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (10)
As of 2018-06-22 21:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Should cpanminus be part of the standard Perl release?

Results (124 votes). Check out past polls.

Notices?