В классе java.util.Random
есть метод nextLong (), который сам по себе вызывает next (32), возвращая случайное целое число со знаком.
public long nextLong() {
// it's okay that the bottom word remains signed.
return ((long)(next(32)) << 32) + next(32);
}
Почему сохранение подписанного нижнего слова не влияет на качество случайно сгенерированных чисел? При построении примера бит в середине сгенерированного длинного значения обнуляется, если нижнее слово является отрицательным.
final long INTEGER_MASK = 0xFFFFFFFFL;
int upper = Integer.MAX_VALUE;
int bottom = -1;
System.out.printf("%14s %64s%n","Upper:",Long.toBinaryString(((long)upper << 32)));
System.out.printf("%14s %64s%n","Lower:",Long.toBinaryString((long)bottom));
System.out.printf("%14s %64s%n"," Lower Masked:",Long.toBinaryString(((long)bottom)& INTEGER_MASK));
long result = ((long)upper << 32) + bottom;
System.out.printf("%14s %64s%n","Result:",Long.toBinaryString(result));
//Proper
long resultMasked = ((long)upper << 32) + (((long)bottom & INTEGER_MASK));
System.out.printf("%14s %64s%n%n","Masked",Long.toBinaryString(resultMasked));
Upper: 111_1111_1111_1111_1111_1111_1111_1111_0000_0000_0000_0000_0000_0000_0000_0000
Lower: 1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111
Lower Mask: 1111_1111_1111_1111_1111_1111_1111_1111
Result: 111_1111_1111_1111_1111_1111_1111_1110_1111_1111_1111_1111_1111_1111_1111_1111
Masked 111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111
В настоящее время младшее слово содержит 33 бита, тогда как старшее слово имеет только 32 бита. Даже если верхнее слово является отрицательным из-за 32-битного сдвига, оно не будет перенесено. Я знаю о javadocs, заявляющем, что:
Поскольку класс {@code Random} использует начальное число только с 48 битами,
этот алгоритм не будет возвращать все возможные значения {@code long}.
В этом случае это может быть не вредно, а, например, Реализация gmu MersenneTwister использует именно этот вызов функции. Не влияет ли это на качество генерируемых случайных чисел? Что мне здесь не хватает?