'How to best create a random float in a range between two floats
I know that I can generate random floats with rand(max). I tried to generate a float in a range, this shouldn't be hard. But e.g rand(1.4512) returns 0, thus rand isn't calculating with floats. Now I tried a little trick, converting the thing to an integer and after randomizing a fitting number in my desired range, calculating it back to a float.. which is not working.
My question is how to do this in a better way. If there is no better way, why is this one not working? (Maybe it's too late for me, I should've started sleeping 2 hours ago..). The whole thing aims to be a method for calculating a "position" field for database records so users can order them manually. I've never done something like this before, maybe someone can hint me with a better solution.
Here's the code so far:
def calculate_position(@elements, index)
min = @elements[index].position
if @elements[index + 1].nil?
pos = min + 1
else
pos = min + (rand(@elements[index + 1].position * 10000000000) / 10000000000)
end
return pos
end
Solution 1:[1]
Let's recap:
rand() will generate a (psuedo-)random float between 0 and 1.
rand(int) will generate a (psuedo-)random integer between 0 and int.
So something like:
def range (min, max)
rand * (max-min) + min
end
Should do nicely.
Update:
Just tested with a little unit test:
def testRange
min = 1
max = 100
1_000_000.times {
result = range min, max
print "ERROR" if result < min || result > max
}
end
Looks fine.
Solution 2:[2]
Pass a range of floats to rand
If you want to "create a random float in a range between two floats", just pass a range of floats to rand.
rand(11.2...76.9)
(Tested with Ruby 2.1)
Edit
According to the documentation: https://ruby-doc.org/core-2.4.0/Random.html
There are two different ways to write the random function: inclusive and exclusive for the last value
rand(5..9) # => one of [5, 6, 7, 8, 9]
rand(5...9) # => one of [5, 6, 7, 8]
rand(5.0..9.0) # => between 5.0 and 9.0, including 9.0
rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0
Solution 3:[3]
In 1.9 and 2.0 you can give a range argument to rand:
irb(main):001:0> 10.times { puts rand Math::E..Math::PI }
3.0656267148715446
2.7813979580609587
2.7661725184200563
2.9745784681934655
2.852157154320737
2.741063222095785
2.992638029938756
3.0713152547478866
2.879739743508003
2.7836491029737407
=> 10
Solution 4:[4]
I think your best bet is to use rand() to generate a random float between 0 and 1, and then multiply to set the range and add to set the offset:
def float_rand(start_num, end_num=0)
width = end_num-start_num
return (rand*width)+start_num
end
Note: since the order of the terms doesn't matter, making end_num default to 0 allows you to get a random float between 0 and x with float_rand(x).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | G M |
| Solution 3 | Sandor Bedo |
| Solution 4 |
