package hex.rng;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
/**
* Simple XorShiftRNG.
*
* Note: According to RF benchmarks it does not provide so accurate results
* as {@link java.util.Random}, however it can be used as an alternative.
*
*/
public class XorShiftRNG extends Random {
private AtomicLong _seed;
public XorShiftRNG (long seed) {
this._seed = new AtomicLong(seed);
}
@Override
public long nextLong() {
long oldseed, nextseed;
AtomicLong seed = this._seed;
do {
oldseed = seed.get();
nextseed = xorShift(oldseed);
} while (!seed.compareAndSet(oldseed, nextseed));
return nextseed;
}
@Override
public int nextInt() {
return nextInt(Integer.MAX_VALUE);
}
@Override
public int nextInt(int n) {
int r = (int) (nextLong() % n);
return r > 0 ? r : -r;
}
@Override
protected int next(int bits) {
long nextseed = nextLong();
return (int) (nextseed & ((1L << bits) - 1));
}
private long xorShift(long x) {
x ^= (x << 21);
x ^= (x >>> 35);
x ^= (x << 4);
return x;
}
}