“最小到最大”均匀实际分布会产生Inf,-Inf还是NaN?

时间:2016-04-24 16:25:05

标签: c++ random floating-point nan uniform-distribution

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

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>();
//...

我是否有可能找回NaNInf-Inf

2 个答案:

答案 0 :(得分:9)

让我们考虑std::uniform_real_distribution生成的内容。

  

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

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

  

最小标准化浮点数

     

最大可表示的有限浮点数

由于{正,负}无穷大,NaN都不在有限数范围内,所以不会生成它们。

正如Christopher Oicles所指出的那样,请注意FLT_MINstd::numeric_limits<foat>::min()是最小的可表示的值。

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

答案 1 :(得分: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,这应该是明确定义的。它也可能是你的例子适用于大多数实现(因为它们通常会促进浮点数在内部计算中加倍),但它仍然会遇到未定义的行为。

在它无效的实施中,我猜最有可能的失败模式是生成Inf,因为这是b-a将生成的。