如何生成一个范围内的随机数?
答案 0 :(得分:62)
这实际上比大多数人意识到的要难得多:
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或更新版本的C ++),您通常应该使用标准库中的distribution
类。上面的代码与std::uniform_int_distribution
最接近,但标准库还包括uniform_real_distribution
以及许多非均匀分布的类(伯努利,泊松,正常,也许还有其他几个我不喜欢)记得此刻)。
答案 1 :(得分:7)
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;
}
答案 2 :(得分:2)
对于[min,max]范围内的整数值:
double scale = (double) (max - min) / RAND_MAX;
int val = min + floor(rand() * scale)
答案 3 :(得分:-1)
我在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];
添加盐味道
答案 4 :(得分:-2)
+(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;
}
我在我制作的随机数相关课程中使用此方法。适用于我的非苛刻需求,但可能在某种程度上有偏见。