Will the “minimum to maximum” uniform real distribution produce Inf, -Inf, or NaN?

If I were to create floating point values ​​as follows:

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 return to NaN , Inf or -Inf ?

+6
source share
2 answers

Consider what std::uniform_real_distribution .

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

So, this is between std::numeric_limits<foat>::min() and std::numeric_limits<float>::max() , including the former, but excluding the latter. What values ​​return these limits? They return FLT_MIN and FLT_MAX respectively. Well what is it?

minimum normalized positive floating point number

The most representable finite floating point number

Since neither {positive, negative} infinity nor NaN are in the range of finite numbers, they are not generated.

As Christopher Oil noted, note that FLT_MIN and finally std::numeric_limits<foat>::min() is the smallest positive representable value.

As Chris Dodd noted, if the range [min, max) exceeds std::numeric_limits<float>::max() , then you will get undefined behavior, in which case any output is possible, including creating infinity.

+9
source

Actually, this causes undefined behavior due to the requirements for std::uniform_real_distribution (section 26.5.8.2.2 of the draft specification that 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 this numeric_limits requirement.

Now you can build std::uniform_real_distribution<double> with std::numeric_limits<float>::min / max as borders, and this should be clearly defined. It is also likely that your example will work on most implementations (since they typically support float for doubling in internal calculations), but it still encounters undefined behavior.

In those implementations where it does not work, I would suggest that the most likely failure mode will generate Inf , since it generates ba .

+6
source

All Articles