I'm a Java head mainly, and I want a way to generate a pseudo-random number between 0 and 74. In Java I would use the method:
Random.nextInt(74)
I'm not interested in a discussion about seeds or true randomness, just how you accomplish the same task in Objective-C. I've scoured Google, and there just seems to be lots of different and conflicting bits of information.
As of iOS 9 and OS X 10.11, you can use the new GameplayKit classes to generate random numbers in a variety of ways.
You have four source types to choose from: a general random source (unnamed, down to the system to choose what it does), linear congruential, ARC4 and Mersenne Twister. These can generate random ints, floats and bools.
At the simplest level, you can generate a random number from the system's built-in random source like this:
That generates a number between -2,147,483,648 and 2,147,483,647. If you want a number between 0 and an upper bound (exclusive) you'd use this:
GameplayKit has some convenience constructors built in to work with dice. For example, you can roll a six-sided die like this:
Plus you can shape the random distribution by using things like
GKShuffledDistribution
.//The following example is going to generate a number between 0 and 73.
Output:
random number: 72
random number step 2: 52
You should use the arc4random_uniform() function. It uses a superior algorithm to rand. You don't even need to set a seed.
The arc4random man page:
According to the manual page for rand(3), the rand family of functions have been obsoleted by random(3). This is due to the fact that the lower 12 bits of rand() go through a cyclic pattern. To get a random number, just seed the generator by calling srandom() with an unsigned seed, and then call random(). So, the equivalent of the code above would be
You'll only need to call srandom() once in your program unless you want to change your seed. Although you said you didn't want a discussion of truly random values, rand() is a pretty bad random number generator, and random() still suffers from modulo bias, as it will generate a number between 0 and RAND_MAX. So, e.g. if RAND_MAX is 3, and you want a random number between 0 and 2, you're twice as likely to get a 0 than a 1 or a 2.
Better to use
arc4random_uniform
. However, this isn't available below iOS 4.3. Luckily iOS will bind this symbol at runtime, not at compile time (so don't use the #if preprocessor directive to check if it's available).The best way to determine if
arc4random_uniform
is available is to do something like this:I thought I could add a method I use in many projects.
If I end up using it in many files I usually declare a macro as
E.g.
Note: Only for iOS 4.3/OS X v10.7 (Lion) and later