From my understanding (and the javadoc), Random.nextInt should return a positive (or zero) value.
But when I use it with arguments that are power of 2, I often receive negative values. Here is my Random class:
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class SavableRandom extends Random {
private AtomicLong seed = new AtomicLong();
/** {@inheritDoc} */
@Override
protected int next(int bits) {
long newSeed = seed.get();
newSeed ^= (newSeed << 21);
newSeed ^= (newSeed >>> 35);
newSeed ^= (newSeed << 4);
seed.set(newSeed);
return (int) (newSeed >>> (48 - bits));
}
/** @return the seed. */
public long getSeed() {
return seed.get();
}
/** @param seed the seed to set. */
@Override
public void setSeed(long seed) {
if (this.seed != null) {
this.seed.set(seed);
}
}
public static void main(String... args) {
Random random = new SavableRandom();
random.setSeed(536662536331391686L);
System.out.println(random.nextInt(13));
System.out.println(random.nextInt(12));
System.out.println(random.nextInt(16));
}
}
I added a main method with a specific seed so that you could easily reproduce it (the last one returns -1).
What am I doing wrong ?
What am I doing wrong ?
Your newSeed
has more than 48 bits, so (newSeed >>> (48 - bits))
has more than bits
bits, meaning that you're violating the contract of next(int bits)
.
Thanks ! What can I do in the method next to fix it ?
@MKL If you know enough about bit-manipulation to come up with your own random sequence algorithm, then you should know enough to apply a mask using
&
to clear all but the lowerbits
bits of anint
, e.g.x & ((1 << bits) - 1)
Thanks again ! I hope doing so wont mess with probability distribution too much.