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