给定随机位函数生成随机int

时间:2017-10-23 02:38:43

标签: random binary numbers bit-manipulation bit

假设您已获得int randBit()函数,该函数返回,均匀分布,0或1。

编写一个randNumber(int max)函数。

这是我的实施,但我无法证明/反驳它是对的。

    // max number of bits
    int i = (int)Math.floor(Math.log(max) / Math.log(2)) + 1;

    int ret = randBit();
    while (i-- > 0) {
        ret = ret << 1 | randBit();
    }

    return ret;

我的基本想法是

  • 查找数字
  • 中的位数
  • 然后通过连续连接LSB直到满足位长来生成数字

1 个答案:

答案 0 :(得分:1)

在我看来,用随机位填充int的方法是正确的方法。但是,由于您的算法仅在最大功率为2且在循环中偏离1时有效,我建议进行此修改:

// max number of bits
int i = (int)Math.floor(Math.log(max) / Math.log(2)) + 1;

int rnd = 0;
int mask = 1;

while (i-- > 0) {
    rnd = rnd << 1 | randBit();
    mask <<= 1;  // or: mask *= 2
}
double q = (double)rnd / mask; // range is [0, 1)
return (int)((max + 1) * q);

我们来看看这个:

i将始终等于max占用的位数。当循环结束时,rnd将包含随机填充0或1的位数,mask-1将包含填充1s的位数。因此,可以安全地假设rndmask-1的商均匀分布在0和1之间。这与max相乘会产生0到max之间的范围内的结果,就浮动/实际价值而言,也是均匀分布的。

现在这个结果必须映射到整数,当然你也希望它们统一分布。这里唯一的问题是1.如果rndmask-1的商正好是1,那么会有一个边缘情况会在缩放到所需的结果范围时造成麻烦:会有{ {1}}值均匀分布,但0 .. max-1是一种罕见的例外情况。

为了处理这种情况,必须构建商,使其范围从0到1,但使用1 exclusive 。这是通过max实现的。通过乘以rnd / mask并转换为int,可以轻松将此范围映射到均匀扩展的整数0 .. max