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