From wikipedia (цитата, на которую ссылается цитата, размещенная @ helloworld922):
Еще одна проблема LCG состоит в том, что биты младшего разряда сгенерированной последовательностииметь намного более короткий период, чем последовательность в целом, если m установлен на степень 2. В общем, n-ная младшая цифра в базовом b представлении выходной последовательности, где bk = m для некоторого целого числа k, повторяется ссамое большее период bn.
И, кроме того, он продолжается (мой курсив):
Младшие биты LCG, когда m - степень 2никогда не следует полагаться на какую-либо степень случайности .Действительно, простая замена 2n на член модуля показывает, что биты младшего разряда проходят очень короткие циклы.В частности, любой полный цикл LCG, когда m является степенью 2, будет давать попеременно нечетные и четные результаты.
В конце концов, причина, вероятно, историческая: люди в Sun хотели, чтобы что-то работалонадежно, а формула Кнута дала 32 значащих бита.Обратите внимание, что API java.util.Random
говорит следующее (мой курсив):
Если два экземпляра Random создаются с одним и тем же начальным числом и выполняется одна и та же последовательность вызовов методовдля каждого они будут генерировать и возвращать идентичные последовательности чисел. Чтобы гарантировать это свойство, для класса Random указаны конкретные алгоритмы.Реализации Java должны использовать все алгоритмы, показанные здесь для класса Random, для абсолютной переносимости кода Java. Однако подклассам класса Random разрешено использовать другие алгоритмы, если они придерживаются общих контрактов длявсе методы.
Так что мы застряли с ним в качестве эталонной реализации.Однако это не означает, что вы не можете использовать другой генератор (и подкласс Random или создать новый класс):
с той же страницы Википедии:
MMIX от Donald Knuth m= 2 64 a = 6364136223846793005 c = 1442695040888963407
Существует 64-битная формула для вас.
Случайные числа являются хитрыми (как отмечает Кнут) и зависят отесли вам нужно 64-битное число, вам может быть достаточно просто дважды набрать java.util.Random
и объединить биты.Если вы действительно заботитесь о статистических свойствах, используйте что-то вроде Mersenne Twister или, если вас волнует утечка / непредсказуемость информации, используйте java.security.SecureRandom
.