java - What's wrong with Android's Random.nextInt(2^N)? -


i executed following code several times clicking button:

int = 4; log.println(log.debug, "random", new random().nextint(up) + " "                                 + new random().nextint(up) + " "                                + new random().nextint(up) + " "                                + new random().nextint(up) + " "                                + new random().nextint(up) + " "                                + new random().nextint(up) + " "                                + new random().nextint(up) + " "                                + new random().nextint(up) + " "  ); 

and surprised of getting in log:

04-07 21:26:36.659: d/random(15640): 1 1 1 1 1 1 1 1  04-07 21:26:37.059: d/random(15640): 2 2 2 2 2 2 2 2  04-07 21:26:37.429: d/random(15640): 2 2 2 2 2 2 2 2  04-07 21:26:37.789: d/random(15640): 2 2 2 2 2 2 2 2  04-07 21:26:38.119: d/random(15640): 1 1 1 1 1 1 1 1  04-07 21:26:38.429: d/random(15640): 1 1 1 1 1 1 1 1  04-07 21:26:38.739: d/random(15640): 1 1 1 1 1 1 1 1  04-07 21:26:39.019: d/random(15640): 2 2 2 2 2 2 2 2  04-07 21:26:39.319: d/random(15640): 2 2 2 2 2 2 2 1  04-07 21:26:39.599: d/random(15640): 2 1 1 1 1 1 1 1  

--for sure, these sequences absolutely non-random.

i know, should create 1 instance of random object , call nexint() many times need. java changes static seed number every time new random instance created random() constructor:

public random() {      this(++seeduniquifier + system.nanotime());  } private static volatile long seeduniquifier = 8682522807148012l; 

so produced sequences should random independently on whether use 1 object or every time new one. reason not.

i decided continue research, calling nextint() different arguments. , saw next, surprised me more. noticed every time choose up constant to power of 2, result of new random().nextint(up) remains absolutely non-random, when choose different number, quite ok.

up = 8:

04-07 21:43:47.169: d/random(15789): 5 4 4 4 4 5 5 5  04-07 21:43:47.809: d/random(15789): 7 7 7 7 7 7 7 7  04-07 21:43:48.249: d/random(15789): 6 7 7 7 7 6 6 6  04-07 21:43:48.619: d/random(15789): 6 6 6 6 6 6 6 6  04-07 21:43:48.999: d/random(15789): 5 5 5 5 5 5 4 4  04-07 21:43:49.399: d/random(15789): 4 4 4 4 4 4 4 4 

up = 32:

04-07 21:45:27.979: d/random(15888): 16 15 15 14 15 15 15 24  04-07 21:45:28.329: d/random(15888): 23 23 23 24 24 24 24 21  04-07 21:45:28.549: d/random(15888): 22 20 20 20 20 21 21 21  04-07 21:45:28.849: d/random(15888): 31 31 31 31 31 31 29 29  04-07 21:45:29.329: d/random(15888): 27 28 28 28 26 26 26 26  

but = 10 result looks random, doesn't it? --

04-07 21:47:02.189: d/random(15983): 8 4 1 9 6 6 4 2  04-07 21:47:02.639: d/random(15983): 7 5 3 0 7 5 2 0  04-07 21:47:02.999: d/random(15983): 3 9 6 4 1 8 6 3  04-07 21:47:03.379: d/random(15983): 5 4 1 8 6 3 0 8  04-07 21:47:03.669: d/random(15983): 5 1 8 6 3 3 1 8  04-07 21:47:03.989: d/random(15983): 3 3 1 4 1 8 6 3  04-07 21:47:04.269: d/random(15983): 6 6 3 1 8 5 3 0  

so have 1 question: knows what's happening , why? why results obtained nextint(2^n) non-random while results obtained other argument quite good?

==================================

update. guys in comments on desktop jvm results random independently on number passed nextint() argument. described behavior specific android?

update 2. answer marked best question and, especially, discussion below give quite clear explanation of happens.

from java documentation on nextint():

public int nextint(int n) returns pseudorandom, uniformly distributed int value between 0 (inclusive) , specified value (exclusive), drawn random number generator's sequence. general contract of nextint 1 int value in specified range pseudorandomly generated , returned. n possible int values produced (approximately) equal probability. method nextint(int n) implemented class random if by:

 public int nextint(int n) {    if (n <= 0)      throw new illegalargumentexception("n must positive");     *if ((n & -n) == n)  // i.e., n power of 2      return (int)((n * (long)next(31)) >> 31);*     int bits, val;    {        bits = next(31);        val = bits % n;    } while (bits - val + (n-1) < 0);    return val;  } 

note specific case when n power of 2. regardless of n pass nextint, function next called same input bits, , return statement n times that, time you're issuing power of 2 request, it's going come deterministic.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -