2013-07-22 17 views
6

я был удивлен видеть, что выход этой программы:Сколько случайных чисел использует std :: uniform_real_distribution?

#include <iostream> 
#include <random> 

int main() 
{ 
    std::mt19937 rng1; 
    std::mt19937 rng2; 
    std::uniform_real_distribution<double> dist; 

    double random = dist(rng1); 
    rng2.discard(2); 

    std::cout << (rng1() - rng2()) << "\n"; 

    return 0; 
} 

является 0 - т.е. std::uniform_real_distribution использует два случайных чисел, чтобы произвести случайное double значение в диапазоне [0,1). Я думал, что это просто сгенерирует один и перемасштабирует это. Подумав об этом, я предполагаю, что это связано с тем, что std::mt19937 производит 32-битные int и double в два раза больше этого размера и, следовательно, не «случайным образом».

Вопрос: Как узнать это число в общем случае, т. Е. Если генератор случайных чисел и тип с плавающей точкой являются произвольными типами?

Редактировать: Я только заметил, что вместо этого могу использовать std::generate_canonical, так как меня интересуют только случайные числа [0,1]. Не уверен, что это имеет значение.

+0

Вы не можете найти это в общих чертах. –

+2

@ R.MartinhoFernandes: потому что ... – arne

+1

Как в стороне, подумайте, что это означало бы «перемасштабировать» 32-битное целое число в 64-битном двойном: имеется приблизительно 2^62 различных двойных значения. Существует 2^32 различных значения int. Это означает, что только ** один из каждых миллиардов ** возможных двойных значений будет представлен в двойном результате. Это явно неприемлемо. – JohannesD

ответ

2

Для template<class RealType, size_t bits, class URNG> std::generate_canonical стандартной (раздел 27.5.7.2) явно определяет количество вызовов единого генератора случайных чисел (НРЕГ), чтобы быть

макс (1, б/log_2 R)

, где b - минимальное количество бит в мантиссе RealType и количество бит, заданных для generate_canonical в качестве параметра шаблона. R - это диапазон номеров, который может получить URNG (URNG::max()-URNG::min()+1). Однако в вашем примере это не будет иметь никакого значения, так как вам нужно 2 вызова mt19937 для заполнения 53 бит мантиссы двойника.

Для других дистрибутивов стандарт не предоставляет общий способ получения какой-либо информации о количестве номеров, которые должен иметь URNG для получения одного номера распределения.

Причина может заключаться в том, что для некоторых распределений число равномерных случайных чисел, необходимых для создания одного номера распределения, не является фиксированным и может варьироваться от вызова к вызову. Примером может служить std::poisson_distribution, который обычно реализуется как цикл, который рисует равномерное случайное число на каждой итерации до тех пор, пока произведение этих чисел не достигнет определенного порога (см., Например, implementation of the GNU C++ library (строка 1523-1528)).

Смежные вопросы