diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2008-06-30 05:15:05 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2008-06-30 05:15:05 +0000 |
commit | 9e896b470f5a4550a7fbbdc515db08b0249f5950 (patch) | |
tree | 8f2ea4d701f554a578a7d7e441f98e1f77425e9a /xdelta3/testing/random.h | |
parent | e127914b71638072798f7c02e93caf9377ba7385 (diff) |
A test is taking shape...
Diffstat (limited to 'xdelta3/testing/random.h')
-rw-r--r-- | xdelta3/testing/random.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/xdelta3/testing/random.h b/xdelta3/testing/random.h new file mode 100644 index 0000000..6648edb --- /dev/null +++ b/xdelta3/testing/random.h | |||
@@ -0,0 +1,125 @@ | |||
1 | /* -*- Mode: C++ -*- */ | ||
2 | /* This is public-domain Mersenne Twister code, | ||
3 | * attributed to Michael Brundage. Thanks! | ||
4 | * http://www.qbrundage.com/michaelb/pubs/essays/random_number_generation.html | ||
5 | */ | ||
6 | #include <math.h> | ||
7 | |||
8 | namespace regtest { | ||
9 | |||
10 | class MTRandom { | ||
11 | public: | ||
12 | static const uint32_t TEST_SEED1 = 0x1975; | ||
13 | |||
14 | static const int MT_LEN = 624; | ||
15 | static const int MT_IA = 397; | ||
16 | static const int MT_IB = (MT_LEN - MT_IA); | ||
17 | static const uint32_t UPPER_MASK = 0x80000000; | ||
18 | static const uint32_t LOWER_MASK = 0x7FFFFFFF; | ||
19 | static const uint32_t MATRIX_A = 0x9908B0DF; | ||
20 | |||
21 | MTRandom() { | ||
22 | Init(TEST_SEED1); | ||
23 | } | ||
24 | |||
25 | MTRandom(uint32_t seed) { | ||
26 | Init(seed); | ||
27 | } | ||
28 | |||
29 | uint32_t TWIST(int i, int j) { | ||
30 | return (mt_buffer_[i] & UPPER_MASK) | (mt_buffer_[j] & LOWER_MASK); | ||
31 | } | ||
32 | |||
33 | uint32_t MAGIC(uint32_t s) { | ||
34 | return (s & 1) * MATRIX_A; | ||
35 | } | ||
36 | |||
37 | uint32_t Rand32 () { | ||
38 | int idx = mt_index_; | ||
39 | uint32_t s; | ||
40 | int i; | ||
41 | |||
42 | if (idx == MT_LEN * sizeof(uint32_t)) { | ||
43 | idx = 0; | ||
44 | i = 0; | ||
45 | for (; i < MT_IB; i++) { | ||
46 | s = TWIST(i, i+1); | ||
47 | mt_buffer_[i] = mt_buffer_[i + MT_IA] ^ (s >> 1) ^ MAGIC(s); | ||
48 | } | ||
49 | for (; i < MT_LEN-1; i++) { | ||
50 | s = TWIST(i, i+1); | ||
51 | mt_buffer_[i] = mt_buffer_[i - MT_IB] ^ (s >> 1) ^ MAGIC(s); | ||
52 | } | ||
53 | |||
54 | s = TWIST(MT_LEN-1, 0); | ||
55 | mt_buffer_[MT_LEN-1] = mt_buffer_[MT_IA-1] ^ (s >> 1) ^ MAGIC(s); | ||
56 | } | ||
57 | mt_index_ = idx + sizeof(uint32_t); | ||
58 | |||
59 | // Original code had an unaligned access, make it portable. | ||
60 | // return *(uint32_t *)((unsigned char *)b + idx); | ||
61 | uint32_t r; | ||
62 | memcpy(&r, ((unsigned char *)mt_buffer_ + idx), sizeof(uint32_t)); | ||
63 | return r; | ||
64 | } | ||
65 | |||
66 | uint32_t ExpRand32(uint32_t mean) { | ||
67 | double mean_d = mean; | ||
68 | double erand = log (1.0 / (Rand32() / (double)UINT32_MAX)); | ||
69 | uint32_t x = (uint32_t) (mean_d * erand + 0.5); | ||
70 | return x; | ||
71 | } | ||
72 | |||
73 | uint64_t Rand64() { | ||
74 | return ((uint64_t)Rand32() << 32) | Rand32(); | ||
75 | } | ||
76 | |||
77 | uint64_t ExpRand64(uint64_t mean) { | ||
78 | double mean_d = mean; | ||
79 | double erand = log (1.0 / (Rand64() / (double)UINT32_MAX)); | ||
80 | uint64_t x = (uint64_t) (mean_d * erand + 0.5); | ||
81 | return x; | ||
82 | } | ||
83 | |||
84 | template <typename T> | ||
85 | T Rand() { | ||
86 | switch (sizeof(T)) { | ||
87 | case sizeof(uint32_t): | ||
88 | return Rand32(); | ||
89 | case sizeof(uint64_t): | ||
90 | return Rand64(); | ||
91 | default: | ||
92 | cerr << "Invalid sizeof T" << endl; | ||
93 | abort(); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | template <typename T> | ||
98 | T ExpRand(T mean) { | ||
99 | switch (sizeof(T)) { | ||
100 | case sizeof(uint32_t): | ||
101 | return ExpRand32(mean); | ||
102 | case sizeof(uint64_t): | ||
103 | return ExpRand64(mean); | ||
104 | default: | ||
105 | cerr << "Invalid sizeof T" << endl; | ||
106 | abort(); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | private: | ||
111 | void Init(uint32_t seed) { | ||
112 | int i; | ||
113 | srand (seed); | ||
114 | for (i = 0; i < MT_LEN; i++) | ||
115 | { | ||
116 | mt_buffer_[i] = rand (); | ||
117 | } | ||
118 | mt_index_ = 0; | ||
119 | } | ||
120 | |||
121 | int mt_index_; | ||
122 | uint32_t mt_buffer_[MT_LEN]; | ||
123 | }; | ||
124 | |||
125 | } // namespace regtest | ||