为什么2 ^ 31不能被n整除?

时间:2013-11-12 13:00:01

标签: java random division

http://docs.oracle.com/javase/6/docs/api/java/util/Random.html#nextInt%28int%29说:

  

算法有点棘手。它拒绝可能产生的价值   在不均匀的分布中(由于2 ^ 31不可分割的事实)   由n)。值被拒绝的概率取决于n。该   最坏的情况是n = 2 ^ 30 + 1,拒绝的概率是1/2,   并且循环终止前的预期迭代次数为2。

算法:

int bits, val;
do {
    bits = next(31);
    val = bits % n;
} while (bits - val + (n-1) < 0);

代码测试n > 2^30bits > n的情况。然后设置最高有效位并将条件中的结果转换为负值。

我了解bits最多2^31-1 =&gt;有50%的概率。 bits可以是&lt; 2 ^ 30或2 ^ 30和2 ^ 31之间


反正

  1. 为什么 2 ^ 31不能被n 整除?
  2. 为什么只有当两个数字都是有效时才有效? 2 ^ 30?
  3. 我猜一些二元分裂法术,一个破坏均匀分布的溢出?

    谢谢!

3 个答案:

答案 0 :(得分:5)

这是一个问题,任何时候你想要在较大范围内生成一个较小范围内的随机数,其中较小范围的大小不能被较大范围的整数整除。

如果你有一个介于0到9之间的随机数(包括0和9),并希望将其更改为0到3之间的一个,如果你只是将其作为n%4,那么你有3/10的机会获得a 0(0,4或8)%4,但获得3(3或7)%4的概率为2/10。这里最简单的方法是重新生成随机数,如果它大于7。

最糟糕的情况是,较小范围的大小只是较大范围的一半,所以你只需要重新生成一半以上的时间。

答案 1 :(得分:1)

2 ^ 31只是一个幂或2的divisibale。当你检查代码时,这个特殊情况被单独处理而没有循环。描述与拒绝过程有关,并且n不具有2的幂。

答案 2 :(得分:0)

关于第一个问题:

据我理解这句话,据说当^ ^ 31不能被n整除时会导致分布不均匀。

对不起,但我不知道第二个问题。