rand & random & arc4random
2015-01-27 14:32
309 查看
rand(3) / random(3) / arc4random(3) / et al.
Written by Mattt Thompson on August 12th, 2013
What passes for randomness is merely a hidden chain of causality.In a mechanical universe of material interactions expressed through mathematical equations, it is unclear whether nature encodes an element of chance, or if it's a uniquely human way to reconcile uncertainty.
We can be sure of one thing, however: in the closed, digital universe of CPU cycles, processes, and threads, there is no true randomness, only pseudorandomness.
Pseudorandomness, is often implemented in a way very similar to a cryptographic hash, as a deterministic function that returns a value based on the current time (salted, of course, by some initial seed value). Also like hash functions, there are a number of PRNG, or pseudorandom number generators, each of which are optimized for particular performance characteristics: uniformity, periodicity, and computational complexity.
Of course, for app developers, all of this is an academic exercise. And rather than bore you with any more high-minded, long-winded treatises on the philosophical nature of randomness, we're going to tackle this one FAQ-style.
Our goal this week: to clear up all of the lingering questions and misunderstandings about doing random things in Objective-C. Let's dive in!
How Do I Generate a Random Number in Objective-C?
tl;dr: Usearc4random()and its related functions.
Specifically, to generate a random number between
0and
N - 1, use
arc4random_uniform(), which avoids modulo bias.
Random int
between 0
and N - 1
Objective-CNSUInteger r = arc4random_uniform(N);
Random int
between 1
and N
Objective-CNSUInteger r = arc4random_uniform(N) + 1;
Random double
between 0
and 1
If you are generating a random doubleor
float, another good option is the more obscure
rand48family of functions, including
drand48(3).
Objective-C
srand48(time(0)); double r = drand48();
rand48functions, unlike
arc4randomfunctions, require an initial value to be seeded before generating random numbers. This seed function,
srand48(3), should only be run once.
How Do I Pick a Random Element from an NSArray
?
Use arc4random_uniform(3)to generate a random number in the range of a non-empty array.
Objective-C
if ([array count] > 0) { id obj = array[arc4random_uniform([array count])]; }
How Do I Randomly Order an NSArray
?
Objective-CNSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array]; NSUInteger count = [mutableArray count]; // See http://en.wikipedia.org/wiki/Fisher–Yates_shuffle if (count > 1) { for (NSUInteger i = count - 1; i > 0; --i) { [mutableArray exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform((int32_t)(i + 1))]; } } NSArray *randomArray = [NSArray arrayWithArray:mutableArray];
This code is borrowed from TTTRandomizedEnumerator, which also provides randomized enumerators for
NSSet,
NSOrderedSet, and
NSDictionary.
How Do I Generate a Random String?
If you're looking to generate "lorem ipsum"-style sentences, try constructing a Markov Chain from a corpus.Otherwise, if you're looking to just get random letters, try one of the following methods:
Generate a Random Lowercase NSString
If you are operating on a known, contiguous range of Unicode characters, such as the lowercase letters (U+0061—
U+007A), you can do a simple conversion from a
char:
Objective-C
NSString *letter = [NSString stringWithFormat:@"%c", arc4random_uniform(26) + 'a'];
Pick a Random Character From an NSString
Otherwise, a simple way to pick random letters from a set of your choosing is to simply create a string containing all of the possible letters:Objective-C
NSString *vowels = @"aeiouy"; NSString *letter = [vowels substringWithRange:NSMakeRange(arc4random_uniform([vowels length]), 1)];
Why Should I Use arc4random(3)
instead of rand(3)
or random(3)
?
C functions are typically denoted with a number
3inside of parentheses, following the organizational convention of
manpages.
arc4randomdoes not require an initial seed (with
srandor
srandom), making it that much easier to use.
arc4randomhas a range up to
0x100000000 (4294967296), whereas
randand
randomtop out at
RAND_MAX = 0x7fffffff (2147483647).
randhas often been implemented in a way that regularly cycles low bits, making it more predictable.
What are rand(3)
, random(3)
, and arc4random(3)
, and Where Do They Come From?
randis a standard C function.
randomis defined as part of the POSIX standard.
arc4randomis provided on BSD and derived platforms.
If you have any additional questions about randomness on Objective-C, feel free to tweet @NSHipster. As always, corrections are welcome in the form of a pull request.
相关文章推荐
- 随机数生成 arc4random_uniform(_:UInt32) ->UInt32
- iPhone开发随想:rand()还是arc4random()
- iPhone开发随想:rand()还是arc4random()
- iOS 中生成随机数的4种方法(rand、random、arc4random、arc4random_uniform)
- iPhone开发随想:rand()还是arc4random()
- iPhone开发随想:rand()还是arc4random()
- iPhone开发随想:rand()还是arc4random()
- 随机数 iPhone开发随想:rand()还是arc4random()
- iPhone开发随想:rand()还是arc4random()
- rand(3) / random(3) / arc4random(3) / et al.
- iPhone开发随想:rand()还是arc4random()
- rand()还是arc4random()
- Keras: preprocessing_function && random_crop
- no.random.randn
- <python>random模块
- csu1290 Random Integers ——DP入门题&&比赛残留题
- 24-IO流-61-IO流(RandomAccessFile-随机写入&细节)
- 关于arange\range\numpy.random.randint()\numpy.random.randn()的总结
- rand & srand
- Swift - 使用arc4random()、arc4random_uniform()取得随机数