JavaでランダムなBigInteger値を生成するにはどうすればいいですか? 質問する

JavaでランダムなBigInteger値を生成するにはどうすればいいですか? 質問する

0(含む)からn(含まない)までの範囲で任意の大きさの乱数を生成する必要があります。最初に考えたのは、nextDoublen を掛けますが、n が 2 53より大きくなると、結果は均一に分布しなくなります。

BigInteger次のコンストラクタが利用可能です:

public BigInteger(int numBits, Random rnd)

0 から (2 numBits - 1)までの範囲に均一に分布した、ランダムに生成された BigInteger を構築します。

これを使用して、n が 2 の累乗ではない 0 〜 n の範囲のランダムな値を取得するにはどうすればよいでしょうか?

ベストアンサー1

ループを使用します:

BigInteger randomNumber;
do {
    randomNumber = new BigInteger(upperLimit.bitLength(), randomSource);
} while (randomNumber.compareTo(upperLimit) >= 0);

平均すると、2 回未満の反復が必要となり、選択は均一になります。

編集:RNG のコストが高い場合は、次の方法で反復回数を制限できます。

int nlen = upperLimit.bitLength();
BigInteger nm1 = upperLimit.subtract(BigInteger.ONE);
BigInteger randomNumber, temp;
do {
    temp = new BigInteger(nlen + 100, randomSource);
    randomNumber = temp.mod(upperLimit);
} while (s.subtract(randomNumber).add(nm1).bitLength() >= nlen + 100);
// result is in 'randomNumber'

このバージョンでは、ループが2回以上実行される可能性は非常に低い(2^100つまり、次の 1 秒以内にホスト マシンが自然発火する確率よりもはるかに低くなります。一方、このmod()操作は計算コストが高いため、インスタンスが非常に遅い場合を除き、このバージョンはおそらく以前のバージョンよりも遅くなりますrandomSource

おすすめ記事