我想生成一些随机数,例如从min
到max
。问题是rand()
会生成[0, RAND_MAX]
范围内的数字。将其缩放到[min, max]
会导致每个数字的范围为1,除了max
发生RAND_MAX
次之外的max + 1
之外。如果我将上限设为max + 1
,则可能仍会得到[min, max + 1)
作为值。基本上,有没有办法使范围int u_rand(int min, int max)
{
return (int)((double)rand() / RAND_MAX * (max - min + 1)) + min; //has a chance to spit out max + 1
}
?
这里有一些代码:
$c = ($a ^ $b) & 0xffffffff;
if ($c & 0x80000000)
$c -= 0x100000000;
echo $c;
答案 0 :(得分:2)
您的方法不会导致均匀分布。最接近均匀分布的将是模运算符%
。
int u_rand(int min, int max)
{
return min + rand() % (max - min + 1);
}
同样,这并不是完全统一的,而是相当接近和简单的(假设与RAND_MAX相比,您的范围max - min
很小,并且rand()
的实现很好)。
答案 1 :(得分:2)
以下内容应提供[min,max)的随机数的均匀分布
int u_rand(int min, int max) {
int threshold = RAND_MAX - RAND_MAX % (max - min);
int num = rand();
while (num >= threshold) {
num = rand();
}
return num % (max - min) + min;
}
它将舍弃不能在[min,max)之间平均分配的部分范围,如果在该范围内选择了一个数字,它将取一个新的数字,直到它在可接受的范围内为止。这确实意味着对生成随机数需要多长时间没有硬性限制,但是从统计学上讲,它将胜过确定性变体。请注意,我也避免在任何地方使用浮点运算,因此也没有因四舍五入而产生的细微偏差。您的电话号码将与rand()
的原始范围一样统一。
答案 2 :(得分:0)
简短答案:删除+1
。
长答案:(max - min + 1)
计算您要获取该数字的范围的 width ,即该数字所覆盖的数字的总和。仅此而已,没有+ min
,您将在[0, max-min+1)
中得到数字。然后+ min
偏移了从min
开始的位置,因此您最终得到[min, max-min+1+min)
,又名[min, max+1)
,又名[min, max]
。如果要排除max
,请将范围的宽度缩小1,但将其偏移相同的数量:
(int)((double)rand() / RAND_MAX * (max - min)) + min