6

如果我要以下列方式产生浮点值:

template <typename T>
T RandomFromRange(T low, T high){
    std::random_device random_device;
    std::mt19937 engine{random_device()};
    std::uniform_real_distribution<T> dist(low, high);
    return dist(engine);
}

template <typename T>
T GetRandom(){
    return RandomFromRange
    (std::numeric_limits<T>::min(),std::numeric_limits<T>::max());
}

//produce floating point values:
auto num1 = GetRandom<float>();
auto num2 = GetRandom<float>();
auto num3 = GetRandom<float>();
//...

有没有可能我会得到一个NaN, Inf, 或-Inf

4

2 回答 2

10

让我们考虑一下std::uniform_real_distribution产生了什么。

产生随机浮点值 i,均匀分布在区间 [a, b)

所以,这是介于std::numeric_limits<foat>::min()和之间std::numeric_limits<float>::max(),包括前者,但不包括后者。这些限制返回什么值?他们分别返回FLT_MINFLT_MAX。那么,那些是什么?

最小归一化浮点数

最大可表示的有限浮点数

由于 {positive,negative} 无穷大和 NaN 都不在有限数的范围内,因此不会生成它们。

正如 Christopher Oicles 所指出的,请注意,FLT_MIN并且通过扩展,std::numeric_limits<foat>::min()它是最小的可表示值。

正如 Chris Dodd 所指出的,如果[min, max)超出的范围std::numeric_limits<float>::max(),那么您将获得未定义的行为,在这种情况下,任何输出,包括生成无穷大都是可能的。

于 2016-04-24T16:34:42.303 回答
6

实际上,这会导致未定义的行为,因为std::uniform_real_distribution(我拥有的草案规范的第 26.5.8.2.2 节)的要求:

explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);
    Requires: a ≤ b and b − a ≤ numeric_limits<RealType>::max().
    Effects: Constructs a uniform_real_distribution object; a and b correspond to
             the respective parameters of the distribution.

您的具体示例将超出该numeric_limits要求。

现在您可以构建一个std::uniform_real_distribution<double>std::numeric_limits<float>::min/max为边界的,这应该是明确定义的。您的示例也可能适用于大多数实现(因为它们通常在内部计算中将浮点数提升为双精度数),但它仍然会遇到未定义的行为。

在它不起作用的实现中,我猜最有可能的故障模式是 generate Inf,因为这就是b-a生成的。

于 2016-04-24T17:46:10.820 回答