Java: random long number in 0 <= x < n range

ThreadLocalRandom

ThreadLocalRandom has a nextLong(long bound) method.

long v = ThreadLocalRandom.current().nextLong(100);

It also has nextLong(long origin, long bound) if you need an origin other than 0. Pass the origin (inclusive) and the bound (exclusive).

long v = ThreadLocalRandom.current().nextLong(10,100); // For 2-digit integers, 10-99 inclusive.

SplittableRandom has the same nextLong methods and allows you to choose a seed if you want a reproducible sequence of numbers.


The standard method to generate a number (without a utility method) in a range is to just use the double with the range:

long range = 1234567L;
Random r = new Random()
long number = (long)(r.nextDouble()*range);

will give you a long between 0 (inclusive) and range (exclusive). Similarly if you want a number between x and y:

long x = 1234567L;
long y = 23456789L;
Random r = new Random()
long number = x+((long)(r.nextDouble()*(y-x)));

will give you a long from 1234567 (inclusive) through 123456789 (exclusive)

Note: check parentheses, because casting to long has higher priority than multiplication.


Starting from Java 7 (or Android API Level 21 = 5.0+) you could directly use ThreadLocalRandom.current().nextLong(n) (for 0 ≤ x < n) and ThreadLocalRandom.current().nextLong(m, n) (for m ≤ x < n). See @Alex's answer for detail.


If you are stuck with Java 6 (or Android 4.x) you need to use an external library (e.g. org.apache.commons.math3.random.RandomDataGenerator.getRandomGenerator().nextLong(0, n-1), see @mawaldne's answer), or implement your own nextLong(n).

According to https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Random.html nextInt is implemented as

 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;
 }

So we may modify this to perform 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;
}