Reputation: 1951
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
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.
double
s 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
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