1. ホーム
  2. java

[解決済み] Java: 0 <= x < n の範囲にあるランダムな長さの数

2022-02-19 15:52:50

質問

Randomクラスは、指定された範囲のランダムなintを生成するメソッドを持っています。例えば

Random r = new Random(); 
int x = r.nextInt(100);

これは、0以上100未満のint型数値を生成するものです。これと全く同じことをlong数で行いたい。

long y = magicRandomLongGenerator(100);

RandomクラスにはnextLong()しかなく、範囲を設定することができません。

解決方法は?

からのスタートです。 Java 7 (またはAndroid API Level 21 = 5.0+) を直接使用することができます。 ThreadLocalRandom.current().nextLong(n) (0 ≤ x < n の場合) と ThreadLocalRandom.current().nextLong(m, n) (for m ≤ x < n). 参照 アレックス の回答が詳しいです。


に引っかかったら Java 6 (または Android 4.x) を使用する場合は、外部ライブラリ (例. org.apache.commons.math3.random.RandomDataGenerator.getRandomGenerator().nextLong(0, n-1) をご覧ください。 マウォルドネ の回答) を実装するか、または独自の nextLong(n) .

によると https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Random.html nextInt は次のように実装されています。

 public int nextInt(int n) {
     if (n<=0)
                throw new IllegalArgumentException("n must be positive");

     if ((n & -n) == n)  // i.e., n is a power of 2
         return (int)((n * (long)next(31)) >> 31);

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

そこで、これを修正して、次のように実行することができます。 nextLong :

long nextLong(Random rng, long n) {
   // error checking and 2^x checking removed for simplicity.
   long bits, val;
   do {
      bits = (rng.nextLong() << 1) >>> 1;
      val = bits % n;
   } while (bits-val+(n-1) < 0L);
   return val;
}