I wrote a simple program (tried to implement the Linear congruential generator actually), but I'm not quite sure it works like it should.
I wanted to generate 250 number from [0,1] using my generator. However, it seems that instead of random numbers, I get equal values ..
How to improve it / what I did wrong?
Here's the code:
#include <iostream>
#include <cmath>
static const double A = 0.001342;
static const double C = 0.00025194;
static const double RAND_MAX = 1.0;
double rand()
{
static double prev = 0;
prev = A * prev + fmod(C, RAND_MAX);
return prev;
}
int main(int argc, char **argv)
{
for(int i=0; i<6; i++)
std::cout << rand() << "\n";
return 0;
}
And the output:
0.00025194
0.000252278
0.000252279
0.000252279
0.000252279
0.000252279
Switching to int instead of double, however gives some nice results:
#include <iostream>
#include <cmath>
static const int A = 5;
static const int C = 3;
static const int RAND_MAX = 8;
double rand()
{
static int prev = 1;
prev = A * prev + (C % RAND_MAX);
return prev;
}
int main(int argc, char **argv)
{
for(int i=0; i<100; i++)
std::cout << rand() << "\n";
return 0;
}
Output:
8
43
218
1093
5468
27343
136718
683593
3.41797e+06
1.70898e+07
8.54492e+07
4.27246e+08
2.13623e+09
2.09122e+09
1.86615e+09
7.40836e+08
-5.90786e+08
1.34104e+09
...
But I need it for generating random double numbers, greater than or equal to 0 and less than or equal to 1 :(
It's not the program, it's the choice of numbers.
previs in the beginning equal to zero, so the first number becomesC.Then,
previs equal toC, which makes prevA*C + C. However,A*Cis so small, that when adding it as a floating point to the previous one, significant digits are shifted out and you're left with what you had before.You can read more on What Every Computer Scientist Should Know About Floating-Point Arithmetic.