Random#rand_inclusive?

Hi,

Random#rand and Kernel#rand are exclusive i.e. they return a value >=
0.0
but <max if max is a Float. What if one wants a rand that is inclusive
of
the max? Would any of the below approaches guarantee to give an
inclusive
range?

class Random

Return a random number between 0 (inclusive) and max (inclusive).

def rand_incl(max = 1.0)
if Float === max
rand(max+Float::EPSILON)
elsif Integer === max
rand(max+1)
end
end

Same but with other strategy

def rand_incl2(max = 1.0)
if Float === max
num_floats = (max - min)/Float::EPSILON
min + rand(1+num_floats.to_i) * Float::EPSILON
elsif Integer === max
min + rand(max+1-min)
end
end
end

Thanks in advance,

Robert F.

OTOH, without looking up exactly what Epsilon is (the smallest possible
absolute interval represented by a float?), wouldn’t your technique fail
if
max is big, because {big float} + {small float} = {big float} ? I’d
suggest something clever with Rationals, personally, along the lines of
`(max*rand(range+1))/range"

Sent from my phone, so excuse the typos.

On Thu, Mar 7, 2013 at 8:55 AM, Robert F. [email protected]
wrote:

Random#rand and Kernel#rand are exclusive i.e. they return a value >= 0.0
but <max if max is a Float. What if one wants a rand that is inclusive of
the max? Would any of the below approaches guarantee to give an inclusive
range?

I don’t think there is any good way to achieve that for floats. You
could try rounding but this would effectively mean to reduce the
number of significant decimals.

def rand_incl(float, decimals = 10)
rand(float).round(decimals)
end

I would have to reason a bit longer about what that does to
statistical distribution of values. It might still not be exactly
evenly distributed - especially since the edge values have fewer
values to round to (i.e. negatives are missing and values >= max).
Nah, forget it: does not look like a good idea.

Kind regards

robert

On 7 March 2013 17:55, Robert F. [email protected] wrote:

Random#rand and Kernel#rand are exclusive i.e. they return a value >= 0.0
but <max if max is a Float. What if one wants a rand that is inclusive of
the max?

I’m back at a computer now, and have looked up the docs for Random#rand.
Apparently in 2.0 you can simply pass an inclusive range and it will do
what you want, e.g.: Random.rand(0.0…max) <
Class: Random (Ruby 2.0.0)>

However in 1.9, yeah, your rand_incl2 is basically what I’d do. I
independently came up with a simplified version:
https://gist.github.com/phluid61/5107356

Thanks Matthew, didn’t know that about 2.0.

Cheers,

Robert

On Thu, Mar 7, 2013 at 12:21 PM, Matthew K.
[email protected]wrote:

what you want, e.g.: Random.rand(0.0…max) <
Class: Random (Ruby 2.0.0)>

However in 1.9, yeah, your rand_incl2 is basically what I’d do. I
independently came up with a simplified version:
https://gist.github.com/phluid61/5107356


Best regards,

/Robert F.

Tech. Dr. (PhD), Assoc. Professor in Software Engineering
Chalmers, Software Engineering Dept
Blekinge Institute of Technology, Software Engineering Research Lab
robert.feldt (a) chalmers.se or robert.feldt (a) gmail.com
Mobile phone: +46 (0) 733 580 580
Robert Feldt - Homepage