Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
26 | pmbaty | 1 | /* ACC -- Automatic Compiler Configuration |
2 | |||
3 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer |
||
4 | All Rights Reserved. |
||
5 | |||
6 | This software is a copyrighted work licensed under the terms of |
||
7 | the GNU General Public License. Please consult the file "ACC_LICENSE" |
||
8 | for details. |
||
9 | |||
10 | Markus F.X.J. Oberhumer |
||
11 | <markus@oberhumer.com> |
||
12 | http://www.oberhumer.com/ |
||
13 | */ |
||
14 | |||
15 | |||
16 | #define __ACCLIB_RAND_CH_INCLUDED 1 |
||
17 | #if !defined(ACCLIB_PUBLIC) |
||
18 | # define ACCLIB_PUBLIC(r,f) r __ACCLIB_FUNCNAME(f) |
||
19 | #endif |
||
20 | |||
21 | |||
22 | /************************************************************************* |
||
23 | // some linear congruential pseudo random number generators (PRNG) |
||
24 | **************************************************************************/ |
||
25 | |||
26 | ACCLIB_PUBLIC(void, acc_srand31) (acc_rand31_p r, acc_uint32l_t seed) |
||
27 | { |
||
28 | r->seed = seed & ACC_UINT32L_C(0xffffffff); |
||
29 | } |
||
30 | |||
31 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand31) (acc_rand31_p r) |
||
32 | { |
||
33 | r->seed = r->seed * ACC_UINT32L_C(1103515245) + 12345; |
||
34 | r->seed &= ACC_UINT32L_C(0x7fffffff); |
||
35 | return r->seed; |
||
36 | } |
||
37 | |||
38 | |||
39 | #if defined(acc_uint64l_t) |
||
40 | |||
41 | ACCLIB_PUBLIC(void, acc_srand48) (acc_rand48_p r, acc_uint32l_t seed) |
||
42 | { |
||
43 | r->seed = seed & ACC_UINT32L_C(0xffffffff); |
||
44 | r->seed <<= 16; r->seed |= 0x330e; |
||
45 | } |
||
46 | |||
47 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand48) (acc_rand48_p r) |
||
48 | { |
||
49 | r->seed = r->seed * ACC_UINT64L_C(25214903917) + 11; |
||
50 | r->seed &= ACC_UINT64L_C(0xffffffffffff); |
||
51 | return (acc_uint32l_t) (r->seed >> 17); |
||
52 | } |
||
53 | |||
54 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand48_r32) (acc_rand48_p r) |
||
55 | { |
||
56 | r->seed = r->seed * ACC_UINT64L_C(25214903917) + 11; |
||
57 | r->seed &= ACC_UINT64L_C(0xffffffffffff); |
||
58 | return (acc_uint32l_t) (r->seed >> 16); |
||
59 | } |
||
60 | |||
61 | #endif /* acc_uint64l_t */ |
||
62 | |||
63 | |||
64 | #if defined(acc_uint64l_t) |
||
65 | |||
66 | ACCLIB_PUBLIC(void, acc_srand64) (acc_rand64_p r, acc_uint64l_t seed) |
||
67 | { |
||
68 | r->seed = seed & ACC_UINT64L_C(0xffffffffffffffff); |
||
69 | } |
||
70 | |||
71 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand64) (acc_rand64_p r) |
||
72 | { |
||
73 | r->seed = r->seed * ACC_UINT64L_C(6364136223846793005) + 1; |
||
74 | #if (SIZEOF_ACC_INT64L_T > 8) |
||
75 | r->seed &= ACC_UINT64L_C(0xffffffffffffffff); |
||
76 | #endif |
||
77 | return (acc_uint32l_t) (r->seed >> 33); |
||
78 | } |
||
79 | |||
80 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand64_r32) (acc_rand64_p r) |
||
81 | { |
||
82 | r->seed = r->seed * ACC_UINT64L_C(6364136223846793005) + 1; |
||
83 | #if (SIZEOF_ACC_INT64L_T > 8) |
||
84 | r->seed &= ACC_UINT64L_C(0xffffffffffffffff); |
||
85 | #endif |
||
86 | return (acc_uint32l_t) (r->seed >> 32); |
||
87 | } |
||
88 | |||
89 | #endif /* acc_uint64l_t */ |
||
90 | |||
91 | |||
92 | /************************************************************************* |
||
93 | // mersenne twister PRNG |
||
94 | **************************************************************************/ |
||
95 | |||
96 | ACCLIB_PUBLIC(void, acc_srandmt) (acc_randmt_p r, acc_uint32l_t seed) |
||
97 | { |
||
98 | unsigned i = 0; |
||
99 | do { |
||
100 | r->s[i++] = (seed &= ACC_UINT32L_C(0xffffffff)); |
||
101 | seed ^= seed >> 30; |
||
102 | seed = seed * ACC_UINT32L_C(0x6c078965) + i; |
||
103 | } while (i != 624); |
||
104 | r->n = i; |
||
105 | } |
||
106 | |||
107 | ACCLIB_PUBLIC(acc_uint32l_t, acc_randmt) (acc_randmt_p r) |
||
108 | { |
||
109 | return (__ACCLIB_FUNCNAME(acc_randmt_r32)(r)) >> 1; |
||
110 | } |
||
111 | |||
112 | ACCLIB_PUBLIC(acc_uint32l_t, acc_randmt_r32) (acc_randmt_p r) |
||
113 | { |
||
114 | acc_uint32l_t v; |
||
115 | if (r->n == 624) { |
||
116 | int i = 0, j; |
||
117 | r->n = 0; |
||
118 | do { |
||
119 | j = i - 623; if (j < 0) j += 624; |
||
120 | v = (r->s[i] & ACC_UINT32L_C(0x80000000)) ^ (r->s[j] & ACC_UINT32L_C(0x7fffffff)); |
||
121 | j = i - 227; if (j < 0) j += 624; |
||
122 | r->s[i] = r->s[j] ^ (v >> 1); |
||
123 | if (v & 1) r->s[i] ^= ACC_UINT32L_C(0x9908b0df); |
||
124 | } while (++i != 624); |
||
125 | } |
||
126 | v = r->s[r->n++]; |
||
127 | v ^= v >> 11; v ^= (v & ACC_UINT32L_C(0x013a58ad)) << 7; |
||
128 | v ^= (v & ACC_UINT32L_C(0x0001df8c)) << 15; v ^= v >> 18; |
||
129 | return v; |
||
130 | } |
||
131 | |||
132 | |||
133 | /* |
||
134 | vi:ts=4:et |
||
135 | */ |