Могу ли я сгенерировать случайный поплавок на всем пространстве?

Я пытаюсь сгенерировать случайное число в диапазоне от Number.MIN_VALUE до Number.MAX_VALUE, но следующий алгоритм не работает из-за переполнения буфера (я думаю):

var randFloat = Math.floor(Math.random() * (Number.MAX_VALUE - Number.MIN_VALUE)) + Number.MIN_VALUE

Есть ли способ сделать это?


person Magix    schedule 28.03.2017    source источник
comment
crypto.getRandomValues(new Uint32Array(1))[0] почти настолько хорош, насколько это возможно; используйте деление, чтобы плавать   -  person dandavis    schedule 29.03.2017
comment
Что вы подразумеваете под использованием разделения для его плавания?   -  person Magix    schedule 29.03.2017
comment
Он означает, что функция вернет последовательность цифр в виде целого числа. Переместите десятичную запятую влево, разделив на степень 10, чтобы создать число с плавающей запятой с желаемым количеством цифр справа от десятичной запятой.   -  person mba12    schedule 29.03.2017
comment
Сгенерируйте случайные 64 бита, затем используйте формулу на en.wikipedia.org/wiki/Double -precision_floating-point_format, чтобы преобразовать эти биты в число. Если вы не хотите, чтобы Infs и NaNs повторяли попытку, если показатель степени не равен 7ff.   -  person zerkms    schedule 29.03.2017
comment
Разве это не помешает случайным числам быть однородными или уменьшить случайное пространство ?? :/   -  person Magix    schedule 29.03.2017
comment
Что именно вы подразумеваете под униформой?   -  person David Eisenstat    schedule 29.03.2017
comment
все номера от Number.MIN_VALUE до Number.MAX_VALUE (включительно) имеют одинаковую вероятность быть выбранными каждый раз   -  person Magix    schedule 29.03.2017
comment
Знаете ли вы, что MIN_VALUE — это наименьшее положительное число?   -  person Bergi    schedule 29.03.2017
comment
Вы хотите генерировать только целые числа?   -  person Bergi    schedule 29.03.2017
comment
Что именно вы подразумеваете под всеми цифрами? Все действительные числа? Все целые числа? Все представимые числа с плавающей запятой?   -  person Bergi    schedule 29.03.2017
comment
Все числа с плавающей запятой   -  person Magix    schedule 29.03.2017
comment
Затем используйте подход @zerkms для генерации 64 случайных битов (или 63, если вам нужны только положительные значения)   -  person Bergi    schedule 29.03.2017


Ответы (1)


Что вы можете сделать:

function IEEEToDouble(f)
{
    return new Float64Array(f.buffer)[0];
}

var array = new Uint32Array(2); // here we allocate a 2 element unsigned 32 bit ints
window.crypto.getRandomValues(array); // here we generate 64 bits of random values
var f = IEEEToDouble(array); // and convert 64 bits to a double precision number

Это генерирует равномерно распределенный номер двойной точности IEEE754. Таким образом, с помощью этого кода одинаково возможно получить любое возможное значение во всем пространстве, включая NaNs (на самом деле там довольно много NaNs - 2^53 - 2) и Infinitys.

Использованная литература:

person zerkms    schedule 28.03.2017
comment
В любом случае это можно сделать без window.crypto? Я использую Node.JS, и он недоступен:/ - person Magix; 29.03.2017
comment
@Magix nodejs.org/api/ Подойдет любой случайный источник, соответствующий вашим потребностям. - person zerkms; 29.03.2017
comment
Зависит от определения униформы - каждое значение равновероятно, но их плотность сильно смещена в сторону нуля. - person Oliver Charlesworth; 29.03.2017
comment
Мне действительно интересно, почему вы просто не берете f.buffer вместо того, чтобы создавать еще один буфер и два массива только для копирования значения из входного массива. - person Bergi; 29.03.2017
comment
(см. мой ответ на связанный вопрос) - person Bergi; 29.03.2017
comment
@Bergi без особой причины, я просто не удосужился проверить детали реализации. Теперь улучшилось. - person zerkms; 29.03.2017