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

陌路散爱 提交于 2019-12-07 02:55:10

问题


If I were to produce floating point values in the following way:

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

Is it possible that I will ever get back a NaN, Inf, or -Inf?


回答1:


Let's consider what std::uniform_real_distribution generates.

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

So, that's between std::numeric_limits<foat>::min() and std::numeric_limits<float>::max(), including former, but excluding latter. What values do those limits return? They return FLT_MIN and FLT_MAX respectively. Well, what are those?

minimum normalized positive floating-point number

maximum representable finite floating-point number

Since neither {positive,negative} infinity, nor NaN is within the range of finite numbers, no they're not generated.

As pointed out by Christopher Oicles, pay attention that FLT_MIN and by extension, std::numeric_limits<foat>::min() is the smallest positive representable value.

As pointed out by Chris Dodd, if the range of [min, max) exceeds std::numeric_limits<float>::max(), then you would get undefined behaviour and in that case any output, including generating infinity would be possible.




回答2:


Actually, this causes undefined behavior, because of the requirements for std::uniform_real_distribution (section 26.5.8.2.2 of the draft spec I have):

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.

Your specific example will overflow that numeric_limits requirement.

Now you could build a std::uniform_real_distribution<double> with std::numeric_limits<float>::min/max as the bounds, and that should be well-defined. Its also likely that your example will work on most implementations (as they generally promote floats to doubles in internal computations), but it is still hitting undefined behavior.

On implementations where it does't work, I would guess the most likely failure mode would be generating Inf, as that is what the b-a would generate.



来源:https://stackoverflow.com/questions/36825815/will-min-to-max-uniform-real-distribution-produce-inf-inf-or-nan

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!