Ну, математически это просто:
min_value + (max_value - min_value) * (my_random() / (long double)ULONG_MAX)
(Предполагая, что my_random() возвращает равномерно распределенное число от 0 до ULONG_MAX)
Однако, в зависимости от точных значений min_value
, max_value
и ULONG_MAX
, некоторые числа с плавающей запятой почти наверняка будут более вероятными, чем другие.
Каждая возможная случайная длина без знака отображается в число с плавающей запятой по этой формуле. Но поскольку количество различных чисел с плавающей запятой между min_value
и max_value
почти наверняка не равно точно ULONG_MAX
, некоторые беззнаковые длинные числа будут отображаться в одно и то же число с плавающей запятой, или некоторые числа с плавающей запятой не будут иметь никакого беззнакового длинного сопоставления с ними или с обоими.
Исправление этого, чтобы сделать результат действительно однородным,... нетривиально, я думаю. Может быть, кто-то лучше читает, чем я, может процитировать статью.
[редактировать]
Или посмотрите ответ на этот вопрос:
Генерация случайных значений с плавающей запятой на основе случайного битового потока< /а>
Этот ответ зависит от внутреннего устройства представления IEEE double
. Я также не уверен, что полностью понимаю, как это работает.
[править 2]
Хорошо, теперь я понимаю, как это работает. Идея состоит в том, чтобы выбрать случайное представление с плавающей запятой между минимумом и максимумом, а затем отбросить его с вероятностью, обратно пропорциональной его масштабу, представленному его показателем степени. Потому что для равномерного распределения числа между (скажем) 1/2 и 1 должны быть вдвое менее вероятными, чем числа между 1 и 2, но количество представлений с плавающей запятой в этих диапазонах одинаково.
Я думаю, вы могли бы сделать этот код более эффективным, если бы сначала выбирали экспоненту в логарифмическом масштабе, например, используя ffs
для произвольно выбранного целого числа, а затем выбирали мантиссу случайным образом. Хм...
person
Nemo
schedule
22.07.2011