Justin Copeland
Justin Copeland

Reputation: 1951

Why is arc4random returning outlandish values?

I am calling arc4random in a function in my iOS application to generate random values from -5 to 6.

double num;
for (int i = 0; i < 3; i++) {
    num = (arc4random() % 11) - 5;
    NSLog(@"%0.0f", num);
}

I get the following output from console.

2012-05-01 20:25:41.120 Project32[8331:fb03] 0
2012-05-01 20:25:41.121 Project32[8331:fb03] 1
2012-05-01 20:25:41.122 Project32[8331:fb03] 4294967295

0 and 1 are values within range, but wowww, where did 4294967295 come from?

Changing arc4random() to rand() fixes the problem, but rand(), of course, requires seeding.

Upvotes: 3

Views: 778

Answers (2)

jscs
jscs

Reputation: 64002

arc4random() returns a u_int32_t -- that's an unsigned integer, one that doesn't represent negative values. Every time arc4random() % 11 comes up with a number 0 ≤ n < 5, you subtract 5 and wrap around to a very large number.

doubles can represent negative numbers, of course, but you're not converting to double until it's too late. Stick a cast in there:

 num = (double)(arc4random() % 11) - 5;

to promote the result of the modulo before the subtraction, and everything will be okay.

Upvotes: 7

danielbeard
danielbeard

Reputation: 9149

Try using

arc4random_uniform(11) - 5;

instead.

From the man page:

arc4random_uniform() will return a uniformly distributed random number
 less than upper_bound.  arc4random_uniform() is recommended over con-
 structions like ``arc4random() % upper_bound'' as it avoids "modulo bias"
 when the upper bound is not a power of two.

Upvotes: 4

Related Questions