"min to max" 均匀实数分布会产生 Inf、-Inf 还是 NaN?

Will "min to max" uniform real distribution produce Inf,-Inf, or NaN?

如果我按以下方式生成浮点值:

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 吗?

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

Produces random floating-point values i, uniformly distributed on the interval [a, b)

因此,介于std::numeric_limits<foat>::min()std::numeric_limits<float>::max()之间,包括前者,但不包括后者。这些限制 return 的值是多少?他们分别 return FLT_MINFLT_MAX。那么,那些是什么?

minimum normalized positive floating-point number

maximum representable finite floating-point number

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

正如 Christopher Oicles 所指出的,请注意 FLT_MIN 并且推而广之,std::numeric_limits<foat>::min() 是最小的 可表示值。

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

实际上,这会导致未定义的行为,因为 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 会生成的。