在范围内生成一个随机数?

可能重复:
在Objective-C中生成随机数

如何生成一个范围内的随机数字?

这实际上比大多数人意识到的要难得多:

 int rand_lim(int limit) { /* return a random number between 0 and limit inclusive. */ int divisor = RAND_MAX/(limit+1); int retval; do { retval = rand() / divisor; } while (retval > limit); return retval; } 

试图使用% (或等价地, / )来获取范围内的数字几乎不可避免地会引入偏斜(即,一些数字将比其他数字更频繁地生成)。

至于为什么使用%产生偏斜的结果:除非你想要的范围是RAND_MAX的除数,偏斜是不可避免的。 如果你从小数字开始,很容易看出原因。 考虑拿10块糖果,并试图在三个孩子之间均匀分配。 显然这是不可能完成的 – 如果你把所有的糖果都交出来,最近可以得到两个孩子拿到三块糖,其中一块拿到四块。

只有一种方法让所有的孩子都得到相同数量的糖果:确保你根本没有把最后一块糖果分发出去。

为了把这个与上面的代码联系起来,让我们从1到10的糖果和1到3的孩子开始。最初的分组说,因为有三个孩子,我们的除数是三。 然后,我们从桶中随机取出一个糖果,看看它的数量,然后除以三,然后把它交给那个孩子 – 但是如果结果大于3(即我们挑出的糖果数量为10),我们就不会把它拿出来 – 我们丢弃它,挑出另一个糖果。

当然,如果您使用的是C ++的现代化实现(即支持C ++ 11或更新版本),则通常应该使用标准库中的一个distribution类。 上面的代码与std::uniform_int_distribution最为接近,但是标准库也包含了uniform_real_distribution以及一些非均匀分布的类(伯努利,泊松,普通,也许是我现在不记得的其他几个类)。

 int rand_range(int min_n, int max_n) { return rand() % (max_n - min_n + 1) + min_n; } 

对于分数:

 double rand_range(double min_n, double max_n) { return (double)rand()/RAND_MAX * (max_n - min_n) + min_n; } 

http://www.cprogramming.com/tutorial/random.html

第二个例子展示了如何通过范围生成

对于[min,max]范围内的整数值:

 double scale = (double) (max - min) / RAND_MAX; int val = min + floor(rand() * scale) 

我在Obj-C为iPhone项目专门写了这个:

 - (int) intInRangeMinimum:(int)min andMaximum:(int)max { if (min > max) { return -1; } int adjustedMax = (max + 1) - min; // arc4random returns within the set {min, (max - 1)} int random = arc4random() % adjustedMax; int result = random + min; return result; } 

使用:

 int newNumber = [aClass intInRangeMinimum:1 andMaximum:100]; 

加盐调味

 +(NSInteger)randomNumberWithMin:(NSInteger)min WithMax:(NSInteger)max { if (min>max) { int tempMax=max; max=min; min=tempMax; } int randomy=arc4random() % (max-min+1); randomy=randomy+min; return randomy; } 

我在一个随机数相关的类中使用这个方法。 适合我的非苛刻的需求,但可能会有一定的偏见。