Uniform_real не принимает numeric_limits :: lower () - PullRequest
0 голосов
/ 27 августа 2018

У меня есть строка:

std::uniform_real_distribution<T> distribution(std::numeric_limits<T>::lowest(), 
                                               std::numeric_limits<T>::max());

Компилируется, но вылетает при отладке (VS 2017CE). Я предполагаю, что согласно документации std::uniform_real_distribution:

Требуется, чтобы a ≤ b и b-a ≤ std::numeric_limits<RealType>::max()

когда мои b равны ::max(), а a равны ::lowest(), условие:

b-a ≤ std::numeric_limits<RealType>::max()

не выполняется, поскольку b-a в основном удваивает значение max. Есть ли способ обойти это так, чтобы я оставил такой широкий диапазон чисел? ::min() работает отлично, но пропускает отрицательные значения. Проблема возникает только для плавающих чисел.

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Один из способов сделать это - использовать диапазон [-1, 1], а затем умножить его на std::numeric_limits<T>::max(), чтобы получить фактическое число. Это позволяет удовлетворить требование b-a ≤ std::numeric_limits<RealType>::max().

auto dis = std::uniform_real_distribution<T> dis(-1, std::nextafter(1, std::numeric_limits<T>::max()));
return dis(eng) * std::numeric_limits<T>::max();

Это не даст вам все возможные значения с плавающей запятой, но даст вам большое количество их, распределенных как uniform_int_distribution.

0 голосов
/ 27 августа 2018

Одно простое решение, по крайней мере для обычных чисел с плавающей запятой IEEE-754, будет случайным образом отображать знак случайного неотрицательного числа:

std::uniform_real_distribution<T> distribution(0., 
                                               std::numeric_limits<T>::max());
auto rn = distribution(eng);
return someRandomFlag ? rn : -rn;

, где someRandomFlag выбирается равномерно из {true, false}.

...