I need a PRNG for a simulation project, and found a resource which, given my limited but not nonexistent knowledge of PRNG's seems sound and well-informed. I'm trying to encapsulate the algorithms given in this report in a class, but for some reason I get a lot of repeated values. It might just be that the PRNG isn't as good as the report states it is, but I suspect that it's rather something in my implementation that fails.
Background: PRNG code from the report
The following code sample is given on page 3:
/* Public domain code for JKISS RNG */
// seed variables
static unsigned int x = 123456789,y = 987654321,z = 43219876,c = 6543217;
unsigned int JKISS()
{
unsigned long long t;
x = 314527869 * x + 1234567;
y ^= y << 5; y ^= y >> 7; y ^= y << 22;
t = 4294584393ULL * z + c; c = t >> 32; z = t;
return x + y + z;
}
In connection with it, the report claims that
The period of JKISS is ≈2 127 = 1.7x10 38 (2 32 x (2 32 -1) x (1/2 *
4294584393 x 2 32 - 1)) and it passes all of the Dieharder tests and the complete BigCrunch test set in
TestU01.
so this definitely seems good enough to me. Later in the report (page 6), it is stated
The following C code generate [sic] a random (double precision) floating point number 0 <= x < 1:
double x;
x = JKISS() / 4294967296.0;
My encapsulation of this in a class
I have the following in a header file:
class JKISS : public IPRNG {
private:
// Seed variables
static unsigned int x;
static unsigned int y;
static unsigned int z;
static unsigned int c;
public:
static unsigned int randui32();
static double randdouble();
};
with the following implementation file
#include "prng.hpp"
unsigned int JKISS::x = 123456789;
unsigned int JKISS::y = 987654321;
unsigned int JKISS::z = 43219876;
unsigned int JKISS::c = 6543217;
unsigned int JKISS::randui32() {
unsigned long long t;
x = 314527869 * x + 1234567;
y ^= y << 5; y ^= y >> 7; y ^= y << 22;
t = 4294584393ULL * z + c; c = t >> 32; z = t;
return x + y + z;
}
double JKISS::randdouble() {
return randui32() / 4294967296.0;
}
and the following main program
#include <iostream>
#include "prng.hpp"
int main() {
for (int i = 0; i < 10000; ++i) {
std::cout << JKISS::randdouble() << std::endl;
}
}
As you can see, I've copy-pasted most of the code.
However, when I run this, I get 68 repeated values, even though I'm just fetching 10 000 values. This suggests to me that something is wrong with my encapsulation, but I can't figure out what the problem is.
In case it matters, I'm running GCC 4.8.1 on Ubuntu 13.10 with the following specs:
Platform Info:
System: Linux (x86_64-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E5410 @ 2.33GHz
WORD_SIZE: 64
Any ideas as to what could cause this are most welcome.