随机化BigInteger

时间:2010-09-17 13:22:09

标签: java biginteger random

我想随机化一个BigInteger。目的是从1到8180385048中选择一个数字。虽然,从我注意到,BigInteger(BitLen,Random)从n到X 2 -1,我想要一些不可预测的数字。我试图制作一个可以做到这一点的方法,但是我一直遇到错误并最终放弃在这里询问。 :P有没有人对如何做这个有任何建议?

3 个答案:

答案 0 :(得分:5)

从显然需要解决相同问题的Random.nextInt(int n)的文档来看,他们似乎已经得出结论,你不能做得比“重新取样如果超出范围”更好,但是预计会受到惩罚可以忽略不计。

来自文档:

  

算法有点棘手。它拒绝会导致分布不均匀的值(由于2 31 不能被n整除)。值被拒绝的概率取决于n。最坏的情况是n = 2 30 +1,其中拒绝的概率是1/2,并且循环终止前的预期迭代次数是2.

我建议您只使用您提到的randomizing constructor并进行迭代,直到达到范围内的值,例如:

public static BigInteger rndBigInt(BigInteger max) {
    Random rnd = new Random();
    do {
        BigInteger i = new BigInteger(max.bitLength(), rnd);
        if (i.compareTo(max) <= 0)
            return i;
    } while (true);
}

public static void main(String... args) {
    System.out.println(rndBigInt(new BigInteger("8180385048")));
}

对于您的特定情况(最大值= 8180385048),不得不重复的概率,即使只有一次,约为4.8%,所以不用担心: - )

答案 1 :(得分:1)

进行循环并获得覆盖范围的最小位长度的随机BigInteger,直到获得范围内的一个数字。这应该保留随机数的分布。

答案 2 :(得分:0)

如果在其他答案中建议,如果超出范围则重申是此问题的解决方案。但是,如果您想避免这种情况,另一种选择是使用模数运算符:

BigInteger i = new BigInteger(max.bitLength(), rnd);
i = i.mod(max);                 // Now 0 <= i <= max - 1
i = i.add(BigInteger.ONE);      // Now 1 <= i <= max