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