Насколько случайным является JavaScript Math.random?
В течение 6 лет у меня на моем сайте была страница
Сегодня кто-то отправил мне письмо по электронной почте, чтобы сказать мне, что он может быть не таким случайным, как я думал.. Она пыталась создать очень большие случайные числа (например, между 1 и 10000000000000000000) и обнаружила, что они почти всегда столько же цифр. В самом деле, я завернул функцию в цикл, чтобы я мог генерировать тысячи чисел и, конечно же, для очень больших чисел изменение было всего лишь на 2 порядка.
Почему?
Вот петлевая версия, поэтому вы можете попробовать ее сами:
Он включает как прямую реализацию, взятую из , так и некоторый код с 1997 года, который я удалил с веб-страницы, которая больше не существует (Paul Houle "Центральный рандомизатор 1.3" ). Просмотрите источник, чтобы узнать, как работает каждый метод.
Я прочитал и о Mersenne Twister. Я интересуюсь тем, почему в результатах встроенной функции Math.random не будет больше изменений в результатах. Спасибо!
Ответы
Ответ 1
Указанные числа между 1 и 100.
- 9 имеют 1 цифру (1-9)
- 90 имеют 2 цифры (10-99)
- 1 имеет 3 цифры (100)
Приведенные числа от 1 до 1000.
- 9 имеют 1 цифру
- 90 имеют 2 цифры
- 900 имеют 3 цифры
- 1 имеет 4 цифры
и т.д.
Итак, если вы выбираете случайным образом, то подавляющее большинство выбранных чисел будет иметь одинаковое количество цифр, потому что подавляющее большинство возможных значений имеют одинаковое количество цифр.
Ответ 2
Ожидаются ваши результаты. Если случайные числа равномерно распределены в диапазоне от 1 до 10 ^ n, то вы ожидаете, что около 9/10 чисел будут иметь n цифр, а еще 9/100 - n-1.
Ответ 3
Существуют разные типы случайности. Math.random дает вам равномерное распределение чисел.
Если вы хотите разные порядки, я бы предложил использовать экспоненциальную функцию для создания того, что называется распределение законности закона:
public void powerlaw(int minimum, int maxmimum) {
random_number = Math.floor(Math.exp(Math.random()*Math.log(maxmimum-minimum+1)))+minimum
return random_number
}
Эта строка должна содержать примерно одно число из 1-значного числа в виде 2-значных чисел и трехзначных чисел.
Существуют также другие распределения для случайных чисел, таких как нормальное распределение (также называемое гауссовским распределением).
Ответ 4
В следующем документе объясняется, как math.random() в основных веб-браузерах (un) безопасно:
" Временное отслеживание пользователей в основных браузерах и кросс-доменная информация
утечка и атаки "Амида Клейна (Amid Klein, 2008). Это не более сильное, чем обычные встроенные функции PRNG Java или Windows.
С другой стороны, для реализации SFMT периода 2 ^ 19937-1 требуется 2496 байт внутреннего состояния, поддерживаемого для каждой последовательности PRNG. Некоторые люди могут считать это непростительной ценой.
Ответ 5
Выглядит совершенно случайно для меня!
(Подсказка: он зависит от браузера.)
Лично я считаю, что моя реализация была бы лучше, хотя я украл ее из XKCD, который ВСЕГДА должен быть подтвержден:
random = 4; // Chosen by a fair dice throw. Guaranteed to be random.
Ответ 6
Если вы используете число, например 10000000000000000000, вы выходите за пределы точности типа данных, используемого Javascript. Обратите внимание, что все порожденные числа заканчиваются на "00".
Ответ 7
Я попробовал генератор псевдослучайных чисел JS на Chaos Game.
Мой Треугольник Sierpiński говорит о его довольно случайном:
![Fractal]()
Ответ 8
Хорошо, если вы генерируете числа до, скажем, 1e6, вы, надеюсь, получите все числа с приблизительно равной вероятностью. Это также означает, что у вас есть только одна десятая вероятность получить число с одной цифрой меньше. Один из сотен шансов получить две цифры меньше и т.д. Я сомневаюсь, что вы увидите большую разницу при использовании другого RNG, потому что у вас есть равномерное распределение по номерам, а не их логарифм.