在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;}