简体   繁体   中英

Alternatives to using rand() function in C++

I tried this simple code, which "randomly" generates 1's or -1's million times and sums them up:

#include<iostream>
#include<stdlib.h>
#include<time.h>

int pos_or_neg()
{
    if (rand()%2==1) return 1;
    else return -1;
}

int main()
{
    int i,s=0;
    srand (time(NULL));
    for (i=0;i<1000000;i++)
        s+=pos_or_neg();
    std::cout << s;
}

If the rand() instances were independent, then the result should be normally distributed with standard deviation 1000, but I'm getting results of magnitude hundreds at most. If I generate more numbers --- such as 100 millions --- then this is even more striking and the magnitude even decreases !

Is rand() really that bad or am I doing something wrong? In the first case, what are some good alternatives?

rand() is usually implemented with a linear congruential generator, and linear congruential generators are notoriously non-random in their low bits. So either use a different generator, or pick out some other bit; for example, rand() & 0x10 .

Using the following code I have obtained a standard deviation around 1000.

#include <random>
#include <iostream>

constexpr int N = 1000000;

int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, 1);

    int frequencyOfOnes = 0;
    for (int n=0; n<N; ++n)
        frequencyOfOnes += dis(gen);
    std::cout << "Out of " << N << " events, " << frequencyOfOnes << " had 1 as a result " << std::endl;
}

As pointed out by @zett42, there is already a question about this topic. You can go there for more information about that topic.

Generate random numbers using C++11 random library

You should definitely check out this talk, so as to understand why using rand with modulo might not be a good idea.

https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

So if you want an uniform distribution, I strongly suggest that you use http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution

One thing to consider is that taking rand() and using mod on it assumes that RAND_MAX+1 is evenly divisible by your mod function. If it's not, you'll have at least an imbalance because you won't choose "even" the same number of times you'll choose "odd".

In your case of just trying to provide a "coin flip" of random values, use bernoulli_distribution instead.

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