/* Author: Sam Trahan, October 2011 This is the implementation of a good but simple random number generator designed by Bob Jenkins, who placed it in the public domain. His website described the algorithm and its public domain status on 2:23 AM EDT October 8, 2011 at this location: http://burtleburtle.net/bob/rand/smallprng.html And at that time, it said, "I wrote this PRNG. I place it in the public domain." (PNRG is an acronym for "psuedo-random number generator" as defined elsewhere on his website.) I modified his code to work as an array of random number generators and generate four output types (float, double, int32, int64). This code is tested on the Intel, IBM and GNU C compilers, and will successfully produce identical floating-point numbers in [0,1) on all three compilers. This code is not sensitive to optimization since all calculations are integer calculations, and hence are exact. This algorithm, unlike the common Mersenne Twister, is not cryptographically secure, so don't use it to encrypt your banking information. However, it does pass the entire suite of DIEHARD tests, so it is sufficiently random for meterological purposes. Its advantage over cryptographically secure algorithms is that it only needs 16 bytes to store its state, and is very fast, allowing us to have an independent random number generator for each gridpoint. That avoids domain decomposition issues and allows us to generate random numbers in parallel across all processes, producing the same results regardless of which process or thread has which gridpoint. Don't change any of the constants in this file without rerunning the full suite of randomness tests as described on Bob's website. Also, don't change the floating-point conversion unless you first test that it correctly produces 0, never produces 1.0, is uniformly distributed, and produces identical results on at least the Intel, GNU and IBM C compilers. */ #include typedef uint32_t u4; typedef uint64_t u8; #define rot(x,k) (((x)<<(k))|((x)>>(32-(k)))) void bobranval_impl( u4 *a, u4 *b, u4 *c, u4 *d, u4 *n ) { u4 e,i,nd=*n; for(i=0;i