2013-04-25 4 views
9

C++ 11 std :: uniform_real_distribution (-1, 1) дает числа в диапазоне [-1,1).std :: uniform_real_distribution включительно

Как вы получите равномерное реальное распределение в диапазоне [-1,1]?

Практически это, вероятно, не имеет значения, но логически. Я пытаюсь выбрать значение в инклюзивном диапазоне.

ответ

14

Об этом легче думать, если вы начнете с поиска целых чисел. Если вы пройдете [-1, 1), вы ожидаете получить -1, 0. Поскольку вы хотите включить 1, вы должны передать [-1, (1 + 1)) или [-1, 2). Теперь вы получаете -1, 0, 1.

Вы хотите сделать то же самое, но с двойниками:

заимствование из this answer:

#include <cfloat> // DBL_MAX 
#include <cmath> // std::nextafter 
#include <random> 
#include <iostream> 

int main() 
{ 
    const double start = -1.0; 
    const double stop = 1.0; 

    std::random_device rd; 
    std::mt19937 gen(rd()); 

    // Note: uniform_real_distribution does [start, stop), 
    // but we want to do [start, stop]. 
    // Pass the next largest value instead. 
    std::uniform_real_distribution<> dis(start, std::nextafter(stop, DBL_MAX)); 

    for (auto i = 0; i < 100; ++i) 
    { 
    std::cout << dis(gen) << "\n"; 
    } 
    std::cout << std::endl; 
} 

(см код запуска here)

То есть, найти второй по величине двойной значение после того, которое вы хотите, и передайте это вместо конечного значения.

+1

Замечательно, спасибо. Кажется, что VS2012 не имеет этой функции, но, к счастью, он добавляет ее в [математический инструментарий] (http://www.boost.org/doc/libs/1_53_0/libs/math/doc/sf_and_dist/html/math_toolkit/utils/ next_float/nextafter.html) –

+0

Стандартные распределения с плавающей запятой не обеспечивают точность вплоть до последней цифры точности, но вместо этого страдают от проблем округления, которые означают, что нецелесообразно пытаться использовать их таким образом. – bames53

1

К сожалению, фактические реализации распределений с плавающей запятой не позволяют вам быть настолько точными. Например, uniform_real_distribution<float> должен создавать значения в заданном полудиапазоне, но из-за проблем округления он может фактически производить значения в инклюзивном диапазоне.

Here's пример проблемы с generate_cannonical, и подобные проблемы возникают с другими real_distributions.

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