Hacker News new | ask | show | jobs
by Yrlec 5211 days ago
While not exactly a bug, but if you run this code in Java:

  for(int i = 0; i< 100; i++){ 
  	Random random = new Random(i);                                       	
  	System.out.println(random.nextDouble()); 
  }
It prints the following sequence (at least on JDK 7 and Win 7):

  0.730967787376657
  0.7308781907032909
  0.7311469360199058
  0.731057369148862
  0.7306094602878371
  0.730519863614471
  0.7307886238322471
  0.7306990420600421
  0.7302511331990172
  0.7301615514268123
I know that you're not supposed to recreate the Random-instance like that but it's still a bit odd that the initial values in each sequence are so similar to each other.
4 comments

When you created a Random instance and pass in a long value (i), it is used as a seed. And then the seed used to generated random number.

Your seed value from 0-100 is only varies in the last 6 bits out of 64 bits. Which I assume probably caused this whatever psuedo-random function Java is using to generate very similar value for seeds with that low level of entropy. You can look up the formula in Java SDK and do the math.

There's no need to pass in seed value to Random constructor unless you really want to reproduce the same random sequence.

Any reason for the down-vote? I honestly want to learn.
The Java Random class uses a 48-bit LCG with a 35-bit multiplier. Because of this, small seed values won't be able to "wrap around" the full range of the LCG and will cause starting sequences that are all but random relative to each other.

Put differently, you're seeing that 35/48 = 0.73.

I'd consider this a bug in Java, but it's a common one. Qt has the same problem. Could have been avoided by cycling the seed through the LCG once, instead of using XOR.

Interesting, thanks! Any particular reason they limit the multiplier to 35 bits and the output to 48 bits?

Edit: just noticed that Java limits the output to 32 bits, not 48 (http://en.wikipedia.org/wiki/Linear_congruential_generator). How does it create 64 bit values, like long and double?

Any particular reason they limit the multiplier to 35 bits and the output to 48 bits?

Good question. There appears to be no good justification for this, but the generator is guaranteed by the docs. So it's possible the initial implementation was bad and everybody is required to follow it since.

Probably it generates 32 bits twice.
I know nothing about java's random number generator, but your seeds are also very similar to each other.
For any decent RNG, even a lightweight one, that shouldn't matter.
Indeed. When Knuth found was informed of this problem in a random number generator of his, he fixed it: http://news.ycombinator.com/item?id=3730348

There is an obvious use case for this: you have a test which is run N times where you want to have different random numbers in each run, but you also want to be able to go to run X and debug it without running all the previous ones.

Did you intend to link to this page? I'm already here.
Crap, no, and it's too late to edit. I intended to link to: http://www-cs-faculty.stanford.edu/~uno/news02.html#rng

Thanks.

Same sort of thing happens with C#/.NET as well.