blob: 1971ab44a19f83a0a1773081bdd64470922fe5b5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#ifndef RAND_H
#define RAND_H
/*
Some random generator timings:
MacBook Pro w/ Core 2 Duo 2.4GHz. Times are for gcc 4.0.1 (OS X 10.6.2) / VS2008 SP1 (Win XP SP3),
in milliseconds for this loop (4915200 calls):
for (int j = 0; j < 100; ++j)
for (int i = 0; i < 128*128*3; ++i)
data[i] = (rnd.get() & 0x3) << 6;
gcc vs2008 Size
C's rand(): 57.0 109.3 ms 1
Mersenne Twister: 56.0 37.4 ms 2500
Unity 2.x LCG: 11.1 9.2 ms 4
Xorshift 128: 15.0 17.8 ms 16
Xorshift 32: 20.6 10.7 ms 4
WELL 512: 43.6 55.1 ms 68
*/
// Xorshift 128 implementation
// Xorshift paper: http://www.jstatsoft.org/v08/i14/paper
// Wikipedia: http://en.wikipedia.org/wiki/Xorshift
class Rand {
public:
Rand (UInt32 seed = 0)
{
SetSeed (seed);
}
UInt32 Get ()
{
UInt32 t;
t = x ^ (x << 11);
x = y; y = z; z = w;
return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}
inline static float GetFloatFromInt (UInt32 value)
{
// take 23 bits of integer, and divide by 2^23-1
return float(value & 0x007FFFFF) * (1.0f / 8388607.0f);
}
inline static UInt8 GetByteFromInt (UInt32 value)
{
// take the most significant byte from the 23-bit value
return UInt8(value >> (23 - 8));
}
// random number between 0.0 and 1.0
float GetFloat ()
{
return GetFloatFromInt (Get ());
}
// random number between -1.0 and 1.0
float GetSignedFloat ()
{
return GetFloat() * 2.0f - 1.0f;
}
void SetSeed (UInt32 seed)
{
x = seed;
y = x * 1812433253U + 1;
z = y * 1812433253U + 1;
w = z * 1812433253U + 1;
}
UInt32 GetSeed () const { return x; }
private:
UInt32 x, y, z, w;
};
#endif
|