Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
rand.cpp
Go to the documentation of this file.
1
29#include <time.h> // for clock()
30
31// expand _TEST_EXPORT macros
32#define _RWSTD_TEST_SRC
33#include <rw_rand.h>
34
35
36enum { TABLE_SIZE = 55 };
37
38static _RWSTD_UINT32_T table32 [TABLE_SIZE];
39static _RWSTD_SIZE_T inx32 [2];
40
41
42// seeds the 32-bit random number generator
43_TEST_EXPORT void
44rw_seed32 (_RWSTD_UINT32_T seed)
45{
46 if (0xffffffffUL == seed)
47 seed = unsigned (clock ());
48
49 table32 [TABLE_SIZE - 1] = seed;
50
51 _RWSTD_UINT32_T k = 1;
52
53 for (_RWSTD_SIZE_T i = 0; i != TABLE_SIZE - 1U; ++i) {
54
55 const _RWSTD_SIZE_T ii = 21U * i % TABLE_SIZE;
56 table32 [ii] = k;
57 k = seed - k;
58 seed = table32 [ii];
59 }
60
61 for (_RWSTD_SIZE_T i = 0; i != 4U; ++i) {
62 for (_RWSTD_SIZE_T ii = 0; ii != TABLE_SIZE; ++ii)
63 table32 [i] = table32 [i] - table32 [(i + 31U) % TABLE_SIZE];
64 }
65
66 inx32 [0] = 0U;
67 inx32 [1] = TABLE_SIZE * 2U / 3U - 1U;
68}
69
70
71// returns a 32-bit random number in the range [0, limit)
72// if limit is non-zero, otherwise in the range [0, UINT32_MAX)
73_TEST_EXPORT _RWSTD_UINT32_T
74rw_rand32 (_RWSTD_UINT32_T limit /* = 0 */)
75{
76 if (0 == inx32 [0] && 0 == inx32 [1])
77 rw_seed32 (161803398);
78
79 table32 [++inx32 [0] %= TABLE_SIZE] -=
80 table32 [++inx32 [1] %= TABLE_SIZE];
81
82 return limit ? table32 [inx32 [0]] % limit : table32 [inx32 [0]];
83}
84
85
86#ifdef _RWSTD_UINT64_T
87
88static _RWSTD_UINT64_T table64 [TABLE_SIZE];
89static _RWSTD_SIZE_T inx64 [2];
90
91
92// seeds the 64-bit random number generator
93_TEST_EXPORT void
94rw_seed64 (_RWSTD_UINT64_T seed)
95{
96 if ((_RWSTD_UINT64_T)-1 == seed)
97 seed = clock ();
98
99 table64 [TABLE_SIZE - 1] = seed;
100
101 _RWSTD_UINT64_T k = 1;
102
103 for (_RWSTD_SIZE_T i = 0; i != TABLE_SIZE - 1U; ++i) {
104
105 const _RWSTD_SIZE_T ii = 21U * i % TABLE_SIZE;
106 table64 [ii] = k;
107 k = seed - k;
108 seed = table64 [ii];
109 }
110
111 for (_RWSTD_SIZE_T i = 0; i != 4U; ++i) {
112 for (_RWSTD_SIZE_T ii = 0; ii != TABLE_SIZE; ++ii)
113 table64 [i] = table64 [i] - table64 [(i + 31U) % TABLE_SIZE];
114 }
115
116 inx64 [0] = 0U;
117 inx64 [1] = TABLE_SIZE * 2U / 3U - 1U;
118}
119
120
121// returns a 64-bit random number in the range [0, limit)
122// if limit is non-zero, otherwise in the range [0, UINT64_MAX)
123_TEST_EXPORT _RWSTD_UINT64_T
124rw_rand64 (_RWSTD_UINT64_T limit)
125{
126 if (0 == inx64 [0] && 0 == inx64 [1])
127 rw_seed64 (161803398);
128
129 table64 [++inx64 [0] %= TABLE_SIZE] -=
130 table64 [++inx64 [1] %= TABLE_SIZE];
131
132 return limit ? table64 [inx64 [0]] % limit : table64 [inx64 [0]];
133}
134
135#endif // _RWSTD_UINT64_T
#define i
Definition 17.names.cpp:126
#define k
Definition 17.names.cpp:128
#define U
Definition 17.names.cpp:164
_TEST_EXPORT void rw_seed32(_RWSTD_UINT32_T seed)
Definition rand.cpp:44
_TEST_EXPORT _RWSTD_UINT32_T rw_rand32(_RWSTD_UINT32_T limit)
Definition rand.cpp:74
@ TABLE_SIZE
Definition rand.cpp:36
#define _TEST_EXPORT
Definition rw_testdefs.h:55