Reputation: 40339
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
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
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
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
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