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