Search code examples
c++randomfloating-pointnanuniform-distribution

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


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?


Solution

  • 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.