如何使用一点数在低数字和高数字之间生成数字?

时间:2016-01-12 16:25:19

标签: algorithm bit-manipulation

我在接受采访时被问到这个问题,所以我不想要解决方案,只是关于如何处理它的指导。

  

你有两个低和高的数字。并且生成0和1的随机生成器。我必须使用该函数生成介于低和高之间的数字。

我可以在两个数字之间得到差异,并以某种方式尝试使用位操作生成数字。但我无法弄清楚如何做到这一点?

2 个答案:

答案 0 :(得分:2)

你可以这样做:

  1. range = high - low
  2. 找到n <{1}}
  3. 运行随机生成器n次以生成一个int,这要归功于它的二进制表示。像2^n-1 < range <= 2^n(=十进制的154)
  4. 之类的东西
  5. 将获得的号码添加到010011010以获取最终号码!

答案 1 :(得分:1)

这是一个基本的逐位比较算法,使用随机位函数给出低和高之间的随机数:

  • high减少1并将low增加1(如果稍后介绍的随机位数等于highlow中的随机位数。)
  • 创建布尔值high_declow_inc以存储high中的至少一个1是否已更改为0,并且low中至少有一个0已更改为1,并将它们都设置为false(这将有助于避免结果超出范围)。
  • 在这些情况下,将highlow从MSB逐位比较到LSB:

    • 如果您找到high:1low:1,则存储1 low_inc=false或存储随机位,否则(并根据需要更新high_dec)。
    • 如果您找到high:1low:0,则会存储一个随机位(并根据需要更新high_declow_inc)。
    • 如果您找到high:0low:1,则在high_dec=false存储0或在low_inc=false存储1或以其他方式存储随机位。
    • 如果您找到high:0low:0,则在high_dec=false时存储0或以其他方式存储随机位(并根据需要更新low_inc)。

请注意,如果最低可能结果是2的幂,则随机数的分布是均匀的,并且范围是2的幂。在所有情况下,使用整个范围,但可能存在强调范围开始或结束附近的值。

function between(a, b) {
    var lo = (a + 1).toString(2).split(''),         // conversion to bit array because
        hi = (b - 1).toString(2).split(''),         // there is no bit manipulation in JS
        lc = false,                                 // low changed
        hc = false,                                 // high changed
        result = [];
    while (lo.length < hi.length) lo.unshift(0);    // add leading zeros to low
    for (var i = 0; i < hi.length; i++) {           // iterate over bits, msb to lsb
        var bit = Math.round(Math.random());        // random bit generator
        if (hi[i] == 1) {
            if (lo[i] == 1) {                       // case hi:1 lo:1
                if (lc == false) bit = 1
                else if (bit == 0) hc = true;
            } else {                                // case hi:1 lo:0
                if (bit == 0) hc = true
                else lc = true;
            }
        } else {
            if (lo[i] == 1) {                       // case hi:0 lo:1
                if (hc == false) bit = 0
                else if (lc == false) bit = 1;
            } else {                                // case hi:0 lo:0
                if (hc == false) bit = 0
                else if (bit == 1) lc = true;
            }
        }
        result.push(bit);
    }
    return parseInt(result.join(''), 2);            // convert bit array to integer
}

document.write(between(999999, 1000100) + "<BR>");