Today one of my equations which used rand() function from C standard library, had very strange results. My equation sometimes was more than 5% off the actual result it should be. After many attempts trying to find the problem with the equation. I thought of checking the rand() distribution. As far as I know it should be uniform.
But is it...
At first I wrote a quick code to generate 106 numbers in range of [0;100]. As you can see in the picture below it is more or less uniformly distributed.
Code:
#include <QtCore/QCoreApplication>
#include <time.h>
#include < iostream >
#include < random >
#include < fstream >
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int numbers[101] = {0};
srand(time(0));
for(int i=0; i<1000000; i++)
numbers[rand()%100]++;
ofstream fout("randoms.txt");
for(int i=0; i<=101; i++)
fout << numbers[i] << endl;
cout << "Done!";
return a.exec();
}
I tested the code above couple times, and more or less got the same results over and over. But the really insteresting graph appeared when I changed the range from [0;100] to [0;10000] like I have in my real application. The result, the rand() has a very strange drop in distribution around 2500. Immediately I changed the range in my real application to 100 and the error dropped from 5% to around 0.2%, which is in acceptable levels.
I remember reading the changes in C++11 and they included a standard random library, I thought it was time to test it out. Whether it will have the same behaviour as the old C rand() function. The result, it works perefectly, the new std library doesn't seem to have that drop around 2500, see the graph below.
Code:
#include <QtCore/QCoreApplication>
#include <time.h>
#include < iostream >
#include < random >
#include < fstream >
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int numbers[10001] = {0};
std::random_device rd;
std::mt19937_64 gen(rd());
std::uniform_int_distribution<> dis(0, 10001);
srand(time(0));
for(int i=0; i<1000000; i++)
numbers[dis(gen)]++;
ofstream fout("randoms.txt");
for(int i=0; i<=10000; i++)
fout << numbers[i] << endl;
cout << "Done!";
return a.exec();
}
To sum up, it looks like the C rand() function is outdated and actually doesn't produce a well unofrmed random numbers. If you want to generate small range of random numbers which doesn't exceed 2000, then you might be able to use rand(), however as soon as you need a higher range, the rand() fails misserably. Probably good idea would be the use the new C++11 STD random library every time you need some random numbers. Strangley enough, I wasn't able to find any article about this issue, maybe someone who reads this, could explain to me how come the rand() function fails with uniform distribution, that would be very interesting to me.