views:

260

answers:

4

So here is one of the simplest things one might do:

Random rng = new Random();
int a = rng.nextInt(10);
int b = rng.nextInt(10);

So far so good. But we want to avoid having equal a and b, so naturally we do:

Random rng = new Random();
int a = rng.nextInt(10);
int b = rng.nextInt(10);
while (a == b){
  b = rng.nextInt(10);
}

However — to my very very very big surprise — the while loop never exits. Never.

I understand that, in theory, with random numbers you could have an infinite sequence of one number. But I've had this code running for 10 minutes now and it hasn't exited the loop.

What's up with this? I'm running JDK 6 Update 16 on the latest Linux Mint.

+4  A: 

I don't know why this would be happening -- I tried it in 1.6.0_16 for Windows and had no problems. Here's the complete class:

import java.util.Random;
public class Test {
    public static void main(String[] args) {
        Random rng = new Random();
        int a = rng.nextInt(10);
        int b = rng.nextInt(10);
        while (a == b){
            System.out.println(b + " is equal to " + a + "!");
            b = rng.nextInt(10);
        }
        System.out.println(a);
        System.out.println(b);
    }
}

Sometimes I'll get the "a is equal to b!" output once or twice in a row, but then it works after that.

Kaleb Brasee
So the fail is in whatever thing Linux Mint is
RocketSurgeon
RocketSurgeon: Look at the code for java.util.Random(). I severely doubt that there are any OS dependencies that might change the result.
Joey
+1 - Based on this evidence, it looks like the "Linux Mint" packages for Java are broken and should not be trusted.
Stephen C
A: 

You might try setting the seed to something else to see if that helps.

rng.setSeed(123456);

CBFraser
+7  A: 
 Random rng = new Random();
 int a = rng.nextInt(10);
 int b = rng.nextInt(9);
 if (b >= a) ++b;

Problem solved!

Mark Byers
should'nt it be `if (b == a)` ?
Carlos Heuberger
No. If you did that you'd get a+1 twice as often as the other numbers.
Mark Byers
No, because then you lose the possibility of picking 9, and you double the probability of `a+1`. We are removing a from the set of possibilities for b by shifting [a+1,10) down 1, to remove the hole left by a.
Thanatos
Also, +1 for a deterministic way of doing this.
Thanatos
Carlos, that will make b's value equal (a+1) twice as likely as other values. An even quicker one probably is: if(b==a) b=9;
irreputable
THAT code warrants a comment!
Thorbjørn Ravn Andersen
+1  A: 

Practically, it should work. Something wrong with your environment.

However, theoretically, we can't predict what random is; it is legit if a random generator gives you the same number one million times in a row. To have a deterministic code, you can do this:

int a = rng.nextInt(10);
int b = rng.nextInt( 9);
b = (a+b+1)%10;
irreputable