在Objective-C中生成随机数字

我主要是一个Java头,我想要一个方法来产生0到74之间的伪随机数。在Java中,我将使用以下方法:

Random.nextInt(74) 

我对有关种子或真正的随机性的讨论不感兴趣,只是在Objective-C中完成同样的任务。 我search了谷歌,似乎有很多不同和相互矛盾的信息。

你应该使用arc4random_uniform()函数。 它使用卓越的algorithm来进行rand。 你甚至不需要设置种子。

 #include <stdlib.h> // ... // ... int r = arc4random_uniform(74); 

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)) 

使用arc4random_uniform(upper_bound)函数在一个范围内生成一个随机数。 以下内容将生成一个介于0和73之间的数字。

 arc4random_uniform(74) 

arc4random_uniform(upper_bound)避免了手册页中描述的模偏差 :

arc4random_uniform()将返回一个小于upper_bound的均匀分布的随机数。 arc4random_uniform()build议比arc4random()%upper_bound''这样的结构更好,因为当上限不是2的幂时,它避免了“ 模偏置 ”。

和C一样,你会做的

 #include <time.h> #include <stdlib.h> ... srand(time(NULL)); int r = rand() % 74; 

(假设你的意思是包括0,但不包括74,这是你的Java例子)

编辑: random()rand()replacerandom()arc4random() rand()就像别人指出的那样,很烂)。

这会给你一个0到47之间的浮点数

 float low_bound = 0; float high_bound = 47; float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound); 

或者只是简单

 float rndValue = (((float)arc4random()/0x100000000)*47); 

下限和上限也可以是负的 。 下面的示例代码给你一个介于-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); 

将结果转换为一个数值数值:

 int intRndValue = (int)(rndValue + 0.5); 

我想我可以添加一个我在许多项目中使用的方法。

 - (NSInteger)randomValueBetween:(NSInteger)min and:(NSInteger)max { return (NSInteger)(min + arc4random_uniform(max - min + 1)); } 

如果我最终在很多文件中使用它,我通常会声明一个macros

 #define RAND_FROM_TO(min, max) (min + arc4random_uniform(max - min + 1)) 

例如

 NSInteger myInteger = RAND_FROM_TO(0, 74) // 0, 1, 2,..., 73, 74 

注意:仅适用于iOS 4.3 / OS X v10.7(Lion)及更高版本

根据rand(3)的手册页,随机函数rand函数族已经过时(3)。 这是由于rand()的低12位经历循环模式。 要得到一个随机数,只需要用一个无符号的种子调用srandom()来产生生成器,然后调用random()。 所以,相当于上面的代码将是

 #import <stdlib.h> #import <time.h> srandom(time(NULL)); random() % 74; 

除非要更改种子,否则只需在程序中调用srandom()一次。 虽然你说你不想讨论真正的随机值,但rand()是一个非常糟糕的随机数生成器,而random()仍然存在模偏差,因为它会生成一个介于0和RAND_MAX之间的数字。 所以,例如,如果RAND_MAX是3,并且你想要一个0到2之间的随机数,你得到0的概率是1或2的两倍。

最好使用arc4random_uniform 。 但是,这在iOS 4.3下不可用。 幸运的是,iOS将在运行时绑定这个符号,而不是在编译时(所以不要使用#if预处理器指令来检查它是否可用)。

确定arc4random_uniform是否可用的最好方法是做这样的事情:

 #include <stdlib.h> int r = 0; if (arc4random_uniform != NULL) r = arc4random_uniform (74); else r = (arc4random() % 74); 

我编写了我自己的随机数工具类,这样我就可以使用Java中的Math.random()函数。 它只有两个function,都是用C做成的

头文件:

 //Random.h void initRandomSeed(long firstSeed); float nextRandomFloat(); 

实施文件:

 //Random.m static unsigned long seed; void initRandomSeed(long firstSeed) { seed = firstSeed; } float nextRandomFloat() { return (((seed= 1664525*seed + 1013904223)>>16) / (float)0x10000); } 

这是生成伪随机的非常经典的方法。 在我的应用程序代表我打电话:

 #import "Random.h" - (void)applicationDidFinishLaunching:(UIApplication *)application { initRandomSeed( (long) [[NSDate date] timeIntervalSince1970] ); //Do other initialization junk. } 

后来我只是说:

 float myRandomNumber = nextRandomFloat() * 74; 

请注意,此方法返回0.0f(含)和1.0f(不含)之间的随机数。

已经有一些很好的,明确的答案,但问题要求0到74之间的随机数。使用:

arc4random_uniform(75)

生成0到99之间的随机数字:

 int x = arc4random()%100; 

生成500到1000之间的随机数:

 int x = (arc4random()%501) + 500; 

//以下示例将生成一个介于0和73之间的数字。

 int value; value = (arc4random() % 74); NSLog(@"random number: %i ", value); //In order to generate 1 to 73, do the following: int value1; value1 = (arc4random() % 73) + 1; NSLog(@"random number step 2: %i ", value1); 

输出:

  • 随机数: 72

  • 随机数字步骤2:52

从iOS 9和OS X 10.11开始,您可以使用新的GameplayKit类以各种方式生成随机数。

你有四种源types可供select:一般的随机源(未命名,直到系统select它做什么),线性同余,ARC4和Mersenne Twister。 这些可以产生随机整数,浮点数和布尔值。

在最简单的层面上,您可以从系统的内置随机源生成一个随机数,如下所示:

 NSInteger rand = [[GKRandomSource sharedRandom] nextInt]; 

这将产生-2,147,483,648和2,147,483,647之间的数字。 如果你想要一个0到上限(独占)之间的数字,你可以使用这个:

 NSInteger rand6 = [[GKRandomSource sharedRandom] nextIntWithUpperBound:6]; 

GameplayKit有一些便利的构造函数,可以与骰子一起工作。 例如,你可以像这样掷出一个六面骰子:

 GKRandomDistribution *d6 = [GKRandomDistribution d6]; [d6 nextInt]; 

另外你可以通过使用GKShuffledDistribution东西来塑造随机分布。

对于游戏开发使用random()来生成随机数。 可能至less比使用arc4random()快5倍。 当使用random()的全部范围生成随机数时,模偏差不是问题,特别是对于游戏。 一定要先种子 在AppDelegate中调用srandomdev()。 这里有一些帮助function:

 static inline int random_range(int low, int high){ return (random()%(high-low+1))+low;} static inline CGFloat frandom(){ return (CGFloat)random()/UINT32_C(0x7FFFFFFF);} static inline CGFloat frandom_range(CGFloat low, CGFloat high){ return (high-low)*frandom()+low;}