tags:

views:

275

answers:

3

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

Thanks!

+2  A: 

It's an interesting little quirk, if you divide by a Fixnum you get a Fixnum. If you divide by a Float you'll get a Float.

To get a random number between 0.00 and 1.00, try something like this:

rand(100) / 100.0

(depends on how many decimal places you want)

dustmachine
+7  A: 

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.

Josh
+2  A: 

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).

Harpastum