I have two text boxes and user can input 2 positive integers (Using Objective-C). The goal is to return a random value between the two numbers.
I've used "man arc4random" and still can't quite wrap my head around it. I've came up with some code but it's buggy.
float lowerBound = lowerBoundNumber.text.floatValue;
float upperBound = upperBoundNumber.text.floatValue;
float rndValue;
//if lower bound is lowerbound < higherbound else switch the two around before randomizing.
if(lowerBound < upperBound)
{
rndValue = (((float)arc4random()/0x100000000)*((upperBound-lowerBound)+lowerBound));
}
else
{
rndValue = (((float)arc4random()/0x100000000)*((lowerBound-upperBound)+upperBound));
}
Right now if I put in the values 0 and 3 it seems to work just fine. However if I use the numbers 10 and 15 I can still get values as low as 1.0000000 or 2.000000 for "rndValue".
Do I need to elaborate my algorithm or do I need to change the way I use arc4random?
In Swift:
Try this.
You could simply use integer values like this:
Or if you mean you want to include float number between lowerBound and upperBound? If so please refer to this question: https://stackoverflow.com/a/4579457/1265516
Objective-C Function:
Swift:
Call it anywhere by:
For Swift:
You should avoid clamping values with mod (%) if you can, because even if the pseudo-random number generator you're using (like
arc4random
) is good at providing uniformly distributed numbers in its full range, it may not provide uniformly distributed numbers within the restricted modulo range.You also don't need to use a literal like
0x100000000
because there is a convenient constant available in stdint.h:That will give you a random float in the interval [0,1]. Note that
arc4random
returns an integer in the interval [0, 2**32 - 1].To move this into the interval you want, you just add your minimum value and multiply the random float by the size of your range:
In the code you posted you're multiplying the random float by the whole mess (lowerBound + (upperBound - lowerBound)), which is actually just equal to upperBound. And that's why you're still getting results less than your intended lower bound.
The following code include the minimum AND MAXIMUM value as the random output number:
Update:
I edited the answer by replacing
arc4random() % upper_bound
witharc4random_uniform(upper_bound)
as @rmaddy suggested.And here is the reference of arc4random_uniform for the details.
Update2:
I updated the answer by inserting a cast to uint32_t in
arc4random_uniform()
as @bicycle indicated.