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 Feldt
on 2013-03-07 08:56
on 2013-03-07 09:30
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 2013-03-07 10:31
On Thu, Mar 7, 2013 at 8:55 AM, Robert Feldt <robert.feldt@gmail.com> 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 2013-03-07 12:22
On 7 March 2013 17:55, Robert Feldt <robert.feldt@gmail.com> 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) < http://ruby-doc.org/core-2.0/Random.html#method-i-rand> 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
on 2013-03-07 13:02
Thanks Matthew, didn't know that about 2.0. Cheers, Robert On Thu, Mar 7, 2013 at 12:21 PM, Matthew Kerwin <matthew@kerwin.net.au>wrote: > what you want, e.g.: Random.rand(0.0..max) < > http://ruby-doc.org/core-2.0/Random.html#method-i-rand> > > 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 Feldt -- 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 http://www.cse.chalmers.se/~feldt
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.