Почему разрешено держать нижнее слово nextLong () подписанным? - PullRequest
0 голосов
/ 16 сентября 2018

В классе 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 использует именно этот вызов функции. Не влияет ли это на качество генерируемых случайных чисел? Что мне здесь не хватает?

1 Ответ

0 голосов
/ 16 сентября 2018

В настоящее время младшее слово содержит 33 бита, тогда как старшее слово имеет только 32 бита.

...

Что мне здесь не хватает?

Как отмечает Джейкоб Г, нижнее слово содержит 32 бита.Не 33 бита.32-разрядное целое число (грубо говоря) составляет 31 бит точности плюс знаковый бит.

В этом случае мы просто рассматриваем эти 31 + 1 бит как просто биты.Итак, что делает код, чтобы взять две последовательности из 32 равномерно распределенных «случайных» битов, соединить их вместе, чтобы получить одну последовательность из 64 равномерно распределенных «случайных» битов ..., которая затем возвращается как long.

...