1

Please do not dismiss this as a duplicate of: How to generate random positive and negative numbers in java

I need to use a Random number generator with a seed. So, I used the java.util.Random class with a constructor that takes a seed.

Random random = new Random(System.currentTimeMillis());

Then I used the solution given in the above thread

int randomValue = random.nextInt(max - min + 1) + min;

However, the problem with the above solution is that if min is a large negative number and max is a large positive number , then (max - min + 1) would result in overflow.

There should be a better solution out there. Can anyone please point me to it.

Thank you!

Community
  • 1
  • 1
user544192
  • 695
  • 2
  • 10
  • 23
  • 1
    It is, indeed, a duplicate _unless_ you provide more information. – devnull Apr 05 '14 at 17:17
  • Hi devnull, I did provide the information why it is not a duplicate. The reason being (max - min + 1) could result in overflow. – user544192 Apr 05 '14 at 17:21
  • @devnull: unless I'm mistaking, the linked answers don't touch a hypothetical situation that involves `Integer.MIN_VALUE` and `Integer.MAX_VALUE`, which looks like a valid concern. – Jeroen Vannevel Apr 05 '14 at 17:21
  • You could assign the result of max - min + 1 a variable called *range* for example. And then use an if-statement to check if range is negative or too large or whatever causes the overflow – Gee858eeG Apr 05 '14 at 17:22
  • Thanks for the reply, Joroen. Yes, that's the problem with the solution proposed. – user544192 Apr 05 '14 at 17:27
  • @Gee858eeG, What do you think I should when the range is negative? – user544192 Apr 05 '14 at 17:29
  • I don't know. Maybe take Integer.MAX_VALUE as parameter for your Random object. Depends on your application, what is suitable for you. – Gee858eeG Apr 05 '14 at 17:31
  • 2
    I highly recommend you study the Javadoc and source code for `java.util.Random`. There's wealth of information there that should allow you to handle this easily. If `max` and `min` are `int`s, then `max-min` _has_ to fit in a `long`, and all you really want to do is generate 64 random bits and then use the technique from `nextInt()` applied to generate a `long` value. – Jim Garrison Apr 05 '14 at 18:01

1 Answers1

0

How about using BigInteger to avoid int overflow. Also you can use

new BigInteger(int numBits, Random rnd)

to create some BigInteger with randomized bits (up to bit specified with numBits).

So just calculate how many bits you need (range.bitLength() may be useful) check if randomized value is in specified range, so if value is greater than range random again, if everything is OK return randomized value increased by min.

Here is some code example

public static int myRandom(int min, int max, Random r){
    if (max <= min)
        throw new RuntimeException("max value must be greater than min value: max="+max +", min="+min);

    BigInteger maxB = BigInteger.valueOf(max);
    BigInteger minB = BigInteger.valueOf(min);

    BigInteger range = maxB.subtract(minB);
    do{
        BigInteger result = new BigInteger(range.bitLength(), r);
        if (result.compareTo(range)<=0)
            return result.add(minB).intValueExact();
    }while(true);
}
Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • The resulting random function will probably not be uniform. – assylias Apr 05 '14 at 18:36
  • @assylias I am not sure if I understand what you mean by uniform (I am not native English speaker :/ ) but from what I see in documentation of [BigInteger(int numBits, Random rnd) constructor](http://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html#BigInteger-int-java.util.Random-) "*... **uniformly** distributed over the range 0 to (2^numBits - 1)*" so can you say something more about problem with this code? Did I really made some mistake? – Pshemo Apr 05 '14 at 18:51
  • "*if value is greater than range random again*" => you probably introduce a bias in the distribution by doing that. It may not be an issue for the OP though. – assylias Apr 05 '14 at 19:42