Reputation:
Why is std::uniform_real_distribution
better than rand()
as the random number generator? Can someone give an example please?
Upvotes: 12
Views: 4404
Reputation: 234394
First, it should be made clear that the proposed comparison is nonsensical.
uniform_real_distribution
is not a random number generator. You cannot produce random numbers from a uniform_real_distribution
without having a random number generator that you pass to its operator()
. uniform_real_distribution
"shapes" the output of that random number generator into an uniform real distribution. You can plug various kinds of random number generators into a distribution.
I don't think this makes for a decent comparison, so I will be comparing the use of uniform_real_distribution
with a C++11 random number generator against rand()
instead.
Another obvious difference that makes the comparison even less useful is the fact that uniform_real_distribution
is used to produce floating point numbers, while rand()
produces integers.
That said, there are several reasons to prefer the new facilities.
rand()
is global state, while when using the facilities from <random>
there is no global state involved: you can have as many generators and distributions as you want and they are all independent from each other.
rand()
has no specification about the quality of the sequence generated. The random number generators from C++11 are all well-specified, and so are the distributions. rand()
implementations can be, and in practice have been, of very poor quality, and not very uniform.
rand()
provides a random number within a predefined range. It is up to the programmer to adjust that range to the desired range. This is not a simple task. No, it is not enough to use % something. Doing this kind of adjustment in such a naive manner will most likely destroy whatever uniformity was there in the original sequence. uniform_real_distribution
does this range adjustment for you, correctly.
Upvotes: 12
Reputation: 110658
The real comparison is between rand
and one of the random number engines provided by the C++11 standard library. std::uniform_real_distribution
just distributes the output of an engine according to some parameters (for example, real values between 10 and 20). You could just as well make an engine that uses rand
behind the scenes.
Now the difference between the standard library random number engines and using plain old rand
is in guarantee and flexibility. rand
provides no guarantee for the quality of the random numbers - in fact, many implementations have shortcomings in their distribution and period. If you want some high quality random numbers, rand
just won't do. However, the quality of the random number engines is defined by their algorithms. When you use std::mt19937
, you know exactly what you're getting from this thoroughly tested and analysed algorithm. Different engines have different qualities that you may prefer (space efficiency, time efficiency, etc.) and are all configurable.
This is not to say you should use rand
when you don't care too much. You might as well just start using the random number generation facilities from C++11 right away. There's no downside.
Upvotes: 9
Reputation: 63190
The reason is actually in the name of the function, which is the fact that the uniformity of the distribution of random numbers is better with std::uniform_real_distribution
compared to the uniform distribution of random numbers that rand()
provides.
The distribution for std::uniform_real_distribution
is of course between a given interval [a,b).
Essentially, that is saying that the probability density that when you ask for a random number between 1 and 10 is as great of getting 5 or getting 9 or any other of the possible values with std::uniform_real_distribution
, as when you'd do it with rand()
and call it several times, the probability of getting 5 instead of 9 may be different.
Upvotes: 4