在 Objective-C 中生成随机数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/160890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generating random numbers in Objective-C
提问by rustyshelf
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:
我主要是 Java 负责人,我想要一种方法来生成 0 到 74 之间的伪随机数。在 Java 中,我会使用以下方法:
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.
我对关于种子或真正随机性的讨论不感兴趣,我对你如何在 Objective-C 中完成相同的任务不感兴趣。我在谷歌上搜索过,似乎有很多不同且相互矛盾的信息。
回答by lajos
You should use the arc4random_uniform()function. It uses a superior algorithm to rand. You don't even need to set a seed.
您应该使用该arc4random_uniform()功能。它使用高级算法来rand. 您甚至不需要设置种子。
#include <stdlib.h>
// ...
// ...
int r = arc4random_uniform(74);
The arc4randomman page:
该arc4random手册页:
NAME arc4random, arc4random_stir, arc4random_addrandom -- arc4 random number generator LIBRARY Standard C Library (libc, -lc) SYNOPSIS #include <stdlib.h> u_int32_t arc4random(void); void arc4random_stir(void); void arc4random_addrandom(unsigned char *dat, int datlen); DESCRIPTION The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be in about (2**1700) states. The arc4random() function returns pseudo- random numbers in the range of 0 to (2**32)-1, and therefore has twice the range of rand(3) and random(3). The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via arc4random_addrandom(). There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically initializes itself. EXAMPLES The following produces a drop-in replacement for the traditional rand() and random() functions using arc4random(): #define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))
NAME arc4random, arc4random_stir, arc4random_addrandom -- arc4 random number generator LIBRARY Standard C Library (libc, -lc) SYNOPSIS #include <stdlib.h> u_int32_t arc4random(void); void arc4random_stir(void); void arc4random_addrandom(unsigned char *dat, int datlen); DESCRIPTION The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be in about (2**1700) states. The arc4random() function returns pseudo- random numbers in the range of 0 to (2**32)-1, and therefore has twice the range of rand(3) and random(3). The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via arc4random_addrandom(). There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically initializes itself. EXAMPLES The following produces a drop-in replacement for the traditional rand() and random() functions using arc4random(): #define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))
回答by yood
Use the arc4random_uniform(upper_bound)function to generate a random number within a range. The following will generate a number between 0 and 73 inclusive.
使用该arc4random_uniform(upper_bound)函数生成一个范围内的随机数。下面将生成一个介于 0 和 73 之间的数字。
arc4random_uniform(74)
arc4random_uniform(upper_bound)avoids modulo biasas described in the man page:
arc4random_uniform(upper_bound)避免了手册页中描述的模偏差:
arc4random_uniform() 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.
arc4random_uniform() 将返回一个小于 upper_bound 的均匀分布的随机数。arc4random_uniform() 被推荐用于类似 ``arc4random() % upper_bound'' 的结构,因为当上限不是 2 的幂时,它可以避免“模偏差”。
回答by yood
Same as C, you would do
和 C 一样,你会做
#include <time.h>
#include <stdlib.h>
...
srand(time(NULL));
int r = rand() % 74;
(assuming you meant including 0 but excluding 74, which is what your Java example does)
(假设您的意思是包括 0 但不包括 74,这就是您的 Java 示例所做的)
Edit:Feel free to substitute random()or arc4random()for rand()(which is, as others have pointed out, quite sucky).
编辑:随意替代random()或arc4random()为rand()(这是,正如其他人指出的那样,很苏茨基)。
回答by Groot
I thought I could add a method I use in many projects.
我想我可以添加一个我在许多项目中使用的方法。
- (NSInteger)randomValueBetween:(NSInteger)min and:(NSInteger)max {
return (NSInteger)(min + arc4random_uniform(max - min + 1));
}
If I end up using it in many files I usually declare a macro as
如果我最终在许多文件中使用它,我通常将宏声明为
#define RAND_FROM_TO(min, max) (min + arc4random_uniform(max - min + 1))
E.g.
例如
NSInteger myInteger = RAND_FROM_TO(0, 74) // 0, 1, 2,..., 73, 74
Note: Only for iOS 4.3/OS X v10.7 (Lion) and later
注意:仅适用于 iOS 4.3/OS X v10.7 (Lion) 及更高版本
回答by Tibidabo
This will give you a floating pointnumber between 0 and 47
这将为您提供0 到 47 之间的浮点数
float low_bound = 0;
float high_bound = 47;
float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound);
Or just simply
或者只是简单地
float rndValue = (((float)arc4random()/0x100000000)*47);
Both lower and upper bound can be negativeas well. The example code below gives you a random number between -35.76 and +12.09
下限和上限也可以为负数。下面的示例代码为您提供了一个介于 -35.76 和 +12.09 之间的随机数
float low_bound = -35.76;
float high_bound = 12.09;
float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound);
Convert result to a rounder Integervalue:
将结果转换为更圆的整数值:
int intRndValue = (int)(rndValue + 0.5);
回答by Michael Buckley
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
根据 rand(3) 的手册页,rand 函数系列已被 random(3) 淘汰。这是因为 rand() 的低 12 位经过循环模式。要获得随机数,只需通过使用无符号种子调用 srandom() 为生成器设置种子,然后调用 random()。所以,上面代码的等价物是
#import <stdlib.h>
#import <time.h>
srandom(time(NULL));
random() % 74;
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.
除非您想更改种子,否则您只需要在程序中调用 srandom() 一次。虽然你说你不想讨论真正的随机值,但 rand() 是一个非常糟糕的随机数生成器,而且 random() 仍然存在模偏差,因为它会生成一个介于 0 和 RAND_MAX 之间的数字。因此,例如,如果 RAND_MAX 是 3,并且您想要一个介于 0 和 2 之间的随机数,那么您得到 0 的可能性是 1 或 2 的两倍。
回答by AW101
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).
更好地使用arc4random_uniform. 但是,这在 iOS 4.3 以下不可用。幸运的是 iOS 会在运行时绑定这个符号,而不是在编译时(所以不要使用 #if 预处理器指令来检查它是否可用)。
The best way to determine if arc4random_uniformis available is to do something like this:
确定是否arc4random_uniform可用的最佳方法是执行以下操作:
#include <stdlib.h>
int r = 0;
if (arc4random_uniform != NULL)
r = arc4random_uniform (74);
else
r = (arc4random() % 74);
回答by Eli
I wrote my own random number utility class just so that I would have something that functioned a bit more like Math.random() in Java. It has just two functions, and it's all made in C.
我编写了自己的随机数实用程序类,只是为了让我拥有一些功能更像 Java 中的 Math.random() 的东西。它只有两个函数,而且都是用 C 编写的。
Header file:
头文件:
//Random.h
void initRandomSeed(long firstSeed);
float nextRandomFloat();
Implementation file:
实现文件:
//Random.m
static unsigned long seed;
void initRandomSeed(long firstSeed)
{
seed = firstSeed;
}
float nextRandomFloat()
{
return (((seed= 1664525*seed + 1013904223)>>16) / (float)0x10000);
}
It's a pretty classic way of generating pseudo-randoms. In my app delegate I call:
这是生成伪随机数的一种非常经典的方法。在我的应用程序委托中,我调用:
#import "Random.h"
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
initRandomSeed( (long) [[NSDate date] timeIntervalSince1970] );
//Do other initialization junk.
}
Then later I just say:
后来我只说:
float myRandomNumber = nextRandomFloat() * 74;
Note that this method returns a random number between 0.0f (inclusive) and 1.0f (exclusive).
请注意,此方法返回 0.0f(含)和 1.0f(不含)之间的随机数。
回答by Tom Howard
There are some great, articulate answers already, but the question asks for a random number between 0 and 74. Use:
已经有一些很好的清晰的答案,但问题要求一个介于 0 和 74 之间的随机数。使用:
arc4random_uniform(75)
arc4random_uniform(75)
回答by TwoStraws
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.
从 iOS 9 和 OS X 10.11 开始,您可以使用新的 GameplayKit 类以多种方式生成随机数。
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.
您有四种源类型可供选择:一般随机源(未命名,由系统选择其功能)、线性同余、ARC4 和 Mersenne Twister。这些可以生成随机整数、浮点数和布尔值。
At the simplest level, you can generate a random number from the system's built-in random source like this:
在最简单的层面上,您可以从系统内置的随机源中生成一个随机数,如下所示:
NSInteger rand = [[GKRandomSource sharedRandom] nextInt];
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:
这会生成一个介于 -2,147,483,648 和 2,147,483,647 之间的数字。如果你想要一个介于 0 和上限(不包括)之间的数字,你可以使用这个:
NSInteger rand6 = [[GKRandomSource sharedRandom] nextIntWithUpperBound:6];
GameplayKit has some convenience constructors built in to work with dice. For example, you can roll a six-sided die like this:
GameplayKit 内置了一些方便的构造函数来处理骰子。例如,您可以像这样掷出一个六面骰子:
GKRandomDistribution *d6 = [GKRandomDistribution d6];
[d6 nextInt];
Plus you can shape the random distribution by using things like GKShuffledDistribution.
另外,您可以使用诸如GKShuffledDistribution.

