Re: inclusive rand
by LanX (Sage) on Mar 13, 2017 at 12:40 UTC

> Naturally, the probability of getting 1 is 0 anyway, so this has little practical use, but I'm curious.
But that's exactly the point, because in practical use you want an "integer resolution". (don't know how to phrase it better, look at the examples)
This will produce all values between 0 and 10 inclusively perl E"say int rand(11) for 1..20"
and this will produce them between 0 and 1 inclusively in 0.1 steps
C:\Windows\system32>perl E"say 0.1 * int rand(11) for 1..20"
just improve the resolution if 0.1 is not enough, like in
C:\Windows\system32>perl E"say 1e6 * int rand(1e6+1) for 1..20"
edit
or with full abstraction
perl E" $res=1e6; say 1/$res * int rand($res+1) for 1..20"
Please keep in mind that this is not cheating because in perl floats don't have anything like an infinite resolution.
That's why the probability is not 0 like you thought.
Cheers Rolf
_{(addicted to the Perl Programming Language and ☆☆☆☆ :)
Je suis Charlie!
}
 [reply] [d/l] [select] 

 [reply] [d/l] [select] 

Personally I'd make sure to stay below the precision of rand, to avoid skewing the probabilities because of the multiple operations (multiplication, rounding, division) and the error they may imply. Besides, there's nothing particularily significant about the precision of rand, it's probably around the best possible precision on a float. And you could actually get a better resolution than rand with Crypt::Random.
 [reply] 


You were clear and you are wrong to believe computer can produce any real numbers. (see also my update)
We can only approximate them with floats, e.g. you will never get a the real pi, just because for instance nobody can ever finish printing a number with an infinite amount of digits.
This means you can only operate on rational numbers with a chosen resolution.
update
OP changed text of Re^2: inclusive rand . I'm giving up.
Cheers Rolf
_{(addicted to the Perl Programming Language and ☆☆☆☆ :)
Je suis Charlie!
}
 [reply] 


 [reply] 





Re: inclusive rand
by BrowserUk (Patriarch) on Mar 13, 2017 at 13:48 UTC

If you multiply rand by 101, int it, then divide by 100, you'll get all possible (2decimal place) values between 0 and 1 inclusive with 'equal probability':
If you need 3 decimal places, use 1000*int( rand *1001 ); and for 4: 10000*int( rand * 10001 ) etc. Corrected. Thanks to pryrt.
If you need 3 decimal places, use int( rand *1001 )/1000; and for 4: int( rand * 10001 )/10000 etc.
(But beware the number of bits available in the rand() you use. On Windows, pre5.20something, perl's rand() only has 15bits. )
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.
In the absence of evidence, opinion is indistinguishable from prejudice.
 [reply] [d/l] 

"... use 1000*int( rand *1001 ); and for 4: 10000*int( rand * 10001 ) etc." doesn't match the first paragraph, where you multiply by the bigger and divide by the smaller; here, you multiplied twice. I believe it should be, "... use int( rand *1001 )/1000; and for 4: int( rand * 10001 )/10000 etc."?
 [reply] 

 [reply] 

 [reply] [d/l] 
Re: inclusive rand
by Eily (Monsignor) on Mar 13, 2017 at 12:46 UTC

my $precision = 8;
for (0..20)
{
my $var = int(rand($precision));
print $var/($precision1), "\n";
}
Even if the output of rand is not an int, it still is one value among a list of possible ones. Here that fact is explicit rather than implicit, and you get to chose the size of that list.
Maybe Crypt::Random would be a better fit, since you provide a length in bits for the random number, you just have to map 0 to 0, and ~0 to 1 (ie, divide the big unsigned int by the max value).  [reply] [d/l] 

 [reply] [d/l] [select] 
Re: inclusive rand
by Discipulus (Canon) on Mar 13, 2017 at 12:37 UTC

hello msh210
beside rand and srand Math::Random::MTwist can be of your interest.
Also Re: rand() function on Windows systems can be an interesting read.
PS also note that int(rand(2)) return an integer from 0 to 1
PPS ok i misunderstood your question; marioroy offered a valid option
L*
There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
 [reply] [d/l] [select] 

 [reply] [d/l] 
Re: inclusive rand
by vrk (Chaplain) on Mar 13, 2017 at 17:09 UTC

A bit of probability theory: if X has the Uniform(0,1) distribution, the support (range) is [0,1]. If the support is actually [0,1), then the distribution is actually Uniform(0, 1epsilon) for some small epsilon. In this case, if you knew what epsilon is, you could scale by the width of the support to get Y = X/(1  epsilon  0) = X/(1  epsilon) and Y would have true Uniform(0,1) distribution.
As others have pointed out, there are a number of factors involved and epsilon likely isn't just the machine epsilon or unit roundoff. Besides, even if it were, see pryrt's reply Re^6: inclusive rand. The figure in question is too small; on normal floating point hardware, dividing by 1epsilon would be no different from dividing by 1.
 [reply] 

use strict;
use warnings;
use List::MoreUtils qw(uniq);
use List::Util qw(min);
my @samples = sort { $a <=> $b } uniq map {rand} 1..3000;
print scalar @samples, " unique samples.\n";
print "The minimum difference is ", min map { $samples[$_]  $samples[
+$_1] } 1..$#samples;
__END__
2861 unique samples.
The minimum difference is 3.0517578125e005
 [reply] [d/l] 
Re: inclusive rand
by marioroy (Parson) on Mar 13, 2017 at 12:46 UTC

 [reply] 

 [reply] [d/l] [select] 

use strict;
use warnings;
use Math::Random::Secure 'irand';
# Random number between 0 and 1 inclusive (total 5242881 numbers).
sub custom_rand {
irand(524288) / 524287;
}
printf("%f\n", custom_rand()) for 1 .. 20;
Regards, Mario.
Edit: Applied correction. Thanks pryrt.  [reply] [d/l] 



 [reply] 