xoroshiro128+ random number generator
Joseph Rushton Wakeling via Digitalmars-d-announce
digitalmars-d-announce at puremagic.com
Fri Apr 29 14:40:49 PDT 2016
Spotted this reddit post the other day:
https://www.reddit.com/r/programming/comments/4gtlfz/xoroshiro128_the_fastest_fullperiod_pseudorandom/
... and it reminded me that I've been meaning for some time to
follow up on the interesting RNG designs by Sebastiano Vigna and
colleagues. Since I had a free moment, I thought I'd knock up a
D port of the public-domain C reference code available here:
http://xorshift.di.unimi.it/xoroshiro128plus.c
It's a first draft and obviously needs documentation, tests, etc.
before I submit it to Phobos, but I thought I'd throw it out here
if anyone wants to play with it and/or comment. I'll also try to
follow up in the next days with an xorshift1024* implementation,
which should be similarly straightforward.
Code follows -- enjoy! :-)
struct Xoroshiro128plus
{
public:
enum bool isUniformRandom = true;
/// Range primitives
enum bool empty = false;
/// ditto
ulong front() @property @safe const nothrow pure
{
return s[0] + s[1];
}
/// ditto
void popFront() @safe nothrow pure
{
immutable ulong s1 = s[1] ^ s[0];
s[0] = rotateLeft(s[0], 55) ^ s1 ^ (s1 << 14);
s[1] = rotateLeft(s1, 36);
}
void seed(ulong s0, ulong s1) @safe nothrow pure
in
{
// seeds are not both 0
assert(!(!s0 && !s1));
}
body
{
s[0] = s0;
s[1] = s1;
}
void seed(ulong[2] s01) @safe nothrow pure
in
{
// seeds are not both 0
assert(!(!s01[0] && !s01[1]));
}
body
{
s[] = s01[];
}
private:
ulong[2] s;
static ulong rotateLeft(ulong x, int k) @safe nothrow pure
in
{
assert(k <= 64);
}
body
{
return (x << k) | (x >> (64 - k));
}
}
More information about the Digitalmars-d-announce
mailing list