はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【C#】64ビットの擬似乱数生成器"Splitmix64"を実装してみる

はじめに

今回はSplitmix64という擬似乱数生成器をC#で実装してみようという記事になります。

概要

Splitmix6464ビットの高速な疑似乱数生成器です。C#で64ビットの型はlongulongとかですね。

64ビットの状態のみを使用した非常に高速な疑似乱数生成器。
64ビットの状態のみを使用する必要がない限り、XorOshiro128StarStarまたはXorOshiro128Plusを使用することをお勧めします。

Pony - SplitMix64 [ソース]64ビットの状態のみを使用した非常に高速な疑似乱数生成器、詳細 http://xoshiro.di.unimi.it/および http://gee.cs.oswego.edu/dl/papers/oopsla14.pdf

実装

Cでの実装は以下の通り。

uint64_t next() {
	uint64_t z = (x += 0x9e3779b97f4a7c15);
	z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
	z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
	return z ^ (z >> 31);
}

https://xoshiro.di.unimi.it/splitmix64.c

上記のコードでいうxが更新されることによって、毎回出力が異なるようになります。

このコードを参考にしながらC#で実装したコードは以下の通り。

public class Splitmix64
{
    private ulong _seed;

    public Splitmix64(ulong seed)
    {
        _seed = seed;
    }

    public ulong Next()
    {
        var z = _seed += 0x9e3779b97f4a7c15;
        z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
        z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
        return z ^ (z >> 31);
    }
}


利用する方法は以下の通り。

var random = new Splitmix64(0);
            
// 16294208416658607535
Console.WriteLine(random.Next());
            
// 7960286522194355700
Console.WriteLine(random.Next());
            
// 487617019471545679
Console.WriteLine(random.Next());