Java tutorials home  java.util.Random  Random number generators  XORShift  High quality random  Seeding generators  Entropy  SecureRandom  Random sampling  Random simulations and nextGaussian()

A Java implementation of the Numerical Recipies random number generator

The authors of Numerical Recipes: The Art of Scientific Computing propose a random number generator which they advocate as giving a good compromise between quality and speed. It is a combined generator: two XORShift generators are combined with an LCG and a multiply with carry generator. (Without going into all the details here, notice the two blocks of three shifts each, which are the XORShifts; the first line which is the LCG, similar to the standard Java Random algorithm, and the line between the two XORShifts, which is a multiply with carry generator.)

Their suggested C implementation is trivially portable to Java, and a suggested implementation is given below. In this case, we subclass java.util.Random, and also make the generator thread-safe. If thread safety is not required, then the Lock could be removed.

public class HighQualityRandom extends Random {
  private Lock l = new ReentrantLock();
  private long u;
  private long v = 4101842887655102017L;
  private long w = 1;
  
  public HighQualityRandom() {
    this(System.nanoTime());
  }
  public HighQualityRandom(long seed) {
    l.lock();
    u = seed ^ v;
    nextLong();
    v = u;
    nextLong();
    w = v;
    nextLong();
    l.unlock();
  }
  
  public long nextLong() {
    l.lock();
    try {
      u = u * 2862933555777941757L + 7046029254386353087L;
      v ^= v >>> 17;
      v ^= v << 31;
      v ^= v >>> 8;
      w = 4294957665L * (w & 0xffffffff) + (w >>> 32);
      long x = u ^ (u << 21);
      x ^= x >>> 35;
      x ^= x << 4;
      long ret = (x + v) ^ w;
      return ret;
    } finally {
      l.unlock();
    }
  }
  
  protected int next(int bits) {
    return (int) (nextLong() >>> (64-bits));
  }

}

When should you use this generator?

This generator is useful in cases where you need fast, good-quality randomness but don't need cryptographic randomness, as provided by the Java SecureRandom class. The code above is not much slower than java.util.Random and provides much better quality randomness and a much larger period. It is about 20 times faster than SecureRandom. Typical candidates for using this generator would be games and simulations (except games where money depends on the random number generator, such as in gambling applications).

comments powered by Disqus

Written by Neil Coffey. Copyright © Javamex UK 2013. All rights reserved.