简体   繁体   中英

std::uniform_real_distribution - get all possible numbers

I would like to create a std::uniform_real_distribution able to generate a random number in the range [MIN_FLOAT, MAX_FLOAT] . Following is my code:

#include <random>
#include <limits>
using namespace std;

int main()
{
    const auto a = numeric_limits<float>::lowest();
    const auto b = numeric_limits<float>::max();
    uniform_real_distribution<float> dist(a, b);
    return 0;
}

The problem is that when I execute the program, it is aborted because a and b seem to be invalid arguments. How should I fix it?

uniform_real_distribution 's constructor requires:

a ≤ b and b − a ≤ numeric_limits<RealType>::max() .

That last one is not possible for you, since the difference between lowest and max , by definition, must be larger than max (and will almost certainly be INF).

There are several ways to resolve this. The simplest, as Nathan pointed out, is to just use a uniform_real_distribution<double> . Unless double for your implementation couldn't store the range of a float (and IEEE-754 Float64's can store the range of Float32's), this ought to work. You would still be passing the numeric_limits for a float , but since the distribution uses double , it can handle the math for the increased range.

Alternatively, you could combine a uniform_real_distribution<float> with a boolean uniform_int_distribution (that is, one that selects between 0 and 1). Your real distribution should be over the positive numbers, up to max . Every time you get a number from the real distribution, get one from the int distribution too. If the integer is 1, then negate the real value.

This has the downside of making the probability of zero slightly higher than the probability of other numbers, since positive and negative zero are the same thing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM