Какое минимальное ненулевое значение Math.random() может возвращаться в javascript

Я знаю, что компьютеры не могут работать с континуумами. Функция math.random() javascript возвращает число с плавающей запятой между 0 (включительно) и 1 (исключительно). Интересно, каково минимальное ненулевое число, которое он может вернуть. Какой "шаг" имеет эту функцию?

Ответ 1

Стандарт, конечно же, не выражает это значение, поэтому он зависит от реализации (и преувеличения бит в этой точке, возможно, даже реализации, которая возвращает 0,42, поскольку результат для Math.random() по-прежнему соответствует спецификации).

Наименьшее положительное число, которое может быть представлено 64-битным нормированным числом с плавающей запятой в формате IEEE754, составляет 2 -1022 т.е. 2.2250738585072014 × 10 -308.

Однако представление с плавающей запятой использует различное разрешение в зависимости от величины.

Для чисел, близких к 1, разрешение равно 2 -53. Вероятно (только возможно) многие реализации выбирают случайное целое число n между 0 и 2 53 -1 и используют в качестве результата n/9007199254740992.

Ответ 2

Это почти наверняка не просто выбор любого случайного поплавка.

Это не будет точно представлять шаг случайной функции, потому что оно не будет даже близко к равномерному распределению. Скажем, вы получили этот шаг 2 -1022 "(наименьшее ненулевое значение, которое вписывается в float) плюс 0,25 в качестве случайного значения. Ну, это будет округлено до 0,25, потому что поплавки не могут представлять эту точность. Таким образом, у вас есть целая часть" значений", которые равны 0,25 из-за округления. Это даже не отдаленно однородно.

Я бы сказал, что более вероятно, что float сгенерирован с показателем экспоненты до 0 со случайными битами для мантиссы, что приведет к случайности шага 2 -51 (я думаю, XD) между 1 (включено) и 2 (не включены), из которых вы можете просто вычесть 1. В этом случае шагом будет размер мантиссы.

Ответ 3

ECMA не содержит рекомендаций относительно точности случайности:

Возвращает значение числа с положительным знаком, большим или равным 0, но менее 1, выбранным случайным образом или псевдослучайно с приблизительно равномерным распределением по этому диапазону с использованием зависящего от реализации алгоритма или стратегии. Эта функция не принимает аргументов.

Math.random() возвращает a double между 0 и 1. Мы можем игнорировать показатель экспоненты и знак, и у нас осталось 53 используемых бита. Это означает, что минимальный возможный шаг между числами в совершенном мире 1/2^53 == 0.00000000000000011102230246251565404236316680908203125.

Однако преобладающие реализации JavaScript обеспечивают разные уровни случайности:

  • V8 (Chrome, chromium, node.js): 32 бит (src)
  • JavaScriptCore (Safari) 32 бит (src)
  • SpiderMonkey (Firefox): 53 бит (src)
  • Internet Explorer 53 бит

В то время как в некоторых средах вам будет больше, наименьший общий знаменатель в дикой природе - 32 бита. Даже на сервере ваше приложение node.js получает только 32 бита.

Минимальная точность, на которую вы можете положиться, если вы хотите, чтобы приложение корректно выполнялось везде, 1/2^32 == 0.00000000023283064365386962890625.

Ответ 4

Я не знаю, что говорит спецификация, но быстрый тест на консоли Chrome, Firefox и IE11 показывает, что точность никогда не превышает 20 знаков после запятой.

Проверьте это самостоятельно:

for (var i = 0; i < 1000; ++i) console.log(Math.random());

Или увидеть наименьшее число после большого количества итераций:

var smallest = 1;
for (var i = 0; i < 1000000; ++i) smallest = Math.min(smallest, Math.random());