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

Random class has a method to generate random int in a given range. For example:

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

This would generate an int number more or equal to 0 and less than 100. I'd like to do exactly the same with long number.

long y = magicRandomLongGenerator(100);

Random class has only nextLong(), but it doesn't allow to set range.

This question is related to java random range long-integer

The answer is


public static long randomLong(long min, long max)
{
    try
    {
        Random  random  = new Random();
        long    result  = min + (long) (random.nextDouble() * (max - min));
        return  result;
    }
    catch (Throwable t) {t.printStackTrace();}
    return 0L;
}

Further improving kennytm's answer: A subclass implementation taking the actual implementation in Java 8 into account would be:

public class MyRandom extends Random {
  public long nextLong(long bound) {
    if (bound <= 0) {
      throw new IllegalArgumentException("bound must be positive");
    }

    long r = nextLong() & Long.MAX_VALUE;
    long m = bound - 1L;
    if ((bound & m) == 0) { // i.e., bound is a power of 2
      r = (bound * r) >> (Long.SIZE - 1);
    } else {
      for (long u = r; u - (r = u % bound) + m < 0L; u = nextLong() & Long.MAX_VALUE);
    }
    return r;
  }
}

How about this:

public static long nextLong(@NonNull Random r, long min, long max) {
    if (min > max)
        throw new IllegalArgumentException("min>max");
    if (min == max)
        return min;
    long n = r.nextLong();
    //abs (use instead of Math.abs, which might return min value) :
    n = n == Long.MIN_VALUE ? 0 : n < 0 ? -n : n;
    //limit to range:
    n = n % (max - min);
    return min + n;
}

?


If you want a uniformly distributed pseudorandom long in the range of [0,m), try using the modulo operator and the absolute value method combined with the nextLong() method as seen below:

Math.abs(rand.nextLong()) % m;

Where rand is your Random object.

The modulo operator divides two numbers and outputs the remainder of those numbers. For example, 3 % 2 is 1 because the remainder of 3 and 2 is 1.

Since nextLong() generates a uniformly distributed pseudorandom long in the range of [-(2^48),2^48) (or somewhere in that range), you will need to take the absolute value of it. If you don't, the modulo of the nextLong() method has a 50% chance of returning a negative value, which is out of the range [0,m).

What you initially requested was a uniformly distributed pseudorandom long in the range of [0,100). The following code does so:

Math.abs(rand.nextLong()) % 100;

The below Method will Return you a value between 10000000000 to 9999999999

long min = 1000000000L
long max = 9999999999L    

public static long getRandomNumber(long min, long max){

    Random random = new Random();         
    return random.nextLong() % (max - min) + max;

}

The methods above work great. If you're using apache commons (org.apache.commons.math.random) check out RandomData. It has a method: nextLong(long lower, long upper)

http://commons.apache.org/math/userguide/random.html

http://commons.apache.org/math/api-1.1/org/apache/commons/math/random/RandomData.html#nextLong(long,%20long)


From Java 8 API

It could be easier to take actual implementation from API doc https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long- they are using it to generate longs stream. And your origin can be "0" like in the question.

long nextLong(long origin, long bound) {
  long r = nextLong();
  long n = bound - origin, m = n - 1;
  if ((n & m) == 0L)  // power of two
    r = (r & m) + origin;
  else if (n > 0L) {  // reject over-represented candidates
    for (long u = r >>> 1;            // ensure nonnegative
         u + m - (r = u % n) < 0L;    // rejection check
         u = nextLong() >>> 1) // retry
        ;
    r += origin;
  }
  else {              // range not representable as long
    while (r < origin || r >= bound)
      r = nextLong();
  }
  return r;
}

//use system time as seed value to get a good random number

   Random random = new Random(System.currentTimeMillis());
              long x;
             do{
                x=random.nextLong();
             }while(x<0 && x > n); 

//Loop until get a number greater or equal to 0 and smaller than n


Use the '%' operator

resultingNumber = (r.nextLong() % (maximum - minimum)) + minimum;

By using the '%' operator, we take the remainder when divided by your maximum value. This leaves us with only numbers from 0 (inclusive) to the divisor (exclusive).

For example:

public long randLong(long min, long max) {
    return (new java.util.Random().nextLong() % (max - min)) + min;
}

The methods using the r.nextDouble() should use:

long number = (long) (rand.nextDouble()*max);


long number = x+(((long)r.nextDouble())*(y-x));

From the page on Random:

The method nextLong is implemented by class Random as if by:

public long nextLong() {
   return ((long)next(32) << 32) + next(32);
}

Because class Random uses a seed with only 48 bits, this algorithm will not return all possible long values.

So if you want to get a Long, you're already not going to get the full 64 bit range.

I would suggest that if you have a range that falls near a power of 2, you build up the Long as in that snippet, like this:

next(32) + ((long)nextInt(8) << 3)

to get a 35 bit range, for example.


import java.util*;

    Random rnd = new Random ();
    long name = Math.abs(rnd.nextLong());

This should work


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.


If you can use java streams, you can try the following:

Random randomizeTimestamp = new Random();
Long min = ZonedDateTime.parse("2018-01-01T00:00:00.000Z").toInstant().toEpochMilli();
Long max = ZonedDateTime.parse("2019-01-01T00:00:00.000Z").toInstant().toEpochMilli();
randomizeTimestamp.longs(generatedEventListSize, min, max).forEach(timestamp -> {
  System.out.println(timestamp);
});

This will generate numbers in the given range for longs.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to random

How can I get a random number in Kotlin? scikit-learn random state in splitting dataset Random number between 0 and 1 in python In python, what is the difference between random.uniform() and random.random()? Generate random colors (RGB) Random state (Pseudo-random number) in Scikit learn How does one generate a random number in Apple's Swift language? How to generate a random string of a fixed length in Go? Generate 'n' unique random numbers within a range What does random.sample() method in python do?

Examples related to range

How does String substring work in Swift Creating an Array from a Range in VBA How to create range in Swift? Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3? How to find integer array size in java How does one make random number between range for arc4random_uniform()? Skip over a value in the range function in python Excel Define a range based on a cell value How can I generate a random number in a certain range? Subscript out of range error in this Excel VBA script

Examples related to long-integer

"OverflowError: Python int too large to convert to C long" on windows but not mac How to check a Long for null in java What is the difference between "long", "long long", "long int", and "long long int" in C++? java.math.BigInteger cannot be cast to java.lang.Long A long bigger than Long.MAX_VALUE Definition of int64_t How to convert string to long Convert python long/int to fixed size byte array Converting Long to Date in Java returns 1970 Division of integers in Java