srandom(time(NULL));

But... rand() is really not a very good PRNG. random() is a little better, but still less then ideal. Fortunately, these are not the only ones available on the iPhone. Personally, I like arc4random() because it's a decent pseudo-random algorithm and has twice the range or rand().

On the iPhone, RAND_MAX is 0x7fffffff (2147483647), while arc4random() will return a maximum value of 0x100000000 (4294967296), giving much more precision. You also don't need to seed arc4random(), as the first call to it automatically seeds it.

To get an integer value from arc4random() that goes from 0 to x-1, you would do this:

int value = arc4random() % x;

To get an integer in the range 1 to x, just add 1:

int value = (arc4random() % x) + 1;

The parenthesis aren't really necessary based on order of operation rules, but I'm anal about parens.

Finally, if you need to generate a floating point number, define this in your project:

#define ARC4RANDOM_MAX 0x100000000

Then, you can use arc4random() to get a floating point value (at double the precision of using rand()), between 0 and 100, like so:

double val = floorf(((double)arc4random() / ARC4RANDOM_MAX) * 100.0f);

## 20 comments:

You talk about better randomness, but using % is NOT more random.

Lets say random returned a number from 0 - 10 and I wanted one from 0 - 9. I would use % 10. But every time random returned 10, it would get converted to 0, thus doubling all the zeroes returned.

Scaling is better than mod unless performance is a concern.

If the range of the random number actually was from 1 to 10, or even 1 to 100,000, I could see your point, however arc4random() returns a value from 1 to 4294967296. The skew you would get from using modulus math on the resulting value could not be more than x/4294967296, and that's a worst case scenario if 4294967296 is equally divisible by x. We're talking about a number so infinitesimally small that it can't be displayed on most calculators except by using scientific notation. A value that wouldn't register as skew in the vast, vast majority of practical applications.

Whoops, slight error in that last post (I can't do math when I've been drinking :) - when x is evenly divisible by 4294967296, that's actually the best case scenario, it's when x-1 is evenly divisible by 4294967296 that we see worst case scenario. Doesn't change the basic point, though, that modulus math will not skew the results enough for most purposes. If you're doing mission critical simulations, then by all means, take the performance hit, but otherwise, modulus is fine.

Thanks for the tip Jeff. After reading this, I've been using arc4random in my iPhone game with good success. Your Beginning iPhone Development book has helped me out a lot too (I have a copy sitting next to me right now).

Hope I'm not too late to the ball...

If one is truly concerned about skewing when the maximum value is returned by a PRNG, you can always put in a check to discard that value and get a new random number before you do the mod operation.

To know whether this is faster than the Scaling alternative that pfhorte suggests, I'd need to know what he is proposing and how it would be implemented.

arc4random returns a 32 bit integer - so the most it could possibly return is 0xffffffff. There's no way it could return

0x100000000.

He type-casted before division.. so it is actually double, not uint32_t.

Thanks for the syntax :D. Now I can make my character move randomly :D

For anybody who is looking for a way to get a random number between a range of numbers (say 3-12), this is how I did it:

int min = 3;

int max = 12;

int numberOfSides = (arc4random() % (max - min)) + min;

NSLog(@"Random is %d", numberOfSides);

This will give you a random number within a range of 9 numbers and then offsets it from 0 to make the numbers be at least the minimum, but not more than max. I found the following method did not work for me:

int value = (arc4random() % x) + 1;

It did not work because it makes the random numbers exceed the maximum value. It adds one to the max value. So, you have to first subtract that value and then add it as an offset. The original post was very helpful though.

How would you generate a range of random values *INCLUDE* negative values?

From -10 to +20

Register: You could do something like this:

-(NSInteger) getRandFrom: (NSInteger) min to: (NSInteger) max

{

return (arc4random() % (max - min)) + min;

}

[self getRandFrom: -10 to: 20];That should do the trick.

If anyone else gets a problem compiling this try adding LL to the end of #define ARC4RANDOM_MAX 0x100000000.

So...

#define ARC4RANDOM_MAX 0x100000000LL

hope this is correct and helps someone.

Thanks for the function.

How can I make that with texts? Like every time the user changes the page, the app would give a random quote

scrub m65 kamagra attorney lawyer body scrub field jacket lovegra marijuana attorney injury lawyer

I was using arc4random in a game and I had a particular scenario where I wanted to do something random based on 3 weights: 0.4, 0.4, 0.2 (adding up to 1.0). My code was something like this:

r = (double)arc4random() / (double)UINT_MAX;

if (r <= 0.4) { ... }

else if (r <= 0.8) { ... }

else { ... }

What I found is that the first and third options seemed to hit more frequently than the second one. I watched the values in a debugger for a while to make sure my math was right--I never got a value > 1.0 and I did get values in the 0.4 to 0.8 range from time to time, but nowhere near as often as < 0.4 and > 0.8. I switched to rand() (true randomness is really not critical in this case) and the distribution seems a lot more even.

Has anyone seen this? Is this a known issue?

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.

Arsenal vs Huddersfield Town live streaming

Arsenal vs Huddersfield Town live streaming

Wolverhampton Wanderers vs Stoke City Live Streaming

Wolverhampton Wanderers vs Stoke City Live Streaming

Notts County vs Manchester City Live Streaming

Notts County vs Manchester City Live Streaming

Bologna vs AS Roma Live Streaming

Bologna vs AS Roma Live Streaming

Juventus vs Udinese Live Streaming

Juventus vs Udinese Live Streaming

Napoli vs Sampdoria Live Streaming

Napoli vs Sampdoria Live Streaming

Fulham vs Tottenham Hotspur Live Streaming

Fulham vs Tottenham Hotspur Live Streaming

AS Monaco vs Marseille Live Streaming

AS Monaco vs Marseille Live Streaming

Alajuelense vs Perez Zeledon Live Streaming

Alajuelense vs Perez Zeledon Live Streaming

Technology News | News Today | Live Streaming TV Channels

"and most people's first thought is to use rand() after seeding it by calling srandom(time(NULL));"

Shows how most people are really stupid. srandom() seeds random(), while srand() seeds rand(). Using srandom() to seed rand() might not work so well

The value of ARC4RANDOM_MAX is wrong.

arc4random() returns a maximum of (2**32)-1 = 4294967295 = 0xFFFFFFFF

See http://developer.apple.com/library/ios/#documentation/System/Conceptual/ManPages_iPhoneOS/man3/arc4random.3.html

You don't have to define that yourself, just use UINT32_MAX. If you use random() use RAND_MAX.

Post a Comment