42

Can I set a range of numbers when using arc4random()? For example 50-100 only.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
NextRev
  • 1,711
  • 4
  • 22
  • 31
  • use the modulo for the range and add the offset to it, like arc4random() % 50 + 50; it will provide you a random number in range of 50 and 99. – holex Nov 03 '13 at 10:01

6 Answers6

73

As pointed out in other posts below, it is better to use arc4random_uniform. (When this answer was originally written, arc4random_uniform was not available). Besides avoiding the modulo bias of arc4random() % x, it also avoids a seeding problem with arc4random when used recursively in short timeframes.

arc4random_uniform(4)

will generate 0, 1, 2 or 3. Thus you could use:

arc4random_uniform(51)

and merely add 50 to the result to get a range between 50 & 100 (inclusive).

jtbandes
  • 115,675
  • 35
  • 233
  • 266
RunLoop
  • 20,288
  • 21
  • 96
  • 151
  • This only gives you 0 to 50, doesn't give you a range of 50 to 100. – Boon Nov 25 '11 at 01:02
  • 2
    Like Run Loop said add 50. int num = (arc4random() % (51)) +50; – Nungster Feb 24 '12 at 18:38
  • 7
    Beware of this method's [modulo bias](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Modulo_bias). Safer to use [`arc4random_uniform()`](http://stackoverflow.com/questions/648739/objective-c-modulo-bias). – JohnK May 10 '13 at 01:16
  • I've expanded @JohnK thoughts in an answer below. If you want a more accurate random number distribution then it's definitely worth looking at. – Justyn Mar 13 '14 at 18:46
29

To expand upon JohnK comment.

It is suggested that you use the following function to return a ranged random number:

arc4random_uniform(51)

which will return a random number in the range 0 to 50.

Then you can add your lower bounds to this like:

arc4random_uniform(51) + 50

which will return a random number in the range 50 to 100.

The reason we use arc4random_uniform(51) over arc4random() % 51 is to avoid the modulo bias. This is highlighted in the man page as follows:

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

In short you get a more evenly distributed random number generated.

Justyn
  • 1,442
  • 12
  • 27
18
int fromNumber = 10;
int toNumber = 30;
int randomNumber = (arc4random()%(toNumber-fromNumber))+fromNumber;

Will generate randon number between 10 and 30, i.e. 11,12,13,14......29

Vaibhav Saran
  • 12,848
  • 3
  • 65
  • 75
  • 7
    It's (arc4random()%(toNumber-fromNumber+1))+fromNumber – Michaël Apr 11 '11 at 19:29
  • 4
    Beware of this method's [modulo bias](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Modulo_bias). Safer to use [`arc4random_uniform()`](http://stackoverflow.com/questions/648739/objective-c-modulo-bias). – JohnK May 10 '13 at 01:18
3

You can use this code for generating random values with range:

//range from 50 to 100
int num1 = (arc4random() % 50) + 50; or
int num1 = arc4random_uniform(50) + 50;

//range from 0-100
int num1 = arc4random() % 100; or
int num1 = arc4random_uniform(100);
Undo
  • 25,519
  • 37
  • 106
  • 129
handiansom
  • 783
  • 11
  • 27
1

In Swift you can use this (inspired by answer of @Justyn)

func generateRandomKey(fromRange rangeFrom:Int, toRange rangeTo:Int) -> Int{

    let theKey = arc4random_uniform(UInt32(rangeTo - rangeFrom)) +  UInt32(rangeFrom)
    return Int(theKey)
}

Will always give you a random range Integer.

Community
  • 1
  • 1
kurtanamo
  • 1,808
  • 22
  • 27
  • I think this needs adjusting as your range will always be 1 less that you want. You should increment your rangeTo by 1. 'let theKey = arc4random_uniform(UInt32((rangeTo + 1) - rangeFrom)) + UInt32(rangeFrom)' – Justyn Jun 28 '17 at 12:12
  • Also, if you're wanting to generate a random key, you should probably be looking at this instead: https://stackoverflow.com/a/24428458/1130260 – Justyn Jun 28 '17 at 12:14
0

In many situations 10 thru 30 would mean inclusive, (includes 10 and 30) ...

int fromNumber = 10;
int toNumber = 30;
toNumber ++;
int randomNumber = (arc4random()%(toNumber-fromNumber))+fromNumber;

Notice the difference toNumber - fromNumber is now 21 ... (20+1) which yields the possible results of 0 thru 20 (inclusive) which when added to fromNumber (10) results in 10 thru 30 (inclusive).

zero323
  • 322,348
  • 103
  • 959
  • 935
Mike Young
  • 34
  • 4
  • 2
    Beware of this method's [modulo bias](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Modulo_bias). Safer to use [`arc4random_uniform()`](http://stackoverflow.com/questions/648739/objective-c-modulo-bias). – JohnK May 10 '13 at 01:18