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.
prev
is in the beginning equal to zero, so the first number becomesC
.Then,
prev
is equal toC
, which makes prevA*C + C
. However,A*C
is 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.