xref: /aosp_15_r20/external/bc/include/rand.h (revision 5a6e848804d15c18a0125914844ee4eb0bda4fcf)
1*5a6e8488SAndroid Build Coastguard Worker /*
2*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
3*5a6e8488SAndroid Build Coastguard Worker  *
4*5a6e8488SAndroid Build Coastguard Worker  * Parts of this code are adapted from the following:
5*5a6e8488SAndroid Build Coastguard Worker  *
6*5a6e8488SAndroid Build Coastguard Worker  * PCG, A Family of Better Random Number Generators.
7*5a6e8488SAndroid Build Coastguard Worker  *
8*5a6e8488SAndroid Build Coastguard Worker  * You can find the original source code at:
9*5a6e8488SAndroid Build Coastguard Worker  *   https://github.com/imneme/pcg-c
10*5a6e8488SAndroid Build Coastguard Worker  *
11*5a6e8488SAndroid Build Coastguard Worker  * -----------------------------------------------------------------------------
12*5a6e8488SAndroid Build Coastguard Worker  *
13*5a6e8488SAndroid Build Coastguard Worker  * This code is under the following license:
14*5a6e8488SAndroid Build Coastguard Worker  *
15*5a6e8488SAndroid Build Coastguard Worker  * Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
16*5a6e8488SAndroid Build Coastguard Worker  * Copyright (c) 2018-2024 Gavin D. Howard and contributors.
17*5a6e8488SAndroid Build Coastguard Worker  *
18*5a6e8488SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
19*5a6e8488SAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to deal
20*5a6e8488SAndroid Build Coastguard Worker  * in the Software without restriction, including without limitation the rights
21*5a6e8488SAndroid Build Coastguard Worker  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22*5a6e8488SAndroid Build Coastguard Worker  * copies of the Software, and to permit persons to whom the Software is
23*5a6e8488SAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
24*5a6e8488SAndroid Build Coastguard Worker  *
25*5a6e8488SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
26*5a6e8488SAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
27*5a6e8488SAndroid Build Coastguard Worker  *
28*5a6e8488SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29*5a6e8488SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30*5a6e8488SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31*5a6e8488SAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32*5a6e8488SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33*5a6e8488SAndroid Build Coastguard Worker  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34*5a6e8488SAndroid Build Coastguard Worker  * SOFTWARE.
35*5a6e8488SAndroid Build Coastguard Worker  *
36*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
37*5a6e8488SAndroid Build Coastguard Worker  *
38*5a6e8488SAndroid Build Coastguard Worker  * Definitions for the RNG.
39*5a6e8488SAndroid Build Coastguard Worker  *
40*5a6e8488SAndroid Build Coastguard Worker  */
41*5a6e8488SAndroid Build Coastguard Worker 
42*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_RAND_H
43*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_H
44*5a6e8488SAndroid Build Coastguard Worker 
45*5a6e8488SAndroid Build Coastguard Worker #include <stdint.h>
46*5a6e8488SAndroid Build Coastguard Worker #include <inttypes.h>
47*5a6e8488SAndroid Build Coastguard Worker 
48*5a6e8488SAndroid Build Coastguard Worker #include <vector.h>
49*5a6e8488SAndroid Build Coastguard Worker #include <num.h>
50*5a6e8488SAndroid Build Coastguard Worker 
51*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
52*5a6e8488SAndroid Build Coastguard Worker 
53*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_LIBRARY
54*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_USE_FREE (1)
55*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_LIBRARY
56*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG
57*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_USE_FREE (1)
58*5a6e8488SAndroid Build Coastguard Worker #else // BC_DEBUG
59*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_USE_FREE (0)
60*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG
61*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_LIBRARY
62*5a6e8488SAndroid Build Coastguard Worker 
63*5a6e8488SAndroid Build Coastguard Worker /**
64*5a6e8488SAndroid Build Coastguard Worker  * A function to return a random unsigned long.
65*5a6e8488SAndroid Build Coastguard Worker  * @param ptr  A void ptr to some data that will help generate the random ulong.
66*5a6e8488SAndroid Build Coastguard Worker  * @return     The random ulong.
67*5a6e8488SAndroid Build Coastguard Worker  */
68*5a6e8488SAndroid Build Coastguard Worker typedef ulong (*BcRandUlong)(void* ptr);
69*5a6e8488SAndroid Build Coastguard Worker 
70*5a6e8488SAndroid Build Coastguard Worker #if BC_LONG_BIT >= 64
71*5a6e8488SAndroid Build Coastguard Worker 
72*5a6e8488SAndroid Build Coastguard Worker // If longs are 64 bits, we have the option of 128-bit integers on some
73*5a6e8488SAndroid Build Coastguard Worker // compilers. These two sections test that.
74*5a6e8488SAndroid Build Coastguard Worker #ifdef BC_RAND_BUILTIN
75*5a6e8488SAndroid Build Coastguard Worker #if BC_RAND_BUILTIN
76*5a6e8488SAndroid Build Coastguard Worker #ifndef __SIZEOF_INT128__
77*5a6e8488SAndroid Build Coastguard Worker #undef BC_RAND_BUILTIN
78*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_BUILTIN (0)
79*5a6e8488SAndroid Build Coastguard Worker #endif // __SIZEOF_INT128__
80*5a6e8488SAndroid Build Coastguard Worker #endif // BC_RAND_BUILTIN
81*5a6e8488SAndroid Build Coastguard Worker #endif // BC_RAND_BUILTIN
82*5a6e8488SAndroid Build Coastguard Worker 
83*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_RAND_BUILTIN
84*5a6e8488SAndroid Build Coastguard Worker #ifdef __SIZEOF_INT128__
85*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_BUILTIN (1)
86*5a6e8488SAndroid Build Coastguard Worker #else // __SIZEOF_INT128__
87*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_BUILTIN (0)
88*5a6e8488SAndroid Build Coastguard Worker #endif // __SIZEOF_INT128__
89*5a6e8488SAndroid Build Coastguard Worker #endif // BC_RAND_BUILTIN
90*5a6e8488SAndroid Build Coastguard Worker 
91*5a6e8488SAndroid Build Coastguard Worker /// The type for random integers.
92*5a6e8488SAndroid Build Coastguard Worker typedef uint64_t BcRand;
93*5a6e8488SAndroid Build Coastguard Worker 
94*5a6e8488SAndroid Build Coastguard Worker /// A constant defined by PCG.
95*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ROTC (63)
96*5a6e8488SAndroid Build Coastguard Worker 
97*5a6e8488SAndroid Build Coastguard Worker #if BC_RAND_BUILTIN
98*5a6e8488SAndroid Build Coastguard Worker 
99*5a6e8488SAndroid Build Coastguard Worker /// A typedef for the PCG state.
100*5a6e8488SAndroid Build Coastguard Worker typedef __uint128_t BcRandState;
101*5a6e8488SAndroid Build Coastguard Worker 
102*5a6e8488SAndroid Build Coastguard Worker /**
103*5a6e8488SAndroid Build Coastguard Worker  * Multiply two integers, worrying about overflow.
104*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first integer.
105*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second integer.
106*5a6e8488SAndroid Build Coastguard Worker  * @return   The product of the PCG states.
107*5a6e8488SAndroid Build Coastguard Worker  */
108*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_mul(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
109*5a6e8488SAndroid Build Coastguard Worker 
110*5a6e8488SAndroid Build Coastguard Worker /**
111*5a6e8488SAndroid Build Coastguard Worker  * Add two integers, worrying about overflow.
112*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first integer.
113*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second integer.
114*5a6e8488SAndroid Build Coastguard Worker  * @return   The sum of the PCG states.
115*5a6e8488SAndroid Build Coastguard Worker  */
116*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_add(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
117*5a6e8488SAndroid Build Coastguard Worker 
118*5a6e8488SAndroid Build Coastguard Worker /**
119*5a6e8488SAndroid Build Coastguard Worker  * Multiply two PCG states.
120*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first PCG state.
121*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second PCG state.
122*5a6e8488SAndroid Build Coastguard Worker  * @return   The product of the PCG states.
123*5a6e8488SAndroid Build Coastguard Worker  */
124*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_mul2(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
125*5a6e8488SAndroid Build Coastguard Worker 
126*5a6e8488SAndroid Build Coastguard Worker /**
127*5a6e8488SAndroid Build Coastguard Worker  * Add two PCG states.
128*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first PCG state.
129*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second PCG state.
130*5a6e8488SAndroid Build Coastguard Worker  * @return   The sum of the PCG states.
131*5a6e8488SAndroid Build Coastguard Worker  */
132*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_add2(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
133*5a6e8488SAndroid Build Coastguard Worker 
134*5a6e8488SAndroid Build Coastguard Worker /**
135*5a6e8488SAndroid Build Coastguard Worker  * Figure out if the PRNG has been modified. Since the increment of the PRNG has
136*5a6e8488SAndroid Build Coastguard Worker  * to be odd, we use the extra bit to store whether it has been modified or not.
137*5a6e8488SAndroid Build Coastguard Worker  * @param r  The PRNG.
138*5a6e8488SAndroid Build Coastguard Worker  * @return   True if the PRNG has *not* been modified, false otherwise.
139*5a6e8488SAndroid Build Coastguard Worker  */
140*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_NOTMODIFIED(r) (((r)->inc & 1UL) == 0)
141*5a6e8488SAndroid Build Coastguard Worker 
142*5a6e8488SAndroid Build Coastguard Worker /**
143*5a6e8488SAndroid Build Coastguard Worker  * Return true if the PRNG has not been seeded yet.
144*5a6e8488SAndroid Build Coastguard Worker  * @param r  The PRNG.
145*5a6e8488SAndroid Build Coastguard Worker  * @return   True if the PRNG has not been seeded yet, false otherwise.
146*5a6e8488SAndroid Build Coastguard Worker  */
147*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ZERO(r) (!(r)->state)
148*5a6e8488SAndroid Build Coastguard Worker 
149*5a6e8488SAndroid Build Coastguard Worker /**
150*5a6e8488SAndroid Build Coastguard Worker  * Returns a constant built from @a h and @a l.
151*5a6e8488SAndroid Build Coastguard Worker  * @param h  The high 64 bits.
152*5a6e8488SAndroid Build Coastguard Worker  * @param l  The low 64 bits.
153*5a6e8488SAndroid Build Coastguard Worker  * @return   The constant built from @a h and @a l.
154*5a6e8488SAndroid Build Coastguard Worker  */
155*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_CONSTANT(h, l) ((((BcRandState) (h)) << 64) + (BcRandState) (l))
156*5a6e8488SAndroid Build Coastguard Worker 
157*5a6e8488SAndroid Build Coastguard Worker /**
158*5a6e8488SAndroid Build Coastguard Worker  * Truncates a PCG state to the number of bits in a random integer.
159*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to truncate.
160*5a6e8488SAndroid Build Coastguard Worker  * @return   The truncated state.
161*5a6e8488SAndroid Build Coastguard Worker  */
162*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_TRUNC(s) ((uint64_t) (s))
163*5a6e8488SAndroid Build Coastguard Worker 
164*5a6e8488SAndroid Build Coastguard Worker /**
165*5a6e8488SAndroid Build Coastguard Worker  * Chops a PCG state in half and returns the top bits.
166*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to chop.
167*5a6e8488SAndroid Build Coastguard Worker  * @return   The chopped state's top bits.
168*5a6e8488SAndroid Build Coastguard Worker  */
169*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_CHOP(s) ((uint64_t) ((s) >> 64UL))
170*5a6e8488SAndroid Build Coastguard Worker 
171*5a6e8488SAndroid Build Coastguard Worker /**
172*5a6e8488SAndroid Build Coastguard Worker  * Rotates a PCG state.
173*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to rotate.
174*5a6e8488SAndroid Build Coastguard Worker  * @return   The rotated state.
175*5a6e8488SAndroid Build Coastguard Worker  */
176*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ROTAMT(s) ((unsigned int) ((s) >> 122UL))
177*5a6e8488SAndroid Build Coastguard Worker 
178*5a6e8488SAndroid Build Coastguard Worker #else // BC_RAND_BUILTIN
179*5a6e8488SAndroid Build Coastguard Worker 
180*5a6e8488SAndroid Build Coastguard Worker /// A typedef for the PCG state.
181*5a6e8488SAndroid Build Coastguard Worker typedef struct BcRandState
182*5a6e8488SAndroid Build Coastguard Worker {
183*5a6e8488SAndroid Build Coastguard Worker 	/// The low bits.
184*5a6e8488SAndroid Build Coastguard Worker 	uint_fast64_t lo;
185*5a6e8488SAndroid Build Coastguard Worker 
186*5a6e8488SAndroid Build Coastguard Worker 	/// The high bits.
187*5a6e8488SAndroid Build Coastguard Worker 	uint_fast64_t hi;
188*5a6e8488SAndroid Build Coastguard Worker 
189*5a6e8488SAndroid Build Coastguard Worker } BcRandState;
190*5a6e8488SAndroid Build Coastguard Worker 
191*5a6e8488SAndroid Build Coastguard Worker /**
192*5a6e8488SAndroid Build Coastguard Worker  * Multiply two integers, worrying about overflow.
193*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first integer.
194*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second integer.
195*5a6e8488SAndroid Build Coastguard Worker  * @return   The product of the PCG states.
196*5a6e8488SAndroid Build Coastguard Worker  */
197*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_mul(a, b) (bc_rand_multiply((a), (b)))
198*5a6e8488SAndroid Build Coastguard Worker 
199*5a6e8488SAndroid Build Coastguard Worker /**
200*5a6e8488SAndroid Build Coastguard Worker  * Add two integers, worrying about overflow.
201*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first integer.
202*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second integer.
203*5a6e8488SAndroid Build Coastguard Worker  * @return   The sum of the PCG states.
204*5a6e8488SAndroid Build Coastguard Worker  */
205*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_add(a, b) (bc_rand_addition((a), (b)))
206*5a6e8488SAndroid Build Coastguard Worker 
207*5a6e8488SAndroid Build Coastguard Worker /**
208*5a6e8488SAndroid Build Coastguard Worker  * Multiply two PCG states.
209*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first PCG state.
210*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second PCG state.
211*5a6e8488SAndroid Build Coastguard Worker  * @return   The product of the PCG states.
212*5a6e8488SAndroid Build Coastguard Worker  */
213*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_mul2(a, b) (bc_rand_multiply2((a), (b)))
214*5a6e8488SAndroid Build Coastguard Worker 
215*5a6e8488SAndroid Build Coastguard Worker /**
216*5a6e8488SAndroid Build Coastguard Worker  * Add two PCG states.
217*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first PCG state.
218*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second PCG state.
219*5a6e8488SAndroid Build Coastguard Worker  * @return   The sum of the PCG states.
220*5a6e8488SAndroid Build Coastguard Worker  */
221*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_add2(a, b) (bc_rand_addition2((a), (b)))
222*5a6e8488SAndroid Build Coastguard Worker 
223*5a6e8488SAndroid Build Coastguard Worker /**
224*5a6e8488SAndroid Build Coastguard Worker  * Figure out if the PRNG has been modified. Since the increment of the PRNG has
225*5a6e8488SAndroid Build Coastguard Worker  * to be odd, we use the extra bit to store whether it has been modified or not.
226*5a6e8488SAndroid Build Coastguard Worker  * @param r  The PRNG.
227*5a6e8488SAndroid Build Coastguard Worker  * @return   True if the PRNG has *not* been modified, false otherwise.
228*5a6e8488SAndroid Build Coastguard Worker  */
229*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_NOTMODIFIED(r) (((r)->inc.lo & 1) == 0)
230*5a6e8488SAndroid Build Coastguard Worker 
231*5a6e8488SAndroid Build Coastguard Worker /**
232*5a6e8488SAndroid Build Coastguard Worker  * Return true if the PRNG has not been seeded yet.
233*5a6e8488SAndroid Build Coastguard Worker  * @param r  The PRNG.
234*5a6e8488SAndroid Build Coastguard Worker  * @return   True if the PRNG has not been seeded yet, false otherwise.
235*5a6e8488SAndroid Build Coastguard Worker  */
236*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ZERO(r) (!(r)->state.lo && !(r)->state.hi)
237*5a6e8488SAndroid Build Coastguard Worker 
238*5a6e8488SAndroid Build Coastguard Worker /**
239*5a6e8488SAndroid Build Coastguard Worker  * Returns a constant built from @a h and @a l.
240*5a6e8488SAndroid Build Coastguard Worker  * @param h  The high 64 bits.
241*5a6e8488SAndroid Build Coastguard Worker  * @param l  The low 64 bits.
242*5a6e8488SAndroid Build Coastguard Worker  * @return   The constant built from @a h and @a l.
243*5a6e8488SAndroid Build Coastguard Worker  */
244*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_CONSTANT(h, l) { .lo = (l), .hi = (h) }
245*5a6e8488SAndroid Build Coastguard Worker 
246*5a6e8488SAndroid Build Coastguard Worker /**
247*5a6e8488SAndroid Build Coastguard Worker  * Truncates a PCG state to the number of bits in a random integer.
248*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to truncate.
249*5a6e8488SAndroid Build Coastguard Worker  * @return   The truncated state.
250*5a6e8488SAndroid Build Coastguard Worker  */
251*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_TRUNC(s) ((s).lo)
252*5a6e8488SAndroid Build Coastguard Worker 
253*5a6e8488SAndroid Build Coastguard Worker /**
254*5a6e8488SAndroid Build Coastguard Worker  * Chops a PCG state in half and returns the top bits.
255*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to chop.
256*5a6e8488SAndroid Build Coastguard Worker  * @return   The chopped state's top bits.
257*5a6e8488SAndroid Build Coastguard Worker  */
258*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_CHOP(s) ((s).hi)
259*5a6e8488SAndroid Build Coastguard Worker 
260*5a6e8488SAndroid Build Coastguard Worker /**
261*5a6e8488SAndroid Build Coastguard Worker  * Returns the rotate amount for a PCG state.
262*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to rotate.
263*5a6e8488SAndroid Build Coastguard Worker  * @return   The semi-rotated state.
264*5a6e8488SAndroid Build Coastguard Worker  */
265*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ROTAMT(s) ((unsigned int) ((s).hi >> 58UL))
266*5a6e8488SAndroid Build Coastguard Worker 
267*5a6e8488SAndroid Build Coastguard Worker /// A 64-bit integer with the bottom 32 bits set.
268*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_BOTTOM32 (((uint_fast64_t) 0xffffffffULL))
269*5a6e8488SAndroid Build Coastguard Worker 
270*5a6e8488SAndroid Build Coastguard Worker /**
271*5a6e8488SAndroid Build Coastguard Worker  * Returns the 32-bit truncated value of @a n.
272*5a6e8488SAndroid Build Coastguard Worker  * @param n  The integer to truncate.
273*5a6e8488SAndroid Build Coastguard Worker  * @return   The bottom 32 bits of @a n.
274*5a6e8488SAndroid Build Coastguard Worker  */
275*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_TRUNC32(n) ((n) & (BC_RAND_BOTTOM32))
276*5a6e8488SAndroid Build Coastguard Worker 
277*5a6e8488SAndroid Build Coastguard Worker /**
278*5a6e8488SAndroid Build Coastguard Worker  * Returns the second 32 bits of @a n.
279*5a6e8488SAndroid Build Coastguard Worker  * @param n  The integer to truncate.
280*5a6e8488SAndroid Build Coastguard Worker  * @return   The second 32 bits of @a n.
281*5a6e8488SAndroid Build Coastguard Worker  */
282*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_CHOP32(n) ((n) >> 32)
283*5a6e8488SAndroid Build Coastguard Worker 
284*5a6e8488SAndroid Build Coastguard Worker #endif // BC_RAND_BUILTIN
285*5a6e8488SAndroid Build Coastguard Worker 
286*5a6e8488SAndroid Build Coastguard Worker /// A constant defined by PCG.
287*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_MULTIPLIER \
288*5a6e8488SAndroid Build Coastguard Worker 	BC_RAND_CONSTANT(2549297995355413924ULL, 4865540595714422341ULL)
289*5a6e8488SAndroid Build Coastguard Worker 
290*5a6e8488SAndroid Build Coastguard Worker /**
291*5a6e8488SAndroid Build Coastguard Worker  * Returns the result of a PCG fold.
292*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to fold.
293*5a6e8488SAndroid Build Coastguard Worker  * @return   The folded state.
294*5a6e8488SAndroid Build Coastguard Worker  */
295*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_FOLD(s) ((BcRand) (BC_RAND_CHOP(s) ^ BC_RAND_TRUNC(s)))
296*5a6e8488SAndroid Build Coastguard Worker 
297*5a6e8488SAndroid Build Coastguard Worker #else // BC_LONG_BIT >= 64
298*5a6e8488SAndroid Build Coastguard Worker 
299*5a6e8488SAndroid Build Coastguard Worker // If we are using 32-bit longs, we need to set these so.
300*5a6e8488SAndroid Build Coastguard Worker #undef BC_RAND_BUILTIN
301*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_BUILTIN (1)
302*5a6e8488SAndroid Build Coastguard Worker 
303*5a6e8488SAndroid Build Coastguard Worker /// The type for random integers.
304*5a6e8488SAndroid Build Coastguard Worker typedef uint32_t BcRand;
305*5a6e8488SAndroid Build Coastguard Worker 
306*5a6e8488SAndroid Build Coastguard Worker /// A constant defined by PCG.
307*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ROTC (31)
308*5a6e8488SAndroid Build Coastguard Worker 
309*5a6e8488SAndroid Build Coastguard Worker /// A typedef for the PCG state.
310*5a6e8488SAndroid Build Coastguard Worker typedef uint_fast64_t BcRandState;
311*5a6e8488SAndroid Build Coastguard Worker 
312*5a6e8488SAndroid Build Coastguard Worker /**
313*5a6e8488SAndroid Build Coastguard Worker  * Multiply two integers, worrying about overflow.
314*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first integer.
315*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second integer.
316*5a6e8488SAndroid Build Coastguard Worker  * @return   The product of the PCG states.
317*5a6e8488SAndroid Build Coastguard Worker  */
318*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_mul(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
319*5a6e8488SAndroid Build Coastguard Worker 
320*5a6e8488SAndroid Build Coastguard Worker /**
321*5a6e8488SAndroid Build Coastguard Worker  * Add two integers, worrying about overflow.
322*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first integer.
323*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second integer.
324*5a6e8488SAndroid Build Coastguard Worker  * @return   The sum of the PCG states.
325*5a6e8488SAndroid Build Coastguard Worker  */
326*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_add(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
327*5a6e8488SAndroid Build Coastguard Worker 
328*5a6e8488SAndroid Build Coastguard Worker /**
329*5a6e8488SAndroid Build Coastguard Worker  * Multiply two PCG states.
330*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first PCG state.
331*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second PCG state.
332*5a6e8488SAndroid Build Coastguard Worker  * @return   The product of the PCG states.
333*5a6e8488SAndroid Build Coastguard Worker  */
334*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_mul2(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
335*5a6e8488SAndroid Build Coastguard Worker 
336*5a6e8488SAndroid Build Coastguard Worker /**
337*5a6e8488SAndroid Build Coastguard Worker  * Add two PCG states.
338*5a6e8488SAndroid Build Coastguard Worker  * @param a  The first PCG state.
339*5a6e8488SAndroid Build Coastguard Worker  * @param b  The second PCG state.
340*5a6e8488SAndroid Build Coastguard Worker  * @return   The sum of the PCG states.
341*5a6e8488SAndroid Build Coastguard Worker  */
342*5a6e8488SAndroid Build Coastguard Worker #define bc_rand_add2(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
343*5a6e8488SAndroid Build Coastguard Worker 
344*5a6e8488SAndroid Build Coastguard Worker /**
345*5a6e8488SAndroid Build Coastguard Worker  * Figure out if the PRNG has been modified. Since the increment of the PRNG has
346*5a6e8488SAndroid Build Coastguard Worker  * to be odd, we use the extra bit to store whether it has been modified or not.
347*5a6e8488SAndroid Build Coastguard Worker  * @param r  The PRNG.
348*5a6e8488SAndroid Build Coastguard Worker  * @return   True if the PRNG has *not* been modified, false otherwise.
349*5a6e8488SAndroid Build Coastguard Worker  */
350*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_NOTMODIFIED(r) (((r)->inc & 1UL) == 0)
351*5a6e8488SAndroid Build Coastguard Worker 
352*5a6e8488SAndroid Build Coastguard Worker /**
353*5a6e8488SAndroid Build Coastguard Worker  * Return true if the PRNG has not been seeded yet.
354*5a6e8488SAndroid Build Coastguard Worker  * @param r  The PRNG.
355*5a6e8488SAndroid Build Coastguard Worker  * @return   True if the PRNG has not been seeded yet, false otherwise.
356*5a6e8488SAndroid Build Coastguard Worker  */
357*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ZERO(r) (!(r)->state)
358*5a6e8488SAndroid Build Coastguard Worker 
359*5a6e8488SAndroid Build Coastguard Worker /**
360*5a6e8488SAndroid Build Coastguard Worker  * Returns a constant built from a number.
361*5a6e8488SAndroid Build Coastguard Worker  * @param n  The number.
362*5a6e8488SAndroid Build Coastguard Worker  * @return   The constant built from @a n.
363*5a6e8488SAndroid Build Coastguard Worker  */
364*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_CONSTANT(n) UINT64_C(n)
365*5a6e8488SAndroid Build Coastguard Worker 
366*5a6e8488SAndroid Build Coastguard Worker /// A constant defined by PCG.
367*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_MULTIPLIER BC_RAND_CONSTANT(6364136223846793005)
368*5a6e8488SAndroid Build Coastguard Worker 
369*5a6e8488SAndroid Build Coastguard Worker /**
370*5a6e8488SAndroid Build Coastguard Worker  * Truncates a PCG state to the number of bits in a random integer.
371*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to truncate.
372*5a6e8488SAndroid Build Coastguard Worker  * @return   The truncated state.
373*5a6e8488SAndroid Build Coastguard Worker  */
374*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_TRUNC(s) ((uint32_t) (s))
375*5a6e8488SAndroid Build Coastguard Worker 
376*5a6e8488SAndroid Build Coastguard Worker /**
377*5a6e8488SAndroid Build Coastguard Worker  * Chops a PCG state in half and returns the top bits.
378*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to chop.
379*5a6e8488SAndroid Build Coastguard Worker  * @return   The chopped state's top bits.
380*5a6e8488SAndroid Build Coastguard Worker  */
381*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_CHOP(s) ((uint32_t) ((s) >> 32UL))
382*5a6e8488SAndroid Build Coastguard Worker 
383*5a6e8488SAndroid Build Coastguard Worker /**
384*5a6e8488SAndroid Build Coastguard Worker  * Returns the rotate amount for a PCG state.
385*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to rotate.
386*5a6e8488SAndroid Build Coastguard Worker  * @return   The semi-rotated state.
387*5a6e8488SAndroid Build Coastguard Worker  */
388*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ROTAMT(s) ((unsigned int) ((s) >> 59UL))
389*5a6e8488SAndroid Build Coastguard Worker 
390*5a6e8488SAndroid Build Coastguard Worker /**
391*5a6e8488SAndroid Build Coastguard Worker  * Returns the result of a PCG fold.
392*5a6e8488SAndroid Build Coastguard Worker  * @param s  The state to fold.
393*5a6e8488SAndroid Build Coastguard Worker  * @return   The folded state.
394*5a6e8488SAndroid Build Coastguard Worker  */
395*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_FOLD(s) ((BcRand) ((((s) >> 18U) ^ (s)) >> 27U))
396*5a6e8488SAndroid Build Coastguard Worker 
397*5a6e8488SAndroid Build Coastguard Worker #endif // BC_LONG_BIT >= 64
398*5a6e8488SAndroid Build Coastguard Worker 
399*5a6e8488SAndroid Build Coastguard Worker /**
400*5a6e8488SAndroid Build Coastguard Worker  * Rotates @a v by @a r bits.
401*5a6e8488SAndroid Build Coastguard Worker  * @param v  The value to rotate.
402*5a6e8488SAndroid Build Coastguard Worker  * @param r  The amount to rotate by.
403*5a6e8488SAndroid Build Coastguard Worker  * @return   The rotated value.
404*5a6e8488SAndroid Build Coastguard Worker  */
405*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_ROT(v, r) \
406*5a6e8488SAndroid Build Coastguard Worker 	((BcRand) (((v) >> (r)) | ((v) << ((0 - (r)) & BC_RAND_ROTC))))
407*5a6e8488SAndroid Build Coastguard Worker 
408*5a6e8488SAndroid Build Coastguard Worker /// The number of bits in a random integer.
409*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_BITS (sizeof(BcRand) * CHAR_BIT)
410*5a6e8488SAndroid Build Coastguard Worker 
411*5a6e8488SAndroid Build Coastguard Worker /// The number of bits in a PCG state.
412*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_STATE_BITS (sizeof(BcRandState) * CHAR_BIT)
413*5a6e8488SAndroid Build Coastguard Worker 
414*5a6e8488SAndroid Build Coastguard Worker /// The size of a BcNum with the max random integer. This isn't exact; it's
415*5a6e8488SAndroid Build Coastguard Worker /// actually rather crude. But it's always enough.
416*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_NUM_SIZE (BC_NUM_BIGDIG_LOG10 * 2 + 2)
417*5a6e8488SAndroid Build Coastguard Worker 
418*5a6e8488SAndroid Build Coastguard Worker /// The mask for how many bits bc_rand_srand() can set per iteration.
419*5a6e8488SAndroid Build Coastguard Worker #define BC_RAND_SRAND_BITS ((1 << CHAR_BIT) - 1)
420*5a6e8488SAndroid Build Coastguard Worker 
421*5a6e8488SAndroid Build Coastguard Worker /// The actual RNG data. These are the actual PRNG's.
422*5a6e8488SAndroid Build Coastguard Worker typedef struct BcRNGData
423*5a6e8488SAndroid Build Coastguard Worker {
424*5a6e8488SAndroid Build Coastguard Worker 	/// The state.
425*5a6e8488SAndroid Build Coastguard Worker 	BcRandState state;
426*5a6e8488SAndroid Build Coastguard Worker 
427*5a6e8488SAndroid Build Coastguard Worker 	/// The increment and the modified bit.
428*5a6e8488SAndroid Build Coastguard Worker 	BcRandState inc;
429*5a6e8488SAndroid Build Coastguard Worker 
430*5a6e8488SAndroid Build Coastguard Worker } BcRNGData;
431*5a6e8488SAndroid Build Coastguard Worker 
432*5a6e8488SAndroid Build Coastguard Worker /// The public PRNG. This is just a stack of PRNG's to maintain the globals
433*5a6e8488SAndroid Build Coastguard Worker /// stack illusion.
434*5a6e8488SAndroid Build Coastguard Worker typedef struct BcRNG
435*5a6e8488SAndroid Build Coastguard Worker {
436*5a6e8488SAndroid Build Coastguard Worker 	/// The stack of PRNG's.
437*5a6e8488SAndroid Build Coastguard Worker 	BcVec v;
438*5a6e8488SAndroid Build Coastguard Worker 
439*5a6e8488SAndroid Build Coastguard Worker } BcRNG;
440*5a6e8488SAndroid Build Coastguard Worker 
441*5a6e8488SAndroid Build Coastguard Worker /**
442*5a6e8488SAndroid Build Coastguard Worker  * Initializes a BcRNG.
443*5a6e8488SAndroid Build Coastguard Worker  * @param r  The BcRNG to initialize.
444*5a6e8488SAndroid Build Coastguard Worker  */
445*5a6e8488SAndroid Build Coastguard Worker void
446*5a6e8488SAndroid Build Coastguard Worker bc_rand_init(BcRNG* r);
447*5a6e8488SAndroid Build Coastguard Worker 
448*5a6e8488SAndroid Build Coastguard Worker #if BC_RAND_USE_FREE
449*5a6e8488SAndroid Build Coastguard Worker 
450*5a6e8488SAndroid Build Coastguard Worker /**
451*5a6e8488SAndroid Build Coastguard Worker  * Frees a BcRNG. This is only in debug builds because it would only be freed on
452*5a6e8488SAndroid Build Coastguard Worker  * exit.
453*5a6e8488SAndroid Build Coastguard Worker  * @param r  The BcRNG to free.
454*5a6e8488SAndroid Build Coastguard Worker  */
455*5a6e8488SAndroid Build Coastguard Worker void
456*5a6e8488SAndroid Build Coastguard Worker bc_rand_free(BcRNG* r);
457*5a6e8488SAndroid Build Coastguard Worker 
458*5a6e8488SAndroid Build Coastguard Worker #endif // BC_RAND_USE_FREE
459*5a6e8488SAndroid Build Coastguard Worker 
460*5a6e8488SAndroid Build Coastguard Worker /**
461*5a6e8488SAndroid Build Coastguard Worker  * Returns a random integer from the PRNG.
462*5a6e8488SAndroid Build Coastguard Worker  * @param r  The PRNG.
463*5a6e8488SAndroid Build Coastguard Worker  * @return   A random integer.
464*5a6e8488SAndroid Build Coastguard Worker  */
465*5a6e8488SAndroid Build Coastguard Worker BcRand
466*5a6e8488SAndroid Build Coastguard Worker bc_rand_int(BcRNG* r);
467*5a6e8488SAndroid Build Coastguard Worker 
468*5a6e8488SAndroid Build Coastguard Worker /**
469*5a6e8488SAndroid Build Coastguard Worker  * Returns a random integer from the PRNG bounded by @a bound. Bias is
470*5a6e8488SAndroid Build Coastguard Worker  * eliminated.
471*5a6e8488SAndroid Build Coastguard Worker  * @param r      The PRNG.
472*5a6e8488SAndroid Build Coastguard Worker  * @param bound  The bound for the random integer.
473*5a6e8488SAndroid Build Coastguard Worker  * @return       A bounded random integer.
474*5a6e8488SAndroid Build Coastguard Worker  */
475*5a6e8488SAndroid Build Coastguard Worker BcRand
476*5a6e8488SAndroid Build Coastguard Worker bc_rand_bounded(BcRNG* r, BcRand bound);
477*5a6e8488SAndroid Build Coastguard Worker 
478*5a6e8488SAndroid Build Coastguard Worker /**
479*5a6e8488SAndroid Build Coastguard Worker  * Seed the PRNG with the state in two parts and the increment in two parts.
480*5a6e8488SAndroid Build Coastguard Worker  * @param r       The PRNG.
481*5a6e8488SAndroid Build Coastguard Worker  * @param state1  The first part of the state.
482*5a6e8488SAndroid Build Coastguard Worker  * @param state2  The second part of the state.
483*5a6e8488SAndroid Build Coastguard Worker  * @param inc1    The first part of the increment.
484*5a6e8488SAndroid Build Coastguard Worker  * @param inc2    The second part of the increment.
485*5a6e8488SAndroid Build Coastguard Worker  */
486*5a6e8488SAndroid Build Coastguard Worker void
487*5a6e8488SAndroid Build Coastguard Worker bc_rand_seed(BcRNG* r, ulong state1, ulong state2, ulong inc1, ulong inc2);
488*5a6e8488SAndroid Build Coastguard Worker 
489*5a6e8488SAndroid Build Coastguard Worker /**
490*5a6e8488SAndroid Build Coastguard Worker  * Pushes a new PRNG onto the PRNG stack.
491*5a6e8488SAndroid Build Coastguard Worker  * @param r  The PRNG.
492*5a6e8488SAndroid Build Coastguard Worker  */
493*5a6e8488SAndroid Build Coastguard Worker void
494*5a6e8488SAndroid Build Coastguard Worker bc_rand_push(BcRNG* r);
495*5a6e8488SAndroid Build Coastguard Worker 
496*5a6e8488SAndroid Build Coastguard Worker /**
497*5a6e8488SAndroid Build Coastguard Worker  * Pops one or all but one items off of the PRNG stack.
498*5a6e8488SAndroid Build Coastguard Worker  * @param r      The PRNG.
499*5a6e8488SAndroid Build Coastguard Worker  * @param reset  True if all but one PRNG should be popped off the stack, false
500*5a6e8488SAndroid Build Coastguard Worker  *               if only one should be popped.
501*5a6e8488SAndroid Build Coastguard Worker  */
502*5a6e8488SAndroid Build Coastguard Worker void
503*5a6e8488SAndroid Build Coastguard Worker bc_rand_pop(BcRNG* r, bool reset);
504*5a6e8488SAndroid Build Coastguard Worker 
505*5a6e8488SAndroid Build Coastguard Worker /**
506*5a6e8488SAndroid Build Coastguard Worker  * Returns, via pointers, the state of the PRNG in pieces.
507*5a6e8488SAndroid Build Coastguard Worker  * @param r   The PRNG.
508*5a6e8488SAndroid Build Coastguard Worker  * @param s1  The return value for the first part of the state.
509*5a6e8488SAndroid Build Coastguard Worker  * @param s2  The return value for the second part of the state.
510*5a6e8488SAndroid Build Coastguard Worker  * @param i1  The return value for the first part of the increment.
511*5a6e8488SAndroid Build Coastguard Worker  * @param i2  The return value for the second part of the increment.
512*5a6e8488SAndroid Build Coastguard Worker  */
513*5a6e8488SAndroid Build Coastguard Worker void
514*5a6e8488SAndroid Build Coastguard Worker bc_rand_getRands(BcRNG* r, BcRand* s1, BcRand* s2, BcRand* i1, BcRand* i2);
515*5a6e8488SAndroid Build Coastguard Worker 
516*5a6e8488SAndroid Build Coastguard Worker /**
517*5a6e8488SAndroid Build Coastguard Worker  * Seed the PRNG with random data.
518*5a6e8488SAndroid Build Coastguard Worker  * @param rng  The PRNG.
519*5a6e8488SAndroid Build Coastguard Worker  */
520*5a6e8488SAndroid Build Coastguard Worker void
521*5a6e8488SAndroid Build Coastguard Worker bc_rand_srand(BcRNGData* rng);
522*5a6e8488SAndroid Build Coastguard Worker 
523*5a6e8488SAndroid Build Coastguard Worker /// A reference to a constant multiplier.
524*5a6e8488SAndroid Build Coastguard Worker extern const BcRandState bc_rand_multiplier;
525*5a6e8488SAndroid Build Coastguard Worker 
526*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
527*5a6e8488SAndroid Build Coastguard Worker 
528*5a6e8488SAndroid Build Coastguard Worker #endif // BC_RAND_H
529