Skip to content

Instantly share code, notes, and snippets.

@TheRayTracer
Created August 2, 2013 01:27
Show Gist options
  • Save TheRayTracer/6136841 to your computer and use it in GitHub Desktop.
Save TheRayTracer/6136841 to your computer and use it in GitHub Desktop.
A small random number generator.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#define SAMPLE_SIZE 36000
namespace std { }
using namespace std;
struct RandomNumberGenerator
{
// Marsaglia MWC generator
// http://en.wikipedia.org/wiki/Talk:Random_number_generation#Marsaglia_MWC_generator
RandomNumberGenerator() : m_z(0x74826158), m_w(0x36187008) { }
RandomNumberGenerator(unsigned int z, unsigned int w) : m_z(z), m_w(w) { }
unsigned int GetUINT()
{
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w; // 0 <= u < 2^32
}
double GetNext()
{
// The magic number below is 1 / (2 ^ 32 + 2).
// The result is strictly between 0 and 1.
return (GetUINT() + 1.0) * 2.328306435454494e-10;
}
private:
unsigned int m_z, m_w;
};
int main(int argc, char* argv[])
{
RandomNumberGenerator rng;
bool failed = false;
vector<double> store(SAMPLE_SIZE);
for (size_t i = 0; i < SAMPLE_SIZE && failed == false; ++i)
{
double r = rng.GetNext();
if (store.end() != find(store.begin(), store.end(), r))
{
cout << "Test failed. Duplicate found." << endl;
failed = true;
}
else
{
store[i] = r;
}
}
assert(failed == false);
if (failed == false)
{
cout << "Test passed." << endl;
}
cin.get();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment