well1024a 유사 난수 발생기 C# 소스코드
원본 C코드를 가능한 그대로 유지하였고, C코드와 동일 난수가 발생되었음을 확인 하였습니다. Unity3d에서 사용하기 위해 작성 하였습니다. 다수의 난수발생기를 사용할 수 있도록 하기 위해 클래스를 static 속성을 주지 않았으며 이 객체를 생성하여 사용하셔야 합니다.
아래의 저작권 표시와 달리 이 소스코드는 자유롭게 사용할 수 있습니다. 다만, 원본의 출처를 밝혀 주시기 바랍니다.
/* ************************************************************** */
/* WELL1024a C# code */
/* This source code re-written from Makoto Matsumoto's WELL1023a.c*/
/* at http://www.iro.umontreal.ca/~panneton/WELLRNG.html */
/* Original C Code Author: Makoto Matsumoto */
/* C# Code Author: Booil Ted Joung */
/* ************************************************************** */
namespace PseudoRandom
{
public partial class WELLRNG1024a
{
private const uint W = 32;
private const uint R = 32;
private const uint M1 = 3;
private const uint M2 = 24;
private const uint M3 = 10;
private static uint MAT0POS(int t, uint v) { return (v^(v>>t)); }
private static uint MAT0NEG(int t, uint v) { return (v^(v<<(-(t)))); }
private static uint Identity(uint v) { return (v); }
private uint V0 { get { return STATE[state_i ]; } }
private uint VM1 { get { return STATE[(state_i+M1) & 0x0000001fU]; } }
private uint VM2 { get { return STATE[(state_i+M2) & 0x0000001fU]; } }
private uint VM3 { get { return STATE[(state_i+M3) & 0x0000001fU]; } }
private uint VRm1 { get { return STATE[(state_i+31) & 0x0000001fU]; } }
private uint newV0 {
get { return STATE[(state_i+31) & 0x0000001fU]; }
set { STATE[(state_i+31) & 0x0000001fU] = value; }
}
private uint newV1 {
get { return STATE[state_i]; }
set { STATE[state_i] = value; }
}
private const double FACT = 2.32830643653869628906e-10;
private uint state_i = 0;
private uint[] STATE = new uint[R];
private uint z0, z1, z2;
public WELLRNG1024a(uint[] init)
{
this.Seed(init);
}
public void Seed(uint[] seed)
{
int j;
state_i = 0;
for (j = 0; j < R; j++)
STATE[j] = seed[j];
}
// 0.0 <= r && r < 1
public double Generate()
{
z0 = VRm1;
z1 = Identity(V0) ^ MAT0POS (8, VM1);
z2 = MAT0NEG (-19, VM2) ^ MAT0NEG(-14,VM3);
newV1 = z1 ^ z2;
newV0 = MAT0NEG (-11,z0) ^ MAT0NEG(-7,z1) ^ MAT0NEG(-13,z2) ;
state_i = (state_i + 31) & 0x0000001fU;
return ((double) STATE[state_i] * FACT);
}
}
} // namespace PseudoRandom