2

In order to understand how java.util.random works, I wrote a piece of simple code to simulate the java random functions and compared the results of java random function's and my function's. However, the results are different. It means either I made some mistakes or I misunderstood the concept.

import java.util.Random;

public class test2 {
  private static long multiplier = 0x5DEECE66DL;

  private static long addend = 0xBL;

  private static long mask = (1L << 48) - 1;


  public static void main(String args[]){
    long seed = 128856;
    Random random = new Random(seed);
    long n1 = random.nextInt();
    long n2 = random.nextInt();
    long n3 = random.nextInt();

    System.out.println("Results: " + n1 +" "+ n2 +" "+ n3);


    System.out.println("seed: " + seed);
    long seed0 = (seed ^ multiplier) & mask;
    System.out.println("seed0: " + seed0);

    long seed1 = ((seed0 * multiplier + addend) & mask);
    System.out.println("seed1: " + seed1);     
    long v1 = seed1 >>> 16;
    System.out.println("v1: " + v1);

    long seed2 = ((seed1 * multiplier + addend) & mask); 
    System.out.println("seed2: " + seed2);
    long v2 = seed2 >>> 16;
    System.out.println("v2: " + v2);
  }   

}

And here is the screenshot of the result: Result

n1 is not equal to v1. Please tell me what the mistakes I made? Thank you.

Alan Wu
  • 115
  • 9
  • There are many algorithms to create pseudo-random numbers. – OldProgrammer Nov 10 '17 at 19:20
  • @OldProgrammer I am trying to understand java.util.random which I believe it is linear congruential generator. – Alan Wu Nov 10 '17 at 19:25
  • 1
    Well here is the openjdk version - http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/Random.java – OldProgrammer Nov 10 '17 at 19:26
  • @OldProgrammer Thank you for the link. Although I have checked that before I wrote my code. The code was written based on that. However, I still don't understand why the results are not same. Could you please tell me why? – Alan Wu Nov 10 '17 at 19:39
  • Your code calculates almost correct values. The problem is that `Random.nextInt()` returns an int value that you expand to a long, but your code calcuates a long value instead of an int. The lower 32 bits of n1 and v1 are the same – Thomas Kläger Nov 10 '17 at 19:40
  • @ThomasKläger I changed the v1 and v2 to int, and the results are same. Problem solved! Thank you very much! – Alan Wu Nov 10 '17 at 19:50

1 Answers1

0

Good Question! Random Generator is not a random generator afterall! The only difference between your generation and what Random does it you return a long, while Random casts it to int.

The following change will fix it:

public static void main(String args[]){
     long multiplier = 0x5DEECE66DL;

    long addend = 0xBL;

     long mask = (1L << 48) - 1;

    long seed = 128856;
    Random random = new Random(seed);
    long n1 = random.nextInt();
    long n2 = random.nextInt();
    long n3 = random.nextInt();

    System.out.println("Results: " + n1 +" "+ n2 +" "+ n3);


    System.out.println("seed: " + seed);
    long seed0 = (seed ^ multiplier) & mask;
    System.out.println("seed0: " + seed0);

    long seed1 = ((seed0 * multiplier + addend) & mask);
    System.out.println("seed1: " + seed1);
    int v1 = (int)(seed1 >>> 16);
    System.out.println("v1: " + v1);

    long seed2 = ((seed1 * multiplier + addend) & mask);
    System.out.println("seed2: " + seed2);
    int v2 = (int)(seed2 >>> 16);
    System.out.println("v2: " + v2);
}