43 lines
1.2 KiB
C#
43 lines
1.2 KiB
C#
using System;
|
|
|
|
namespace XWorld.Framework
|
|
{
|
|
// SplitMix64:跨平台确定性、无浮点、状态即种子(便于快照/复盘)
|
|
public sealed class DeterministicRandom : IRandom
|
|
{
|
|
private ulong _state;
|
|
|
|
public DeterministicRandom(ulong seed)
|
|
{
|
|
_state = seed;
|
|
}
|
|
|
|
// 当前内部状态;用它构造新实例可从"下一步"继续同一序列
|
|
public ulong State => _state;
|
|
|
|
private ulong NextU64()
|
|
{
|
|
_state += 0x9E3779B97F4A7C15UL;
|
|
ulong z = _state;
|
|
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9UL;
|
|
z = (z ^ (z >> 27)) * 0x94D049BB133111EBUL;
|
|
return z ^ (z >> 31);
|
|
}
|
|
|
|
public int Next(int maxExclusive)
|
|
{
|
|
if (maxExclusive <= 0)
|
|
throw new ArgumentOutOfRangeException(nameof(maxExclusive), "maxExclusive 必须为正");
|
|
|
|
ulong bound = (ulong)maxExclusive;
|
|
// 拒绝采样,消除取模偏差
|
|
ulong threshold = (ulong.MaxValue - bound + 1) % bound;
|
|
while (true)
|
|
{
|
|
ulong r = NextU64();
|
|
if (r >= threshold) return (int)(r % bound);
|
|
}
|
|
}
|
|
}
|
|
}
|