统一随机数-不包括上限

时间:2018-07-15 01:22:02

标签: c

我想生成一些随机数,例如从minmax。问题是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;

3 个答案:

答案 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