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

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 =>有50%的概率。 bits可以是<2 ^ 30或者在2 ^ 30和2 ^ 31之间


无论如何,

  1. 为什么2 ^ 31不能被n整除
  2. 为什么只有当两个数字> 2 ^ 30时才有效?

我猜一些二元分裂魔法,一个破坏均匀分布的溢出?

谢谢!

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

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

它所讨论的最糟糕的情况是当较小范围的尺寸刚好超过较大范围的一半时,所以你将不得不重新生成超过一半的时间。

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

关于第一个问题:

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

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