Thanks
Thanks

Reputation: 40339

What's the most optimal way to get a random floatingpoint number between floatA and floatB?

I have an interval consisting of two float numbers, and need to generate 20 random numbers in a look that are somewhere inbetween this interval defined by the two floats.

Lets say, for example:

float a = 12.49953f
float b = 39.11234f
float r = //best way to get best randomly numbers between a and b

The random number may be == a and == b. What would you suggest? I know that all computers and languages have problems with random numbers, and that there are many ways to generate them. But I have no experience in objective c.

It's pretty important that the numbers that are generated are not the same in one block of 20 numbers that are generated in the loop. I think for that I would make a method, put the number in an array and check if the generated number differs from all others in the array, and if it doesnt, I would generate another one.

I've tried this:

CGFloat r = 1 + arc4random() % 5;

but that will only generate integers, and most of the time I get 2 times the same random number after another.

Upvotes: 6

Views: 1417

Answers (4)

0xFADE
0xFADE

Reputation: 832

When using arc4random to get a float value it is a pretty good idea to divide it by it's maximum value. This will give you a float that ranges from 0 to 1 with a pretty high precision. Instead of getting a value from 1-100 that goes 1 2 3 4...

#define ARC4RANDOM_MAX  0x100000000
float r = ((double)arc4random() / ARC4RANDOM_MAX);

Like Tobias said, to get a range you would use something like

float result = a + ((b-a)*r);

Upvotes: 0

Rik Smith-Unna
Rik Smith-Unna

Reputation: 3475

This is what I use, equivalent to python's random.uniform():

   float random_uniform(float min, float max) {
       // equivalent of random.uniform()
       return ((float)arc4random_uniform(((max-min)*1000)))/1000+min;
   }

arc4random_uniform gives a pretty good uniform distribution. The multiplying by 1000 is to allow handling numbers smaller than 1. Increase the multiplier (and divisor) to increase the precision.

Upvotes: 0

oxigen
oxigen

Reputation: 6263

try this

float a = 12.49953f;
float b = 39.11234f;
int startVal = a*10000;
int endVal = b*10000; 

srandom((unsigned)(mach_absolute_time() & 0xFFFFFFFF));
int randomValue = startVal+ (random() % (endVal - startVal));

float r = (float)randomValue / 10000.0f; 

Upvotes: 5

Tobias Langner
Tobias Langner

Reputation: 10828

Generally you get a random number between 0 and 1 (1 excluded) by the random function. This can be uniformly spread to the required interval by multiplying the random number with the interval-length between a and b and adding the lower to it.

with a

float r = random();
return a+(b-a)*r;

For the problem with 20 different random numbers: with 20 numbers - i'd create some kind of array and do a linear search each time as you suggested. This is easy to implement without failure and easy to debug. This saves you time solving problems that are more complicated. 20 is low enough for the linear search to have no major performance impact.

Upvotes: 3

Related Questions