blob: 914a6072cd2b8ff3d8f0618f69f4f65a89063040 (
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
82
83
84
85
86
87
88
|
#ifndef _ASURA_RANDOM_H_
#define _ASURA_RANDOM_H_
#include "../Type.h"
#include "../Classes.h"
namespace_begin(AsuraEngine)
//namespace_begin(Math)
/*
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;
};
//namespace_end
namespace_end
#endif
|