ОК, поэтому существенная проблема заключается в том, что вам нужно выполнять деление с плавающей точкой, а не целочисленное деление, как указывали другие.
Но я думаю, что исправление этого конкретного кода является чем-то особенным. Зачем беспокоиться об этом в первую очередь? Он использует по сути тот же класс алгоритма, что и java.lang.Random!
Если вам нужен быстрый генератор, рассмотрите генератор XORShift . Если вам нужен генератор хорошего качества, у вас есть SecureRandom из коробки (хотя он намного медленнее), рассмотрите алгоритм Numeric Recipes (довольно быстрый, комбинированный генератор), который вы можете реализовать в Java как следующим образом:
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();
}
@Override
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;
return (x + v) ^ w;
} finally {
l.unlock();
}
}
protected int next(int bits) {
return (int) (nextLong() >>> (64-bits));
}
}
Это скопировано из некоторого кода, где я хотел, чтобы он был параллельным; вы можете в принципе избавиться от блокировки или просто использовать обычную синхронизацию.
Если вы абсолютно настаиваете на использовании Park-Miller-Carta, я бы, по крайней мере, обернул его в подкласс Random и позволил java.util.Random позаботиться о преобразовании целых чисел в двойные и т. Д. - в конце концов, это то, что расширяемо библиотеки на объектно-ориентированном языке предназначены для ...