previous_developer
previous_developer

Reputation: 10988

Choose random integer in a range bigger than Integer.MAX_VALUE?

I know there are another questions about random in a range but none of their answers accomplishes what I am trying to do. Actually they have the same error I have. I wrote this simple function to generate random with range.

Random m_random = new Random();
...
public int RandomWithRange(int min, int max) {
    return m_random.nextInt(max - min + 1) + min;
}

If range is bigger than Integer.MAX_VALUE, it throws an IllegalArgumentException: n must be positive. I know it overflows and turn to a negative number. My question is how to handle that?

Example ranges;

Note: min and max must be inclusive.

Upvotes: 4

Views: 1578

Answers (4)

Peter Lawrey
Peter Lawrey

Reputation: 533500

The problem you have is that (max - min) overflows and gives you a negative value.

You can use a long instead.

public int randomWithRange(int min, int max) {
    return (int) ((m_random.nextLong() & Long.MAX_VALUE) % (1L + max - min)) + min;
}

Upvotes: 4

Louis Wasserman
Louis Wasserman

Reputation: 198053

The most "dumb but definitely correct" solution I can think of:

if (max - min + 1 > 0) // no overflow
  return delta + random.nextInt(max - min + 1);
else {
  int result;
  do {
    result = random.nextInt();
  } while (result < min || result > max);
  // finishes in <= 2 iterations on average
  return result;
}

Upvotes: 0

Asgeir
Asgeir

Reputation: 1112

Have you considered getting a random double and then casting back to int

return (int)(m_random.nextDouble() * ((double)max - (double)min) + min);

Upvotes: 2

Hakan Serce
Hakan Serce

Reputation: 11256

You cannot use int in this case. You need to go with BigInteger. The following constructor does what you want (need some tweaking for your needs of course):

BigInteger(int numBits, Random rnd) 

Constructs a randomly generated BigInteger, uniformly distributed over the range 0 to (2numBits - 1), inclusive.

Upvotes: 6

Related Questions