Thread overview
xoroshiro128+ random number generator
Apr 30, 2016
Nordlöw
April 29, 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));
    }
}

April 30, 2016
On Friday, 29 April 2016 at 21:40:49 UTC, Joseph Rushton Wakeling wrote:
> Spotted this reddit post the other day:
> https://www.reddit.com/r/programming/comments/4gtlfz/xoroshiro128_the_fastest_fullperiod_pseudorandom/

@nogc :)
April 30, 2016
On Saturday, 30 April 2016 at 08:54:39 UTC, Nordlöw wrote:
> On Friday, 29 April 2016 at 21:40:49 UTC, Joseph Rushton Wakeling wrote:
>> Spotted this reddit post the other day:
>> https://www.reddit.com/r/programming/comments/4gtlfz/xoroshiro128_the_fastest_fullperiod_pseudorandom/
>
> @nogc :)

Hah, nicely spotted :-)
April 30, 2016
On Saturday, 30 April 2016 at 11:04:14 UTC, Joseph Rushton Wakeling wrote:
> On Saturday, 30 April 2016 at 08:54:39 UTC, Nordlöw wrote:
>> On Friday, 29 April 2016 at 21:40:49 UTC, Joseph Rushton Wakeling wrote:
>>> Spotted this reddit post the other day:
>>> https://www.reddit.com/r/programming/comments/4gtlfz/xoroshiro128_the_fastest_fullperiod_pseudorandom/
>>
>> @nogc :)
>
> Hah, nicely spotted :-)

More importantly, the public fields of this generator should include:

    enum ulong min = ulong.min;

    enum ulong max = ulong.max;

... otherwise it won't work with `uniform` or anything that depends on it.