1*9119bafbSConrad Meyer /* 2*9119bafbSConrad Meyer * PCG Random Number Generation for C. 3*9119bafbSConrad Meyer * 4*9119bafbSConrad Meyer * Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>, 5*9119bafbSConrad Meyer * and the PCG Project contributors. 6*9119bafbSConrad Meyer * 7*9119bafbSConrad Meyer * SPDX-License-Identifier: (Apache-2.0 OR MIT) 8*9119bafbSConrad Meyer * 9*9119bafbSConrad Meyer * Licensed under the Apache License, Version 2.0 (provided in 10*9119bafbSConrad Meyer * LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0) 11*9119bafbSConrad Meyer * or under the MIT license (provided in LICENSE-MIT.txt and at 12*9119bafbSConrad Meyer * http://opensource.org/licenses/MIT), at your option. This file may not 13*9119bafbSConrad Meyer * be copied, modified, or distributed except according to those terms. 14*9119bafbSConrad Meyer * 15*9119bafbSConrad Meyer * Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either 16*9119bafbSConrad Meyer * express or implied. See your chosen license for details. 17*9119bafbSConrad Meyer * 18*9119bafbSConrad Meyer * For additional information about the PCG random number generation scheme, 19*9119bafbSConrad Meyer * visit http://www.pcg-random.org/. 20*9119bafbSConrad Meyer */ 21*9119bafbSConrad Meyer 22*9119bafbSConrad Meyer /* 23*9119bafbSConrad Meyer * This code is derived from the canonical C++ PCG implementation, which 24*9119bafbSConrad Meyer * has many additional features and is preferable if you can use C++ in 25*9119bafbSConrad Meyer * your project. 26*9119bafbSConrad Meyer * 27*9119bafbSConrad Meyer * Much of the derivation was performed mechanically. In particular, the 28*9119bafbSConrad Meyer * output functions were generated by compiling the C++ output functions 29*9119bafbSConrad Meyer * into LLVM bitcode and then transforming that using the LLVM C backend 30*9119bafbSConrad Meyer * (from https://github.com/draperlaboratory/llvm-cbe), and then 31*9119bafbSConrad Meyer * postprocessing and hand editing the output. 32*9119bafbSConrad Meyer * 33*9119bafbSConrad Meyer * Much of the remaining code was generated by C-preprocessor metaprogramming. 34*9119bafbSConrad Meyer */ 35*9119bafbSConrad Meyer 36*9119bafbSConrad Meyer #ifndef PCG_VARIANTS_H_INCLUDED 37*9119bafbSConrad Meyer #define PCG_VARIANTS_H_INCLUDED 1 38*9119bafbSConrad Meyer 39*9119bafbSConrad Meyer #include <inttypes.h> 40*9119bafbSConrad Meyer 41*9119bafbSConrad Meyer #if __SIZEOF_INT128__ 42*9119bafbSConrad Meyer typedef __uint128_t pcg128_t; 43*9119bafbSConrad Meyer #define PCG_128BIT_CONSTANT(high,low) \ 44*9119bafbSConrad Meyer ((((pcg128_t)high) << 64) + low) 45*9119bafbSConrad Meyer #define PCG_HAS_128BIT_OPS 1 46*9119bafbSConrad Meyer #endif 47*9119bafbSConrad Meyer 48*9119bafbSConrad Meyer #if __GNUC_GNU_INLINE__ && !defined(__cplusplus) 49*9119bafbSConrad Meyer #error Nonstandard GNU inlining semantics. Compile with -std=c99 or better. 50*9119bafbSConrad Meyer /* We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE 51*9119bafbSConrad Meyer but better to just reject ancient C code. */ 52*9119bafbSConrad Meyer #endif 53*9119bafbSConrad Meyer 54*9119bafbSConrad Meyer #if __cplusplus 55*9119bafbSConrad Meyer extern "C" { 56*9119bafbSConrad Meyer #endif 57*9119bafbSConrad Meyer 58*9119bafbSConrad Meyer /* 59*9119bafbSConrad Meyer * Rotate helper functions. 60*9119bafbSConrad Meyer */ 61*9119bafbSConrad Meyer 62*9119bafbSConrad Meyer inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot) 63*9119bafbSConrad Meyer { 64*9119bafbSConrad Meyer /* Unfortunately, clang is kinda pathetic when it comes to properly 65*9119bafbSConrad Meyer * recognizing idiomatic rotate code, so for clang we actually provide 66*9119bafbSConrad Meyer * assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss. 67*9119bafbSConrad Meyer */ 68*9119bafbSConrad Meyer #if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) 69*9119bafbSConrad Meyer asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); 70*9119bafbSConrad Meyer return value; 71*9119bafbSConrad Meyer #else 72*9119bafbSConrad Meyer return (value >> rot) | (value << ((- rot) & 7)); 73*9119bafbSConrad Meyer #endif 74*9119bafbSConrad Meyer } 75*9119bafbSConrad Meyer 76*9119bafbSConrad Meyer inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot) 77*9119bafbSConrad Meyer { 78*9119bafbSConrad Meyer #if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) 79*9119bafbSConrad Meyer asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); 80*9119bafbSConrad Meyer return value; 81*9119bafbSConrad Meyer #else 82*9119bafbSConrad Meyer return (value >> rot) | (value << ((- rot) & 15)); 83*9119bafbSConrad Meyer #endif 84*9119bafbSConrad Meyer } 85*9119bafbSConrad Meyer 86*9119bafbSConrad Meyer inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) 87*9119bafbSConrad Meyer { 88*9119bafbSConrad Meyer #if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) 89*9119bafbSConrad Meyer asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); 90*9119bafbSConrad Meyer return value; 91*9119bafbSConrad Meyer #else 92*9119bafbSConrad Meyer return (value >> rot) | (value << ((- rot) & 31)); 93*9119bafbSConrad Meyer #endif 94*9119bafbSConrad Meyer } 95*9119bafbSConrad Meyer 96*9119bafbSConrad Meyer inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) 97*9119bafbSConrad Meyer { 98*9119bafbSConrad Meyer #if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__ 99*9119bafbSConrad Meyer /* For whatever reason, clang actually *does* generate rotq by 100*9119bafbSConrad Meyer itself, so we don't need this code. */ 101*9119bafbSConrad Meyer asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); 102*9119bafbSConrad Meyer return value; 103*9119bafbSConrad Meyer #else 104*9119bafbSConrad Meyer return (value >> rot) | (value << ((- rot) & 63)); 105*9119bafbSConrad Meyer #endif 106*9119bafbSConrad Meyer } 107*9119bafbSConrad Meyer 108*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 109*9119bafbSConrad Meyer inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot) 110*9119bafbSConrad Meyer { 111*9119bafbSConrad Meyer return (value >> rot) | (value << ((- rot) & 127)); 112*9119bafbSConrad Meyer } 113*9119bafbSConrad Meyer #endif 114*9119bafbSConrad Meyer 115*9119bafbSConrad Meyer /* 116*9119bafbSConrad Meyer * Output functions. These are the core of the PCG generation scheme. 117*9119bafbSConrad Meyer */ 118*9119bafbSConrad Meyer 119*9119bafbSConrad Meyer /* XSH RS */ 120*9119bafbSConrad Meyer 121*9119bafbSConrad Meyer inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state) 122*9119bafbSConrad Meyer { 123*9119bafbSConrad Meyer return (uint8_t)(((state >> 7u) ^ state) >> ((state >> 14u) + 3u)); 124*9119bafbSConrad Meyer } 125*9119bafbSConrad Meyer 126*9119bafbSConrad Meyer inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state) 127*9119bafbSConrad Meyer { 128*9119bafbSConrad Meyer return (uint16_t)(((state >> 11u) ^ state) >> ((state >> 30u) + 11u)); 129*9119bafbSConrad Meyer } 130*9119bafbSConrad Meyer 131*9119bafbSConrad Meyer inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state) 132*9119bafbSConrad Meyer { 133*9119bafbSConrad Meyer 134*9119bafbSConrad Meyer return (uint32_t)(((state >> 22u) ^ state) >> ((state >> 61u) + 22u)); 135*9119bafbSConrad Meyer } 136*9119bafbSConrad Meyer 137*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 138*9119bafbSConrad Meyer inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state) 139*9119bafbSConrad Meyer { 140*9119bafbSConrad Meyer return (uint64_t)(((state >> 43u) ^ state) >> ((state >> 124u) + 45u)); 141*9119bafbSConrad Meyer } 142*9119bafbSConrad Meyer #endif 143*9119bafbSConrad Meyer 144*9119bafbSConrad Meyer /* XSH RR */ 145*9119bafbSConrad Meyer 146*9119bafbSConrad Meyer inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state) 147*9119bafbSConrad Meyer { 148*9119bafbSConrad Meyer return pcg_rotr_8(((state >> 5u) ^ state) >> 5u, state >> 13u); 149*9119bafbSConrad Meyer } 150*9119bafbSConrad Meyer 151*9119bafbSConrad Meyer inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state) 152*9119bafbSConrad Meyer { 153*9119bafbSConrad Meyer return pcg_rotr_16(((state >> 10u) ^ state) >> 12u, state >> 28u); 154*9119bafbSConrad Meyer } 155*9119bafbSConrad Meyer 156*9119bafbSConrad Meyer inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state) 157*9119bafbSConrad Meyer { 158*9119bafbSConrad Meyer return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u); 159*9119bafbSConrad Meyer } 160*9119bafbSConrad Meyer 161*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 162*9119bafbSConrad Meyer inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state) 163*9119bafbSConrad Meyer { 164*9119bafbSConrad Meyer return pcg_rotr_64(((state >> 35u) ^ state) >> 58u, state >> 122u); 165*9119bafbSConrad Meyer } 166*9119bafbSConrad Meyer #endif 167*9119bafbSConrad Meyer 168*9119bafbSConrad Meyer /* RXS M XS */ 169*9119bafbSConrad Meyer 170*9119bafbSConrad Meyer inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state) 171*9119bafbSConrad Meyer { 172*9119bafbSConrad Meyer uint8_t word = ((state >> ((state >> 6u) + 2u)) ^ state) * 217u; 173*9119bafbSConrad Meyer return (word >> 6u) ^ word; 174*9119bafbSConrad Meyer } 175*9119bafbSConrad Meyer 176*9119bafbSConrad Meyer inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state) 177*9119bafbSConrad Meyer { 178*9119bafbSConrad Meyer uint16_t word = ((state >> ((state >> 13u) + 3u)) ^ state) * 62169u; 179*9119bafbSConrad Meyer return (word >> 11u) ^ word; 180*9119bafbSConrad Meyer } 181*9119bafbSConrad Meyer 182*9119bafbSConrad Meyer inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state) 183*9119bafbSConrad Meyer { 184*9119bafbSConrad Meyer uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; 185*9119bafbSConrad Meyer return (word >> 22u) ^ word; 186*9119bafbSConrad Meyer } 187*9119bafbSConrad Meyer 188*9119bafbSConrad Meyer inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state) 189*9119bafbSConrad Meyer { 190*9119bafbSConrad Meyer uint64_t word = ((state >> ((state >> 59u) + 5u)) ^ state) 191*9119bafbSConrad Meyer * 12605985483714917081ull; 192*9119bafbSConrad Meyer return (word >> 43u) ^ word; 193*9119bafbSConrad Meyer } 194*9119bafbSConrad Meyer 195*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 196*9119bafbSConrad Meyer inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state) 197*9119bafbSConrad Meyer { 198*9119bafbSConrad Meyer pcg128_t word = ((state >> ((state >> 122u) + 6u)) ^ state) 199*9119bafbSConrad Meyer * (PCG_128BIT_CONSTANT(17766728186571221404ULL, 200*9119bafbSConrad Meyer 12605985483714917081ULL)); 201*9119bafbSConrad Meyer /* 327738287884841127335028083622016905945 */ 202*9119bafbSConrad Meyer return (word >> 86u) ^ word; 203*9119bafbSConrad Meyer } 204*9119bafbSConrad Meyer #endif 205*9119bafbSConrad Meyer 206*9119bafbSConrad Meyer /* RXS M */ 207*9119bafbSConrad Meyer 208*9119bafbSConrad Meyer inline uint8_t pcg_output_rxs_m_16_8(uint16_t state) 209*9119bafbSConrad Meyer { 210*9119bafbSConrad Meyer return (((state >> ((state >> 13u) + 3u)) ^ state) * 62169u) >> 8u; 211*9119bafbSConrad Meyer } 212*9119bafbSConrad Meyer 213*9119bafbSConrad Meyer inline uint16_t pcg_output_rxs_m_32_16(uint32_t state) 214*9119bafbSConrad Meyer { 215*9119bafbSConrad Meyer return (((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u) >> 16u; 216*9119bafbSConrad Meyer } 217*9119bafbSConrad Meyer 218*9119bafbSConrad Meyer inline uint32_t pcg_output_rxs_m_64_32(uint64_t state) 219*9119bafbSConrad Meyer { 220*9119bafbSConrad Meyer return (((state >> ((state >> 59u) + 5u)) ^ state) 221*9119bafbSConrad Meyer * 12605985483714917081ull) >> 32u; 222*9119bafbSConrad Meyer } 223*9119bafbSConrad Meyer 224*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 225*9119bafbSConrad Meyer inline uint64_t pcg_output_rxs_m_128_64(pcg128_t state) 226*9119bafbSConrad Meyer { 227*9119bafbSConrad Meyer return (((state >> ((state >> 122u) + 6u)) ^ state) 228*9119bafbSConrad Meyer * (PCG_128BIT_CONSTANT(17766728186571221404ULL, 229*9119bafbSConrad Meyer 12605985483714917081ULL))) >> 64u; 230*9119bafbSConrad Meyer /* 327738287884841127335028083622016905945 */ 231*9119bafbSConrad Meyer } 232*9119bafbSConrad Meyer #endif 233*9119bafbSConrad Meyer 234*9119bafbSConrad Meyer /* XSL RR (only defined for >= 64 bits) */ 235*9119bafbSConrad Meyer 236*9119bafbSConrad Meyer inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state) 237*9119bafbSConrad Meyer { 238*9119bafbSConrad Meyer return pcg_rotr_32(((uint32_t)(state >> 32u)) ^ (uint32_t)state, 239*9119bafbSConrad Meyer state >> 59u); 240*9119bafbSConrad Meyer } 241*9119bafbSConrad Meyer 242*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 243*9119bafbSConrad Meyer inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state) 244*9119bafbSConrad Meyer { 245*9119bafbSConrad Meyer return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state, 246*9119bafbSConrad Meyer state >> 122u); 247*9119bafbSConrad Meyer } 248*9119bafbSConrad Meyer #endif 249*9119bafbSConrad Meyer 250*9119bafbSConrad Meyer /* XSL RR RR (only defined for >= 64 bits) */ 251*9119bafbSConrad Meyer 252*9119bafbSConrad Meyer inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state) 253*9119bafbSConrad Meyer { 254*9119bafbSConrad Meyer uint32_t rot1 = (uint32_t)(state >> 59u); 255*9119bafbSConrad Meyer uint32_t high = (uint32_t)(state >> 32u); 256*9119bafbSConrad Meyer uint32_t low = (uint32_t)state; 257*9119bafbSConrad Meyer uint32_t xored = high ^ low; 258*9119bafbSConrad Meyer uint32_t newlow = pcg_rotr_32(xored, rot1); 259*9119bafbSConrad Meyer uint32_t newhigh = pcg_rotr_32(high, newlow & 31u); 260*9119bafbSConrad Meyer return (((uint64_t)newhigh) << 32u) | newlow; 261*9119bafbSConrad Meyer } 262*9119bafbSConrad Meyer 263*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 264*9119bafbSConrad Meyer inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state) 265*9119bafbSConrad Meyer { 266*9119bafbSConrad Meyer uint32_t rot1 = (uint32_t)(state >> 122u); 267*9119bafbSConrad Meyer uint64_t high = (uint64_t)(state >> 64u); 268*9119bafbSConrad Meyer uint64_t low = (uint64_t)state; 269*9119bafbSConrad Meyer uint64_t xored = high ^ low; 270*9119bafbSConrad Meyer uint64_t newlow = pcg_rotr_64(xored, rot1); 271*9119bafbSConrad Meyer uint64_t newhigh = pcg_rotr_64(high, newlow & 63u); 272*9119bafbSConrad Meyer return (((pcg128_t)newhigh) << 64u) | newlow; 273*9119bafbSConrad Meyer } 274*9119bafbSConrad Meyer #endif 275*9119bafbSConrad Meyer 276*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_8 141U 277*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_16 12829U 278*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_32 747796405U 279*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL 280*9119bafbSConrad Meyer 281*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_8 77U 282*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_16 47989U 283*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_32 2891336453U 284*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL 285*9119bafbSConrad Meyer 286*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 287*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_128 \ 288*9119bafbSConrad Meyer PCG_128BIT_CONSTANT(2549297995355413924ULL,4865540595714422341ULL) 289*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_128 \ 290*9119bafbSConrad Meyer PCG_128BIT_CONSTANT(6364136223846793005ULL,1442695040888963407ULL) 291*9119bafbSConrad Meyer #endif 292*9119bafbSConrad Meyer 293*9119bafbSConrad Meyer /* 294*9119bafbSConrad Meyer * Static initialization constants (if you can't call srandom for some 295*9119bafbSConrad Meyer * bizarre reason). 296*9119bafbSConrad Meyer */ 297*9119bafbSConrad Meyer 298*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_8_INITIALIZER { 0xd7U } 299*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_16_INITIALIZER { 0x20dfU } 300*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_32_INITIALIZER { 0x46b56677U } 301*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_64_INITIALIZER { 0x4d595df4d0f33173ULL } 302*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 303*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_128_INITIALIZER \ 304*9119bafbSConrad Meyer { PCG_128BIT_CONSTANT(0xb8dc10e158a92392ULL, 0x98046df007ec0a53ULL) } 305*9119bafbSConrad Meyer #endif 306*9119bafbSConrad Meyer 307*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_8_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER 308*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_16_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER 309*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_32_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER 310*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_64_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER 311*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 312*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_128_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER 313*9119bafbSConrad Meyer #endif 314*9119bafbSConrad Meyer 315*9119bafbSConrad Meyer #define PCG_STATE_MCG_8_INITIALIZER { 0xe5U } 316*9119bafbSConrad Meyer #define PCG_STATE_MCG_16_INITIALIZER { 0xa5e5U } 317*9119bafbSConrad Meyer #define PCG_STATE_MCG_32_INITIALIZER { 0xd15ea5e5U } 318*9119bafbSConrad Meyer #define PCG_STATE_MCG_64_INITIALIZER { 0xcafef00dd15ea5e5ULL } 319*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 320*9119bafbSConrad Meyer #define PCG_STATE_MCG_128_INITIALIZER \ 321*9119bafbSConrad Meyer { PCG_128BIT_CONSTANT(0x0000000000000000ULL, 0xcafef00dd15ea5e5ULL) } 322*9119bafbSConrad Meyer #endif 323*9119bafbSConrad Meyer 324*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_8_INITIALIZER { 0x9bU, 0xdbU } 325*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_16_INITIALIZER { 0xe39bU, 0x5bdbU } 326*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_32_INITIALIZER { 0xec02d89bU, 0x94b95bdbU } 327*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_64_INITIALIZER \ 328*9119bafbSConrad Meyer { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL } 329*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 330*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_128_INITIALIZER \ 331*9119bafbSConrad Meyer { PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL), \ 332*9119bafbSConrad Meyer PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) } 333*9119bafbSConrad Meyer #endif 334*9119bafbSConrad Meyer 335*9119bafbSConrad Meyer /* Representations for the oneseq, mcg, and unique variants */ 336*9119bafbSConrad Meyer 337*9119bafbSConrad Meyer struct pcg_state_8 { 338*9119bafbSConrad Meyer uint8_t state; 339*9119bafbSConrad Meyer }; 340*9119bafbSConrad Meyer 341*9119bafbSConrad Meyer struct pcg_state_16 { 342*9119bafbSConrad Meyer uint16_t state; 343*9119bafbSConrad Meyer }; 344*9119bafbSConrad Meyer 345*9119bafbSConrad Meyer struct pcg_state_32 { 346*9119bafbSConrad Meyer uint32_t state; 347*9119bafbSConrad Meyer }; 348*9119bafbSConrad Meyer 349*9119bafbSConrad Meyer struct pcg_state_64 { 350*9119bafbSConrad Meyer uint64_t state; 351*9119bafbSConrad Meyer }; 352*9119bafbSConrad Meyer 353*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 354*9119bafbSConrad Meyer struct pcg_state_128 { 355*9119bafbSConrad Meyer pcg128_t state; 356*9119bafbSConrad Meyer }; 357*9119bafbSConrad Meyer #endif 358*9119bafbSConrad Meyer 359*9119bafbSConrad Meyer /* Representations setseq variants */ 360*9119bafbSConrad Meyer 361*9119bafbSConrad Meyer struct pcg_state_setseq_8 { 362*9119bafbSConrad Meyer uint8_t state; 363*9119bafbSConrad Meyer uint8_t inc; 364*9119bafbSConrad Meyer }; 365*9119bafbSConrad Meyer 366*9119bafbSConrad Meyer struct pcg_state_setseq_16 { 367*9119bafbSConrad Meyer uint16_t state; 368*9119bafbSConrad Meyer uint16_t inc; 369*9119bafbSConrad Meyer }; 370*9119bafbSConrad Meyer 371*9119bafbSConrad Meyer struct pcg_state_setseq_32 { 372*9119bafbSConrad Meyer uint32_t state; 373*9119bafbSConrad Meyer uint32_t inc; 374*9119bafbSConrad Meyer }; 375*9119bafbSConrad Meyer 376*9119bafbSConrad Meyer struct pcg_state_setseq_64 { 377*9119bafbSConrad Meyer uint64_t state; 378*9119bafbSConrad Meyer uint64_t inc; 379*9119bafbSConrad Meyer }; 380*9119bafbSConrad Meyer 381*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 382*9119bafbSConrad Meyer struct pcg_state_setseq_128 { 383*9119bafbSConrad Meyer pcg128_t state; 384*9119bafbSConrad Meyer pcg128_t inc; 385*9119bafbSConrad Meyer }; 386*9119bafbSConrad Meyer #endif 387*9119bafbSConrad Meyer 388*9119bafbSConrad Meyer /* Multi-step advance functions (jump-ahead, jump-back) */ 389*9119bafbSConrad Meyer 390*9119bafbSConrad Meyer extern uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult, 391*9119bafbSConrad Meyer uint8_t cur_plus); 392*9119bafbSConrad Meyer extern uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta, 393*9119bafbSConrad Meyer uint16_t cur_mult, uint16_t cur_plus); 394*9119bafbSConrad Meyer extern uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta, 395*9119bafbSConrad Meyer uint32_t cur_mult, uint32_t cur_plus); 396*9119bafbSConrad Meyer extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, 397*9119bafbSConrad Meyer uint64_t cur_mult, uint64_t cur_plus); 398*9119bafbSConrad Meyer 399*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 400*9119bafbSConrad Meyer extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, 401*9119bafbSConrad Meyer pcg128_t cur_mult, pcg128_t cur_plus); 402*9119bafbSConrad Meyer #endif 403*9119bafbSConrad Meyer 404*9119bafbSConrad Meyer /* Functions to advance the underlying LCG, one version for each size and 405*9119bafbSConrad Meyer * each style. These functions are considered semi-private. There is rarely 406*9119bafbSConrad Meyer * a good reason to call them directly. 407*9119bafbSConrad Meyer */ 408*9119bafbSConrad Meyer 409*9119bafbSConrad Meyer inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng) 410*9119bafbSConrad Meyer { 411*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 412*9119bafbSConrad Meyer + PCG_DEFAULT_INCREMENT_8; 413*9119bafbSConrad Meyer } 414*9119bafbSConrad Meyer 415*9119bafbSConrad Meyer inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng, uint8_t delta) 416*9119bafbSConrad Meyer { 417*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 418*9119bafbSConrad Meyer PCG_DEFAULT_INCREMENT_8); 419*9119bafbSConrad Meyer } 420*9119bafbSConrad Meyer 421*9119bafbSConrad Meyer inline void pcg_mcg_8_step_r(struct pcg_state_8* rng) 422*9119bafbSConrad Meyer { 423*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8; 424*9119bafbSConrad Meyer } 425*9119bafbSConrad Meyer 426*9119bafbSConrad Meyer inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta) 427*9119bafbSConrad Meyer { 428*9119bafbSConrad Meyer rng->state 429*9119bafbSConrad Meyer = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 0u); 430*9119bafbSConrad Meyer } 431*9119bafbSConrad Meyer 432*9119bafbSConrad Meyer inline void pcg_unique_8_step_r(struct pcg_state_8* rng) 433*9119bafbSConrad Meyer { 434*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 435*9119bafbSConrad Meyer + (uint8_t)(((intptr_t)rng) | 1u); 436*9119bafbSConrad Meyer } 437*9119bafbSConrad Meyer 438*9119bafbSConrad Meyer inline void pcg_unique_8_advance_r(struct pcg_state_8* rng, uint8_t delta) 439*9119bafbSConrad Meyer { 440*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 441*9119bafbSConrad Meyer (uint8_t)(((intptr_t)rng) | 1u)); 442*9119bafbSConrad Meyer } 443*9119bafbSConrad Meyer 444*9119bafbSConrad Meyer inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng) 445*9119bafbSConrad Meyer { 446*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + rng->inc; 447*9119bafbSConrad Meyer } 448*9119bafbSConrad Meyer 449*9119bafbSConrad Meyer inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng, 450*9119bafbSConrad Meyer uint8_t delta) 451*9119bafbSConrad Meyer { 452*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 453*9119bafbSConrad Meyer rng->inc); 454*9119bafbSConrad Meyer } 455*9119bafbSConrad Meyer 456*9119bafbSConrad Meyer inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng) 457*9119bafbSConrad Meyer { 458*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 459*9119bafbSConrad Meyer + PCG_DEFAULT_INCREMENT_16; 460*9119bafbSConrad Meyer } 461*9119bafbSConrad Meyer 462*9119bafbSConrad Meyer inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng, uint16_t delta) 463*9119bafbSConrad Meyer { 464*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_16( 465*9119bafbSConrad Meyer rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, PCG_DEFAULT_INCREMENT_16); 466*9119bafbSConrad Meyer } 467*9119bafbSConrad Meyer 468*9119bafbSConrad Meyer inline void pcg_mcg_16_step_r(struct pcg_state_16* rng) 469*9119bafbSConrad Meyer { 470*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16; 471*9119bafbSConrad Meyer } 472*9119bafbSConrad Meyer 473*9119bafbSConrad Meyer inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng, uint16_t delta) 474*9119bafbSConrad Meyer { 475*9119bafbSConrad Meyer rng->state 476*9119bafbSConrad Meyer = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 0u); 477*9119bafbSConrad Meyer } 478*9119bafbSConrad Meyer 479*9119bafbSConrad Meyer inline void pcg_unique_16_step_r(struct pcg_state_16* rng) 480*9119bafbSConrad Meyer { 481*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 482*9119bafbSConrad Meyer + (uint16_t)(((intptr_t)rng) | 1u); 483*9119bafbSConrad Meyer } 484*9119bafbSConrad Meyer 485*9119bafbSConrad Meyer inline void pcg_unique_16_advance_r(struct pcg_state_16* rng, uint16_t delta) 486*9119bafbSConrad Meyer { 487*9119bafbSConrad Meyer rng->state 488*9119bafbSConrad Meyer = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 489*9119bafbSConrad Meyer (uint16_t)(((intptr_t)rng) | 1u)); 490*9119bafbSConrad Meyer } 491*9119bafbSConrad Meyer 492*9119bafbSConrad Meyer inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng) 493*9119bafbSConrad Meyer { 494*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + rng->inc; 495*9119bafbSConrad Meyer } 496*9119bafbSConrad Meyer 497*9119bafbSConrad Meyer inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng, 498*9119bafbSConrad Meyer uint16_t delta) 499*9119bafbSConrad Meyer { 500*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_16(rng->state, delta, 501*9119bafbSConrad Meyer PCG_DEFAULT_MULTIPLIER_16, rng->inc); 502*9119bafbSConrad Meyer } 503*9119bafbSConrad Meyer 504*9119bafbSConrad Meyer inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng) 505*9119bafbSConrad Meyer { 506*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 507*9119bafbSConrad Meyer + PCG_DEFAULT_INCREMENT_32; 508*9119bafbSConrad Meyer } 509*9119bafbSConrad Meyer 510*9119bafbSConrad Meyer inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng, uint32_t delta) 511*9119bafbSConrad Meyer { 512*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_32( 513*9119bafbSConrad Meyer rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, PCG_DEFAULT_INCREMENT_32); 514*9119bafbSConrad Meyer } 515*9119bafbSConrad Meyer 516*9119bafbSConrad Meyer inline void pcg_mcg_32_step_r(struct pcg_state_32* rng) 517*9119bafbSConrad Meyer { 518*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32; 519*9119bafbSConrad Meyer } 520*9119bafbSConrad Meyer 521*9119bafbSConrad Meyer inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng, uint32_t delta) 522*9119bafbSConrad Meyer { 523*9119bafbSConrad Meyer rng->state 524*9119bafbSConrad Meyer = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 0u); 525*9119bafbSConrad Meyer } 526*9119bafbSConrad Meyer 527*9119bafbSConrad Meyer inline void pcg_unique_32_step_r(struct pcg_state_32* rng) 528*9119bafbSConrad Meyer { 529*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 530*9119bafbSConrad Meyer + (uint32_t)(((intptr_t)rng) | 1u); 531*9119bafbSConrad Meyer } 532*9119bafbSConrad Meyer 533*9119bafbSConrad Meyer inline void pcg_unique_32_advance_r(struct pcg_state_32* rng, uint32_t delta) 534*9119bafbSConrad Meyer { 535*9119bafbSConrad Meyer rng->state 536*9119bafbSConrad Meyer = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 537*9119bafbSConrad Meyer (uint32_t)(((intptr_t)rng) | 1u)); 538*9119bafbSConrad Meyer } 539*9119bafbSConrad Meyer 540*9119bafbSConrad Meyer inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng) 541*9119bafbSConrad Meyer { 542*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + rng->inc; 543*9119bafbSConrad Meyer } 544*9119bafbSConrad Meyer 545*9119bafbSConrad Meyer inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng, 546*9119bafbSConrad Meyer uint32_t delta) 547*9119bafbSConrad Meyer { 548*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_32(rng->state, delta, 549*9119bafbSConrad Meyer PCG_DEFAULT_MULTIPLIER_32, rng->inc); 550*9119bafbSConrad Meyer } 551*9119bafbSConrad Meyer 552*9119bafbSConrad Meyer inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng) 553*9119bafbSConrad Meyer { 554*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 555*9119bafbSConrad Meyer + PCG_DEFAULT_INCREMENT_64; 556*9119bafbSConrad Meyer } 557*9119bafbSConrad Meyer 558*9119bafbSConrad Meyer inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng, uint64_t delta) 559*9119bafbSConrad Meyer { 560*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_64( 561*9119bafbSConrad Meyer rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, PCG_DEFAULT_INCREMENT_64); 562*9119bafbSConrad Meyer } 563*9119bafbSConrad Meyer 564*9119bafbSConrad Meyer inline void pcg_mcg_64_step_r(struct pcg_state_64* rng) 565*9119bafbSConrad Meyer { 566*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64; 567*9119bafbSConrad Meyer } 568*9119bafbSConrad Meyer 569*9119bafbSConrad Meyer inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng, uint64_t delta) 570*9119bafbSConrad Meyer { 571*9119bafbSConrad Meyer rng->state 572*9119bafbSConrad Meyer = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 0u); 573*9119bafbSConrad Meyer } 574*9119bafbSConrad Meyer 575*9119bafbSConrad Meyer inline void pcg_unique_64_step_r(struct pcg_state_64* rng) 576*9119bafbSConrad Meyer { 577*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 578*9119bafbSConrad Meyer + (uint64_t)(((intptr_t)rng) | 1u); 579*9119bafbSConrad Meyer } 580*9119bafbSConrad Meyer 581*9119bafbSConrad Meyer inline void pcg_unique_64_advance_r(struct pcg_state_64* rng, uint64_t delta) 582*9119bafbSConrad Meyer { 583*9119bafbSConrad Meyer rng->state 584*9119bafbSConrad Meyer = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 585*9119bafbSConrad Meyer (uint64_t)(((intptr_t)rng) | 1u)); 586*9119bafbSConrad Meyer } 587*9119bafbSConrad Meyer 588*9119bafbSConrad Meyer inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng) 589*9119bafbSConrad Meyer { 590*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc; 591*9119bafbSConrad Meyer } 592*9119bafbSConrad Meyer 593*9119bafbSConrad Meyer inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng, 594*9119bafbSConrad Meyer uint64_t delta) 595*9119bafbSConrad Meyer { 596*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_64(rng->state, delta, 597*9119bafbSConrad Meyer PCG_DEFAULT_MULTIPLIER_64, rng->inc); 598*9119bafbSConrad Meyer } 599*9119bafbSConrad Meyer 600*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 601*9119bafbSConrad Meyer inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng) 602*9119bafbSConrad Meyer { 603*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 604*9119bafbSConrad Meyer + PCG_DEFAULT_INCREMENT_128; 605*9119bafbSConrad Meyer } 606*9119bafbSConrad Meyer #endif 607*9119bafbSConrad Meyer 608*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 609*9119bafbSConrad Meyer inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) 610*9119bafbSConrad Meyer { 611*9119bafbSConrad Meyer rng->state 612*9119bafbSConrad Meyer = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, 613*9119bafbSConrad Meyer PCG_DEFAULT_INCREMENT_128); 614*9119bafbSConrad Meyer } 615*9119bafbSConrad Meyer #endif 616*9119bafbSConrad Meyer 617*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 618*9119bafbSConrad Meyer inline void pcg_mcg_128_step_r(struct pcg_state_128* rng) 619*9119bafbSConrad Meyer { 620*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128; 621*9119bafbSConrad Meyer } 622*9119bafbSConrad Meyer #endif 623*9119bafbSConrad Meyer 624*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 625*9119bafbSConrad Meyer inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) 626*9119bafbSConrad Meyer { 627*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_128(rng->state, delta, 628*9119bafbSConrad Meyer PCG_DEFAULT_MULTIPLIER_128, 0u); 629*9119bafbSConrad Meyer } 630*9119bafbSConrad Meyer #endif 631*9119bafbSConrad Meyer 632*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 633*9119bafbSConrad Meyer inline void pcg_unique_128_step_r(struct pcg_state_128* rng) 634*9119bafbSConrad Meyer { 635*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 636*9119bafbSConrad Meyer + (pcg128_t)(((intptr_t)rng) | 1u); 637*9119bafbSConrad Meyer } 638*9119bafbSConrad Meyer #endif 639*9119bafbSConrad Meyer 640*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 641*9119bafbSConrad Meyer inline void pcg_unique_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) 642*9119bafbSConrad Meyer { 643*9119bafbSConrad Meyer rng->state 644*9119bafbSConrad Meyer = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, 645*9119bafbSConrad Meyer (pcg128_t)(((intptr_t)rng) | 1u)); 646*9119bafbSConrad Meyer } 647*9119bafbSConrad Meyer #endif 648*9119bafbSConrad Meyer 649*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 650*9119bafbSConrad Meyer inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng) 651*9119bafbSConrad Meyer { 652*9119bafbSConrad Meyer rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc; 653*9119bafbSConrad Meyer } 654*9119bafbSConrad Meyer #endif 655*9119bafbSConrad Meyer 656*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 657*9119bafbSConrad Meyer inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng, 658*9119bafbSConrad Meyer pcg128_t delta) 659*9119bafbSConrad Meyer { 660*9119bafbSConrad Meyer rng->state = pcg_advance_lcg_128(rng->state, delta, 661*9119bafbSConrad Meyer PCG_DEFAULT_MULTIPLIER_128, rng->inc); 662*9119bafbSConrad Meyer } 663*9119bafbSConrad Meyer #endif 664*9119bafbSConrad Meyer 665*9119bafbSConrad Meyer /* Functions to seed the RNG state, one version for each size and each 666*9119bafbSConrad Meyer * style. Unlike the step functions, regular users can and should call 667*9119bafbSConrad Meyer * these functions. 668*9119bafbSConrad Meyer */ 669*9119bafbSConrad Meyer 670*9119bafbSConrad Meyer inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) 671*9119bafbSConrad Meyer { 672*9119bafbSConrad Meyer rng->state = 0U; 673*9119bafbSConrad Meyer pcg_oneseq_8_step_r(rng); 674*9119bafbSConrad Meyer rng->state += initstate; 675*9119bafbSConrad Meyer pcg_oneseq_8_step_r(rng); 676*9119bafbSConrad Meyer } 677*9119bafbSConrad Meyer 678*9119bafbSConrad Meyer inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) 679*9119bafbSConrad Meyer { 680*9119bafbSConrad Meyer rng->state = initstate | 1u; 681*9119bafbSConrad Meyer } 682*9119bafbSConrad Meyer 683*9119bafbSConrad Meyer inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) 684*9119bafbSConrad Meyer { 685*9119bafbSConrad Meyer rng->state = 0U; 686*9119bafbSConrad Meyer pcg_unique_8_step_r(rng); 687*9119bafbSConrad Meyer rng->state += initstate; 688*9119bafbSConrad Meyer pcg_unique_8_step_r(rng); 689*9119bafbSConrad Meyer } 690*9119bafbSConrad Meyer 691*9119bafbSConrad Meyer inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng, 692*9119bafbSConrad Meyer uint8_t initstate, uint8_t initseq) 693*9119bafbSConrad Meyer { 694*9119bafbSConrad Meyer rng->state = 0U; 695*9119bafbSConrad Meyer rng->inc = (initseq << 1u) | 1u; 696*9119bafbSConrad Meyer pcg_setseq_8_step_r(rng); 697*9119bafbSConrad Meyer rng->state += initstate; 698*9119bafbSConrad Meyer pcg_setseq_8_step_r(rng); 699*9119bafbSConrad Meyer } 700*9119bafbSConrad Meyer 701*9119bafbSConrad Meyer inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng, 702*9119bafbSConrad Meyer uint16_t initstate) 703*9119bafbSConrad Meyer { 704*9119bafbSConrad Meyer rng->state = 0U; 705*9119bafbSConrad Meyer pcg_oneseq_16_step_r(rng); 706*9119bafbSConrad Meyer rng->state += initstate; 707*9119bafbSConrad Meyer pcg_oneseq_16_step_r(rng); 708*9119bafbSConrad Meyer } 709*9119bafbSConrad Meyer 710*9119bafbSConrad Meyer inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng, uint16_t initstate) 711*9119bafbSConrad Meyer { 712*9119bafbSConrad Meyer rng->state = initstate | 1u; 713*9119bafbSConrad Meyer } 714*9119bafbSConrad Meyer 715*9119bafbSConrad Meyer inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng, 716*9119bafbSConrad Meyer uint16_t initstate) 717*9119bafbSConrad Meyer { 718*9119bafbSConrad Meyer rng->state = 0U; 719*9119bafbSConrad Meyer pcg_unique_16_step_r(rng); 720*9119bafbSConrad Meyer rng->state += initstate; 721*9119bafbSConrad Meyer pcg_unique_16_step_r(rng); 722*9119bafbSConrad Meyer } 723*9119bafbSConrad Meyer 724*9119bafbSConrad Meyer inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng, 725*9119bafbSConrad Meyer uint16_t initstate, uint16_t initseq) 726*9119bafbSConrad Meyer { 727*9119bafbSConrad Meyer rng->state = 0U; 728*9119bafbSConrad Meyer rng->inc = (initseq << 1u) | 1u; 729*9119bafbSConrad Meyer pcg_setseq_16_step_r(rng); 730*9119bafbSConrad Meyer rng->state += initstate; 731*9119bafbSConrad Meyer pcg_setseq_16_step_r(rng); 732*9119bafbSConrad Meyer } 733*9119bafbSConrad Meyer 734*9119bafbSConrad Meyer inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng, 735*9119bafbSConrad Meyer uint32_t initstate) 736*9119bafbSConrad Meyer { 737*9119bafbSConrad Meyer rng->state = 0U; 738*9119bafbSConrad Meyer pcg_oneseq_32_step_r(rng); 739*9119bafbSConrad Meyer rng->state += initstate; 740*9119bafbSConrad Meyer pcg_oneseq_32_step_r(rng); 741*9119bafbSConrad Meyer } 742*9119bafbSConrad Meyer 743*9119bafbSConrad Meyer inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng, uint32_t initstate) 744*9119bafbSConrad Meyer { 745*9119bafbSConrad Meyer rng->state = initstate | 1u; 746*9119bafbSConrad Meyer } 747*9119bafbSConrad Meyer 748*9119bafbSConrad Meyer inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng, 749*9119bafbSConrad Meyer uint32_t initstate) 750*9119bafbSConrad Meyer { 751*9119bafbSConrad Meyer rng->state = 0U; 752*9119bafbSConrad Meyer pcg_unique_32_step_r(rng); 753*9119bafbSConrad Meyer rng->state += initstate; 754*9119bafbSConrad Meyer pcg_unique_32_step_r(rng); 755*9119bafbSConrad Meyer } 756*9119bafbSConrad Meyer 757*9119bafbSConrad Meyer inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng, 758*9119bafbSConrad Meyer uint32_t initstate, uint32_t initseq) 759*9119bafbSConrad Meyer { 760*9119bafbSConrad Meyer rng->state = 0U; 761*9119bafbSConrad Meyer rng->inc = (initseq << 1u) | 1u; 762*9119bafbSConrad Meyer pcg_setseq_32_step_r(rng); 763*9119bafbSConrad Meyer rng->state += initstate; 764*9119bafbSConrad Meyer pcg_setseq_32_step_r(rng); 765*9119bafbSConrad Meyer } 766*9119bafbSConrad Meyer 767*9119bafbSConrad Meyer inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng, 768*9119bafbSConrad Meyer uint64_t initstate) 769*9119bafbSConrad Meyer { 770*9119bafbSConrad Meyer rng->state = 0U; 771*9119bafbSConrad Meyer pcg_oneseq_64_step_r(rng); 772*9119bafbSConrad Meyer rng->state += initstate; 773*9119bafbSConrad Meyer pcg_oneseq_64_step_r(rng); 774*9119bafbSConrad Meyer } 775*9119bafbSConrad Meyer 776*9119bafbSConrad Meyer inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng, uint64_t initstate) 777*9119bafbSConrad Meyer { 778*9119bafbSConrad Meyer rng->state = initstate | 1u; 779*9119bafbSConrad Meyer } 780*9119bafbSConrad Meyer 781*9119bafbSConrad Meyer inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng, 782*9119bafbSConrad Meyer uint64_t initstate) 783*9119bafbSConrad Meyer { 784*9119bafbSConrad Meyer rng->state = 0U; 785*9119bafbSConrad Meyer pcg_unique_64_step_r(rng); 786*9119bafbSConrad Meyer rng->state += initstate; 787*9119bafbSConrad Meyer pcg_unique_64_step_r(rng); 788*9119bafbSConrad Meyer } 789*9119bafbSConrad Meyer 790*9119bafbSConrad Meyer inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng, 791*9119bafbSConrad Meyer uint64_t initstate, uint64_t initseq) 792*9119bafbSConrad Meyer { 793*9119bafbSConrad Meyer rng->state = 0U; 794*9119bafbSConrad Meyer rng->inc = (initseq << 1u) | 1u; 795*9119bafbSConrad Meyer pcg_setseq_64_step_r(rng); 796*9119bafbSConrad Meyer rng->state += initstate; 797*9119bafbSConrad Meyer pcg_setseq_64_step_r(rng); 798*9119bafbSConrad Meyer } 799*9119bafbSConrad Meyer 800*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 801*9119bafbSConrad Meyer inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng, 802*9119bafbSConrad Meyer pcg128_t initstate) 803*9119bafbSConrad Meyer { 804*9119bafbSConrad Meyer rng->state = 0U; 805*9119bafbSConrad Meyer pcg_oneseq_128_step_r(rng); 806*9119bafbSConrad Meyer rng->state += initstate; 807*9119bafbSConrad Meyer pcg_oneseq_128_step_r(rng); 808*9119bafbSConrad Meyer } 809*9119bafbSConrad Meyer #endif 810*9119bafbSConrad Meyer 811*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 812*9119bafbSConrad Meyer inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng, pcg128_t initstate) 813*9119bafbSConrad Meyer { 814*9119bafbSConrad Meyer rng->state = initstate | 1u; 815*9119bafbSConrad Meyer } 816*9119bafbSConrad Meyer #endif 817*9119bafbSConrad Meyer 818*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 819*9119bafbSConrad Meyer inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng, 820*9119bafbSConrad Meyer pcg128_t initstate) 821*9119bafbSConrad Meyer { 822*9119bafbSConrad Meyer rng->state = 0U; 823*9119bafbSConrad Meyer pcg_unique_128_step_r(rng); 824*9119bafbSConrad Meyer rng->state += initstate; 825*9119bafbSConrad Meyer pcg_unique_128_step_r(rng); 826*9119bafbSConrad Meyer } 827*9119bafbSConrad Meyer #endif 828*9119bafbSConrad Meyer 829*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 830*9119bafbSConrad Meyer inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng, 831*9119bafbSConrad Meyer pcg128_t initstate, pcg128_t initseq) 832*9119bafbSConrad Meyer { 833*9119bafbSConrad Meyer rng->state = 0U; 834*9119bafbSConrad Meyer rng->inc = (initseq << 1u) | 1u; 835*9119bafbSConrad Meyer pcg_setseq_128_step_r(rng); 836*9119bafbSConrad Meyer rng->state += initstate; 837*9119bafbSConrad Meyer pcg_setseq_128_step_r(rng); 838*9119bafbSConrad Meyer } 839*9119bafbSConrad Meyer #endif 840*9119bafbSConrad Meyer 841*9119bafbSConrad Meyer /* Now, finally we create each of the individual generators. We provide 842*9119bafbSConrad Meyer * a random_r function that provides a random number of the appropriate 843*9119bafbSConrad Meyer * type (using the full range of the type) and a boundedrand_r version 844*9119bafbSConrad Meyer * that provides 845*9119bafbSConrad Meyer * 846*9119bafbSConrad Meyer * Implementation notes for boundedrand_r: 847*9119bafbSConrad Meyer * 848*9119bafbSConrad Meyer * To avoid bias, we need to make the range of the RNG a multiple of 849*9119bafbSConrad Meyer * bound, which we do by dropping output less than a threshold. 850*9119bafbSConrad Meyer * Let's consider a 32-bit case... A naive scheme to calculate the 851*9119bafbSConrad Meyer * threshold would be to do 852*9119bafbSConrad Meyer * 853*9119bafbSConrad Meyer * uint32_t threshold = 0x100000000ull % bound; 854*9119bafbSConrad Meyer * 855*9119bafbSConrad Meyer * but 64-bit div/mod is slower than 32-bit div/mod (especially on 856*9119bafbSConrad Meyer * 32-bit platforms). In essence, we do 857*9119bafbSConrad Meyer * 858*9119bafbSConrad Meyer * uint32_t threshold = (0x100000000ull-bound) % bound; 859*9119bafbSConrad Meyer * 860*9119bafbSConrad Meyer * because this version will calculate the same modulus, but the LHS 861*9119bafbSConrad Meyer * value is less than 2^32. 862*9119bafbSConrad Meyer * 863*9119bafbSConrad Meyer * (Note that using modulo is only wise for good RNGs, poorer RNGs 864*9119bafbSConrad Meyer * such as raw LCGs do better using a technique based on division.) 865*9119bafbSConrad Meyer * Empricical tests show that division is preferable to modulus for 866*9119bafbSConrad Meyer * reducting the range of an RNG. It's faster, and sometimes it can 867*9119bafbSConrad Meyer * even be statistically prefereable. 868*9119bafbSConrad Meyer */ 869*9119bafbSConrad Meyer 870*9119bafbSConrad Meyer /* Generation functions for XSH RS */ 871*9119bafbSConrad Meyer 872*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng) 873*9119bafbSConrad Meyer { 874*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 875*9119bafbSConrad Meyer pcg_oneseq_16_step_r(rng); 876*9119bafbSConrad Meyer return pcg_output_xsh_rs_16_8(oldstate); 877*9119bafbSConrad Meyer } 878*9119bafbSConrad Meyer 879*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, 880*9119bafbSConrad Meyer uint8_t bound) 881*9119bafbSConrad Meyer { 882*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 883*9119bafbSConrad Meyer for (;;) { 884*9119bafbSConrad Meyer uint8_t r = pcg_oneseq_16_xsh_rs_8_random_r(rng); 885*9119bafbSConrad Meyer if (r >= threshold) 886*9119bafbSConrad Meyer return r % bound; 887*9119bafbSConrad Meyer } 888*9119bafbSConrad Meyer } 889*9119bafbSConrad Meyer 890*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng) 891*9119bafbSConrad Meyer { 892*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 893*9119bafbSConrad Meyer pcg_oneseq_32_step_r(rng); 894*9119bafbSConrad Meyer return pcg_output_xsh_rs_32_16(oldstate); 895*9119bafbSConrad Meyer } 896*9119bafbSConrad Meyer 897*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, 898*9119bafbSConrad Meyer uint16_t bound) 899*9119bafbSConrad Meyer { 900*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 901*9119bafbSConrad Meyer for (;;) { 902*9119bafbSConrad Meyer uint16_t r = pcg_oneseq_32_xsh_rs_16_random_r(rng); 903*9119bafbSConrad Meyer if (r >= threshold) 904*9119bafbSConrad Meyer return r % bound; 905*9119bafbSConrad Meyer } 906*9119bafbSConrad Meyer } 907*9119bafbSConrad Meyer 908*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng) 909*9119bafbSConrad Meyer { 910*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 911*9119bafbSConrad Meyer pcg_oneseq_64_step_r(rng); 912*9119bafbSConrad Meyer return pcg_output_xsh_rs_64_32(oldstate); 913*9119bafbSConrad Meyer } 914*9119bafbSConrad Meyer 915*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, 916*9119bafbSConrad Meyer uint32_t bound) 917*9119bafbSConrad Meyer { 918*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 919*9119bafbSConrad Meyer for (;;) { 920*9119bafbSConrad Meyer uint32_t r = pcg_oneseq_64_xsh_rs_32_random_r(rng); 921*9119bafbSConrad Meyer if (r >= threshold) 922*9119bafbSConrad Meyer return r % bound; 923*9119bafbSConrad Meyer } 924*9119bafbSConrad Meyer } 925*9119bafbSConrad Meyer 926*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 927*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng) 928*9119bafbSConrad Meyer { 929*9119bafbSConrad Meyer pcg_oneseq_128_step_r(rng); 930*9119bafbSConrad Meyer return pcg_output_xsh_rs_128_64(rng->state); 931*9119bafbSConrad Meyer } 932*9119bafbSConrad Meyer #endif 933*9119bafbSConrad Meyer 934*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 935*9119bafbSConrad Meyer inline uint64_t 936*9119bafbSConrad Meyer pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, 937*9119bafbSConrad Meyer uint64_t bound) 938*9119bafbSConrad Meyer { 939*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 940*9119bafbSConrad Meyer for (;;) { 941*9119bafbSConrad Meyer uint64_t r = pcg_oneseq_128_xsh_rs_64_random_r(rng); 942*9119bafbSConrad Meyer if (r >= threshold) 943*9119bafbSConrad Meyer return r % bound; 944*9119bafbSConrad Meyer } 945*9119bafbSConrad Meyer } 946*9119bafbSConrad Meyer #endif 947*9119bafbSConrad Meyer 948*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng) 949*9119bafbSConrad Meyer { 950*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 951*9119bafbSConrad Meyer pcg_unique_16_step_r(rng); 952*9119bafbSConrad Meyer return pcg_output_xsh_rs_16_8(oldstate); 953*9119bafbSConrad Meyer } 954*9119bafbSConrad Meyer 955*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, 956*9119bafbSConrad Meyer uint8_t bound) 957*9119bafbSConrad Meyer { 958*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 959*9119bafbSConrad Meyer for (;;) { 960*9119bafbSConrad Meyer uint8_t r = pcg_unique_16_xsh_rs_8_random_r(rng); 961*9119bafbSConrad Meyer if (r >= threshold) 962*9119bafbSConrad Meyer return r % bound; 963*9119bafbSConrad Meyer } 964*9119bafbSConrad Meyer } 965*9119bafbSConrad Meyer 966*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng) 967*9119bafbSConrad Meyer { 968*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 969*9119bafbSConrad Meyer pcg_unique_32_step_r(rng); 970*9119bafbSConrad Meyer return pcg_output_xsh_rs_32_16(oldstate); 971*9119bafbSConrad Meyer } 972*9119bafbSConrad Meyer 973*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, 974*9119bafbSConrad Meyer uint16_t bound) 975*9119bafbSConrad Meyer { 976*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 977*9119bafbSConrad Meyer for (;;) { 978*9119bafbSConrad Meyer uint16_t r = pcg_unique_32_xsh_rs_16_random_r(rng); 979*9119bafbSConrad Meyer if (r >= threshold) 980*9119bafbSConrad Meyer return r % bound; 981*9119bafbSConrad Meyer } 982*9119bafbSConrad Meyer } 983*9119bafbSConrad Meyer 984*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng) 985*9119bafbSConrad Meyer { 986*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 987*9119bafbSConrad Meyer pcg_unique_64_step_r(rng); 988*9119bafbSConrad Meyer return pcg_output_xsh_rs_64_32(oldstate); 989*9119bafbSConrad Meyer } 990*9119bafbSConrad Meyer 991*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, 992*9119bafbSConrad Meyer uint32_t bound) 993*9119bafbSConrad Meyer { 994*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 995*9119bafbSConrad Meyer for (;;) { 996*9119bafbSConrad Meyer uint32_t r = pcg_unique_64_xsh_rs_32_random_r(rng); 997*9119bafbSConrad Meyer if (r >= threshold) 998*9119bafbSConrad Meyer return r % bound; 999*9119bafbSConrad Meyer } 1000*9119bafbSConrad Meyer } 1001*9119bafbSConrad Meyer 1002*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1003*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng) 1004*9119bafbSConrad Meyer { 1005*9119bafbSConrad Meyer pcg_unique_128_step_r(rng); 1006*9119bafbSConrad Meyer return pcg_output_xsh_rs_128_64(rng->state); 1007*9119bafbSConrad Meyer } 1008*9119bafbSConrad Meyer #endif 1009*9119bafbSConrad Meyer 1010*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1011*9119bafbSConrad Meyer inline uint64_t 1012*9119bafbSConrad Meyer pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, 1013*9119bafbSConrad Meyer uint64_t bound) 1014*9119bafbSConrad Meyer { 1015*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1016*9119bafbSConrad Meyer for (;;) { 1017*9119bafbSConrad Meyer uint64_t r = pcg_unique_128_xsh_rs_64_random_r(rng); 1018*9119bafbSConrad Meyer if (r >= threshold) 1019*9119bafbSConrad Meyer return r % bound; 1020*9119bafbSConrad Meyer } 1021*9119bafbSConrad Meyer } 1022*9119bafbSConrad Meyer #endif 1023*9119bafbSConrad Meyer 1024*9119bafbSConrad Meyer inline uint8_t pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng) 1025*9119bafbSConrad Meyer { 1026*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1027*9119bafbSConrad Meyer pcg_setseq_16_step_r(rng); 1028*9119bafbSConrad Meyer return pcg_output_xsh_rs_16_8(oldstate); 1029*9119bafbSConrad Meyer } 1030*9119bafbSConrad Meyer 1031*9119bafbSConrad Meyer inline uint8_t 1032*9119bafbSConrad Meyer pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng, 1033*9119bafbSConrad Meyer uint8_t bound) 1034*9119bafbSConrad Meyer { 1035*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1036*9119bafbSConrad Meyer for (;;) { 1037*9119bafbSConrad Meyer uint8_t r = pcg_setseq_16_xsh_rs_8_random_r(rng); 1038*9119bafbSConrad Meyer if (r >= threshold) 1039*9119bafbSConrad Meyer return r % bound; 1040*9119bafbSConrad Meyer } 1041*9119bafbSConrad Meyer } 1042*9119bafbSConrad Meyer 1043*9119bafbSConrad Meyer inline uint16_t 1044*9119bafbSConrad Meyer pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng) 1045*9119bafbSConrad Meyer { 1046*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1047*9119bafbSConrad Meyer pcg_setseq_32_step_r(rng); 1048*9119bafbSConrad Meyer return pcg_output_xsh_rs_32_16(oldstate); 1049*9119bafbSConrad Meyer } 1050*9119bafbSConrad Meyer 1051*9119bafbSConrad Meyer inline uint16_t 1052*9119bafbSConrad Meyer pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng, 1053*9119bafbSConrad Meyer uint16_t bound) 1054*9119bafbSConrad Meyer { 1055*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1056*9119bafbSConrad Meyer for (;;) { 1057*9119bafbSConrad Meyer uint16_t r = pcg_setseq_32_xsh_rs_16_random_r(rng); 1058*9119bafbSConrad Meyer if (r >= threshold) 1059*9119bafbSConrad Meyer return r % bound; 1060*9119bafbSConrad Meyer } 1061*9119bafbSConrad Meyer } 1062*9119bafbSConrad Meyer 1063*9119bafbSConrad Meyer inline uint32_t 1064*9119bafbSConrad Meyer pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng) 1065*9119bafbSConrad Meyer { 1066*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1067*9119bafbSConrad Meyer pcg_setseq_64_step_r(rng); 1068*9119bafbSConrad Meyer return pcg_output_xsh_rs_64_32(oldstate); 1069*9119bafbSConrad Meyer } 1070*9119bafbSConrad Meyer 1071*9119bafbSConrad Meyer inline uint32_t 1072*9119bafbSConrad Meyer pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng, 1073*9119bafbSConrad Meyer uint32_t bound) 1074*9119bafbSConrad Meyer { 1075*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1076*9119bafbSConrad Meyer for (;;) { 1077*9119bafbSConrad Meyer uint32_t r = pcg_setseq_64_xsh_rs_32_random_r(rng); 1078*9119bafbSConrad Meyer if (r >= threshold) 1079*9119bafbSConrad Meyer return r % bound; 1080*9119bafbSConrad Meyer } 1081*9119bafbSConrad Meyer } 1082*9119bafbSConrad Meyer 1083*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1084*9119bafbSConrad Meyer inline uint64_t 1085*9119bafbSConrad Meyer pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng) 1086*9119bafbSConrad Meyer { 1087*9119bafbSConrad Meyer pcg_setseq_128_step_r(rng); 1088*9119bafbSConrad Meyer return pcg_output_xsh_rs_128_64(rng->state); 1089*9119bafbSConrad Meyer } 1090*9119bafbSConrad Meyer #endif 1091*9119bafbSConrad Meyer 1092*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1093*9119bafbSConrad Meyer inline uint64_t 1094*9119bafbSConrad Meyer pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng, 1095*9119bafbSConrad Meyer uint64_t bound) 1096*9119bafbSConrad Meyer { 1097*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1098*9119bafbSConrad Meyer for (;;) { 1099*9119bafbSConrad Meyer uint64_t r = pcg_setseq_128_xsh_rs_64_random_r(rng); 1100*9119bafbSConrad Meyer if (r >= threshold) 1101*9119bafbSConrad Meyer return r % bound; 1102*9119bafbSConrad Meyer } 1103*9119bafbSConrad Meyer } 1104*9119bafbSConrad Meyer #endif 1105*9119bafbSConrad Meyer 1106*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng) 1107*9119bafbSConrad Meyer { 1108*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1109*9119bafbSConrad Meyer pcg_mcg_16_step_r(rng); 1110*9119bafbSConrad Meyer return pcg_output_xsh_rs_16_8(oldstate); 1111*9119bafbSConrad Meyer } 1112*9119bafbSConrad Meyer 1113*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, 1114*9119bafbSConrad Meyer uint8_t bound) 1115*9119bafbSConrad Meyer { 1116*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1117*9119bafbSConrad Meyer for (;;) { 1118*9119bafbSConrad Meyer uint8_t r = pcg_mcg_16_xsh_rs_8_random_r(rng); 1119*9119bafbSConrad Meyer if (r >= threshold) 1120*9119bafbSConrad Meyer return r % bound; 1121*9119bafbSConrad Meyer } 1122*9119bafbSConrad Meyer } 1123*9119bafbSConrad Meyer 1124*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng) 1125*9119bafbSConrad Meyer { 1126*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1127*9119bafbSConrad Meyer pcg_mcg_32_step_r(rng); 1128*9119bafbSConrad Meyer return pcg_output_xsh_rs_32_16(oldstate); 1129*9119bafbSConrad Meyer } 1130*9119bafbSConrad Meyer 1131*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, 1132*9119bafbSConrad Meyer uint16_t bound) 1133*9119bafbSConrad Meyer { 1134*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1135*9119bafbSConrad Meyer for (;;) { 1136*9119bafbSConrad Meyer uint16_t r = pcg_mcg_32_xsh_rs_16_random_r(rng); 1137*9119bafbSConrad Meyer if (r >= threshold) 1138*9119bafbSConrad Meyer return r % bound; 1139*9119bafbSConrad Meyer } 1140*9119bafbSConrad Meyer } 1141*9119bafbSConrad Meyer 1142*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng) 1143*9119bafbSConrad Meyer { 1144*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1145*9119bafbSConrad Meyer pcg_mcg_64_step_r(rng); 1146*9119bafbSConrad Meyer return pcg_output_xsh_rs_64_32(oldstate); 1147*9119bafbSConrad Meyer } 1148*9119bafbSConrad Meyer 1149*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, 1150*9119bafbSConrad Meyer uint32_t bound) 1151*9119bafbSConrad Meyer { 1152*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1153*9119bafbSConrad Meyer for (;;) { 1154*9119bafbSConrad Meyer uint32_t r = pcg_mcg_64_xsh_rs_32_random_r(rng); 1155*9119bafbSConrad Meyer if (r >= threshold) 1156*9119bafbSConrad Meyer return r % bound; 1157*9119bafbSConrad Meyer } 1158*9119bafbSConrad Meyer } 1159*9119bafbSConrad Meyer 1160*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1161*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng) 1162*9119bafbSConrad Meyer { 1163*9119bafbSConrad Meyer pcg_mcg_128_step_r(rng); 1164*9119bafbSConrad Meyer return pcg_output_xsh_rs_128_64(rng->state); 1165*9119bafbSConrad Meyer } 1166*9119bafbSConrad Meyer #endif 1167*9119bafbSConrad Meyer 1168*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1169*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, 1170*9119bafbSConrad Meyer uint64_t bound) 1171*9119bafbSConrad Meyer { 1172*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1173*9119bafbSConrad Meyer for (;;) { 1174*9119bafbSConrad Meyer uint64_t r = pcg_mcg_128_xsh_rs_64_random_r(rng); 1175*9119bafbSConrad Meyer if (r >= threshold) 1176*9119bafbSConrad Meyer return r % bound; 1177*9119bafbSConrad Meyer } 1178*9119bafbSConrad Meyer } 1179*9119bafbSConrad Meyer #endif 1180*9119bafbSConrad Meyer 1181*9119bafbSConrad Meyer /* Generation functions for XSH RR */ 1182*9119bafbSConrad Meyer 1183*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng) 1184*9119bafbSConrad Meyer { 1185*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1186*9119bafbSConrad Meyer pcg_oneseq_16_step_r(rng); 1187*9119bafbSConrad Meyer return pcg_output_xsh_rr_16_8(oldstate); 1188*9119bafbSConrad Meyer } 1189*9119bafbSConrad Meyer 1190*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, 1191*9119bafbSConrad Meyer uint8_t bound) 1192*9119bafbSConrad Meyer { 1193*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1194*9119bafbSConrad Meyer for (;;) { 1195*9119bafbSConrad Meyer uint8_t r = pcg_oneseq_16_xsh_rr_8_random_r(rng); 1196*9119bafbSConrad Meyer if (r >= threshold) 1197*9119bafbSConrad Meyer return r % bound; 1198*9119bafbSConrad Meyer } 1199*9119bafbSConrad Meyer } 1200*9119bafbSConrad Meyer 1201*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng) 1202*9119bafbSConrad Meyer { 1203*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1204*9119bafbSConrad Meyer pcg_oneseq_32_step_r(rng); 1205*9119bafbSConrad Meyer return pcg_output_xsh_rr_32_16(oldstate); 1206*9119bafbSConrad Meyer } 1207*9119bafbSConrad Meyer 1208*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, 1209*9119bafbSConrad Meyer uint16_t bound) 1210*9119bafbSConrad Meyer { 1211*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1212*9119bafbSConrad Meyer for (;;) { 1213*9119bafbSConrad Meyer uint16_t r = pcg_oneseq_32_xsh_rr_16_random_r(rng); 1214*9119bafbSConrad Meyer if (r >= threshold) 1215*9119bafbSConrad Meyer return r % bound; 1216*9119bafbSConrad Meyer } 1217*9119bafbSConrad Meyer } 1218*9119bafbSConrad Meyer 1219*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng) 1220*9119bafbSConrad Meyer { 1221*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1222*9119bafbSConrad Meyer pcg_oneseq_64_step_r(rng); 1223*9119bafbSConrad Meyer return pcg_output_xsh_rr_64_32(oldstate); 1224*9119bafbSConrad Meyer } 1225*9119bafbSConrad Meyer 1226*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, 1227*9119bafbSConrad Meyer uint32_t bound) 1228*9119bafbSConrad Meyer { 1229*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1230*9119bafbSConrad Meyer for (;;) { 1231*9119bafbSConrad Meyer uint32_t r = pcg_oneseq_64_xsh_rr_32_random_r(rng); 1232*9119bafbSConrad Meyer if (r >= threshold) 1233*9119bafbSConrad Meyer return r % bound; 1234*9119bafbSConrad Meyer } 1235*9119bafbSConrad Meyer } 1236*9119bafbSConrad Meyer 1237*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1238*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng) 1239*9119bafbSConrad Meyer { 1240*9119bafbSConrad Meyer pcg_oneseq_128_step_r(rng); 1241*9119bafbSConrad Meyer return pcg_output_xsh_rr_128_64(rng->state); 1242*9119bafbSConrad Meyer } 1243*9119bafbSConrad Meyer #endif 1244*9119bafbSConrad Meyer 1245*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1246*9119bafbSConrad Meyer inline uint64_t 1247*9119bafbSConrad Meyer pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, 1248*9119bafbSConrad Meyer uint64_t bound) 1249*9119bafbSConrad Meyer { 1250*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1251*9119bafbSConrad Meyer for (;;) { 1252*9119bafbSConrad Meyer uint64_t r = pcg_oneseq_128_xsh_rr_64_random_r(rng); 1253*9119bafbSConrad Meyer if (r >= threshold) 1254*9119bafbSConrad Meyer return r % bound; 1255*9119bafbSConrad Meyer } 1256*9119bafbSConrad Meyer } 1257*9119bafbSConrad Meyer #endif 1258*9119bafbSConrad Meyer 1259*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng) 1260*9119bafbSConrad Meyer { 1261*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1262*9119bafbSConrad Meyer pcg_unique_16_step_r(rng); 1263*9119bafbSConrad Meyer return pcg_output_xsh_rr_16_8(oldstate); 1264*9119bafbSConrad Meyer } 1265*9119bafbSConrad Meyer 1266*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, 1267*9119bafbSConrad Meyer uint8_t bound) 1268*9119bafbSConrad Meyer { 1269*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1270*9119bafbSConrad Meyer for (;;) { 1271*9119bafbSConrad Meyer uint8_t r = pcg_unique_16_xsh_rr_8_random_r(rng); 1272*9119bafbSConrad Meyer if (r >= threshold) 1273*9119bafbSConrad Meyer return r % bound; 1274*9119bafbSConrad Meyer } 1275*9119bafbSConrad Meyer } 1276*9119bafbSConrad Meyer 1277*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng) 1278*9119bafbSConrad Meyer { 1279*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1280*9119bafbSConrad Meyer pcg_unique_32_step_r(rng); 1281*9119bafbSConrad Meyer return pcg_output_xsh_rr_32_16(oldstate); 1282*9119bafbSConrad Meyer } 1283*9119bafbSConrad Meyer 1284*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, 1285*9119bafbSConrad Meyer uint16_t bound) 1286*9119bafbSConrad Meyer { 1287*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1288*9119bafbSConrad Meyer for (;;) { 1289*9119bafbSConrad Meyer uint16_t r = pcg_unique_32_xsh_rr_16_random_r(rng); 1290*9119bafbSConrad Meyer if (r >= threshold) 1291*9119bafbSConrad Meyer return r % bound; 1292*9119bafbSConrad Meyer } 1293*9119bafbSConrad Meyer } 1294*9119bafbSConrad Meyer 1295*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng) 1296*9119bafbSConrad Meyer { 1297*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1298*9119bafbSConrad Meyer pcg_unique_64_step_r(rng); 1299*9119bafbSConrad Meyer return pcg_output_xsh_rr_64_32(oldstate); 1300*9119bafbSConrad Meyer } 1301*9119bafbSConrad Meyer 1302*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, 1303*9119bafbSConrad Meyer uint32_t bound) 1304*9119bafbSConrad Meyer { 1305*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1306*9119bafbSConrad Meyer for (;;) { 1307*9119bafbSConrad Meyer uint32_t r = pcg_unique_64_xsh_rr_32_random_r(rng); 1308*9119bafbSConrad Meyer if (r >= threshold) 1309*9119bafbSConrad Meyer return r % bound; 1310*9119bafbSConrad Meyer } 1311*9119bafbSConrad Meyer } 1312*9119bafbSConrad Meyer 1313*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1314*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng) 1315*9119bafbSConrad Meyer { 1316*9119bafbSConrad Meyer pcg_unique_128_step_r(rng); 1317*9119bafbSConrad Meyer return pcg_output_xsh_rr_128_64(rng->state); 1318*9119bafbSConrad Meyer } 1319*9119bafbSConrad Meyer #endif 1320*9119bafbSConrad Meyer 1321*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1322*9119bafbSConrad Meyer inline uint64_t 1323*9119bafbSConrad Meyer pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, 1324*9119bafbSConrad Meyer uint64_t bound) 1325*9119bafbSConrad Meyer { 1326*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1327*9119bafbSConrad Meyer for (;;) { 1328*9119bafbSConrad Meyer uint64_t r = pcg_unique_128_xsh_rr_64_random_r(rng); 1329*9119bafbSConrad Meyer if (r >= threshold) 1330*9119bafbSConrad Meyer return r % bound; 1331*9119bafbSConrad Meyer } 1332*9119bafbSConrad Meyer } 1333*9119bafbSConrad Meyer #endif 1334*9119bafbSConrad Meyer 1335*9119bafbSConrad Meyer inline uint8_t pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng) 1336*9119bafbSConrad Meyer { 1337*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1338*9119bafbSConrad Meyer pcg_setseq_16_step_r(rng); 1339*9119bafbSConrad Meyer return pcg_output_xsh_rr_16_8(oldstate); 1340*9119bafbSConrad Meyer } 1341*9119bafbSConrad Meyer 1342*9119bafbSConrad Meyer inline uint8_t 1343*9119bafbSConrad Meyer pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng, 1344*9119bafbSConrad Meyer uint8_t bound) 1345*9119bafbSConrad Meyer { 1346*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1347*9119bafbSConrad Meyer for (;;) { 1348*9119bafbSConrad Meyer uint8_t r = pcg_setseq_16_xsh_rr_8_random_r(rng); 1349*9119bafbSConrad Meyer if (r >= threshold) 1350*9119bafbSConrad Meyer return r % bound; 1351*9119bafbSConrad Meyer } 1352*9119bafbSConrad Meyer } 1353*9119bafbSConrad Meyer 1354*9119bafbSConrad Meyer inline uint16_t 1355*9119bafbSConrad Meyer pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng) 1356*9119bafbSConrad Meyer { 1357*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1358*9119bafbSConrad Meyer pcg_setseq_32_step_r(rng); 1359*9119bafbSConrad Meyer return pcg_output_xsh_rr_32_16(oldstate); 1360*9119bafbSConrad Meyer } 1361*9119bafbSConrad Meyer 1362*9119bafbSConrad Meyer inline uint16_t 1363*9119bafbSConrad Meyer pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng, 1364*9119bafbSConrad Meyer uint16_t bound) 1365*9119bafbSConrad Meyer { 1366*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1367*9119bafbSConrad Meyer for (;;) { 1368*9119bafbSConrad Meyer uint16_t r = pcg_setseq_32_xsh_rr_16_random_r(rng); 1369*9119bafbSConrad Meyer if (r >= threshold) 1370*9119bafbSConrad Meyer return r % bound; 1371*9119bafbSConrad Meyer } 1372*9119bafbSConrad Meyer } 1373*9119bafbSConrad Meyer 1374*9119bafbSConrad Meyer inline uint32_t 1375*9119bafbSConrad Meyer pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng) 1376*9119bafbSConrad Meyer { 1377*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1378*9119bafbSConrad Meyer pcg_setseq_64_step_r(rng); 1379*9119bafbSConrad Meyer return pcg_output_xsh_rr_64_32(oldstate); 1380*9119bafbSConrad Meyer } 1381*9119bafbSConrad Meyer 1382*9119bafbSConrad Meyer inline uint32_t 1383*9119bafbSConrad Meyer pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng, 1384*9119bafbSConrad Meyer uint32_t bound) 1385*9119bafbSConrad Meyer { 1386*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1387*9119bafbSConrad Meyer for (;;) { 1388*9119bafbSConrad Meyer uint32_t r = pcg_setseq_64_xsh_rr_32_random_r(rng); 1389*9119bafbSConrad Meyer if (r >= threshold) 1390*9119bafbSConrad Meyer return r % bound; 1391*9119bafbSConrad Meyer } 1392*9119bafbSConrad Meyer } 1393*9119bafbSConrad Meyer 1394*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1395*9119bafbSConrad Meyer inline uint64_t 1396*9119bafbSConrad Meyer pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng) 1397*9119bafbSConrad Meyer { 1398*9119bafbSConrad Meyer pcg_setseq_128_step_r(rng); 1399*9119bafbSConrad Meyer return pcg_output_xsh_rr_128_64(rng->state); 1400*9119bafbSConrad Meyer } 1401*9119bafbSConrad Meyer #endif 1402*9119bafbSConrad Meyer 1403*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1404*9119bafbSConrad Meyer inline uint64_t 1405*9119bafbSConrad Meyer pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng, 1406*9119bafbSConrad Meyer uint64_t bound) 1407*9119bafbSConrad Meyer { 1408*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1409*9119bafbSConrad Meyer for (;;) { 1410*9119bafbSConrad Meyer uint64_t r = pcg_setseq_128_xsh_rr_64_random_r(rng); 1411*9119bafbSConrad Meyer if (r >= threshold) 1412*9119bafbSConrad Meyer return r % bound; 1413*9119bafbSConrad Meyer } 1414*9119bafbSConrad Meyer } 1415*9119bafbSConrad Meyer #endif 1416*9119bafbSConrad Meyer 1417*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng) 1418*9119bafbSConrad Meyer { 1419*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1420*9119bafbSConrad Meyer pcg_mcg_16_step_r(rng); 1421*9119bafbSConrad Meyer return pcg_output_xsh_rr_16_8(oldstate); 1422*9119bafbSConrad Meyer } 1423*9119bafbSConrad Meyer 1424*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, 1425*9119bafbSConrad Meyer uint8_t bound) 1426*9119bafbSConrad Meyer { 1427*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1428*9119bafbSConrad Meyer for (;;) { 1429*9119bafbSConrad Meyer uint8_t r = pcg_mcg_16_xsh_rr_8_random_r(rng); 1430*9119bafbSConrad Meyer if (r >= threshold) 1431*9119bafbSConrad Meyer return r % bound; 1432*9119bafbSConrad Meyer } 1433*9119bafbSConrad Meyer } 1434*9119bafbSConrad Meyer 1435*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng) 1436*9119bafbSConrad Meyer { 1437*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1438*9119bafbSConrad Meyer pcg_mcg_32_step_r(rng); 1439*9119bafbSConrad Meyer return pcg_output_xsh_rr_32_16(oldstate); 1440*9119bafbSConrad Meyer } 1441*9119bafbSConrad Meyer 1442*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, 1443*9119bafbSConrad Meyer uint16_t bound) 1444*9119bafbSConrad Meyer { 1445*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1446*9119bafbSConrad Meyer for (;;) { 1447*9119bafbSConrad Meyer uint16_t r = pcg_mcg_32_xsh_rr_16_random_r(rng); 1448*9119bafbSConrad Meyer if (r >= threshold) 1449*9119bafbSConrad Meyer return r % bound; 1450*9119bafbSConrad Meyer } 1451*9119bafbSConrad Meyer } 1452*9119bafbSConrad Meyer 1453*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng) 1454*9119bafbSConrad Meyer { 1455*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1456*9119bafbSConrad Meyer pcg_mcg_64_step_r(rng); 1457*9119bafbSConrad Meyer return pcg_output_xsh_rr_64_32(oldstate); 1458*9119bafbSConrad Meyer } 1459*9119bafbSConrad Meyer 1460*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, 1461*9119bafbSConrad Meyer uint32_t bound) 1462*9119bafbSConrad Meyer { 1463*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1464*9119bafbSConrad Meyer for (;;) { 1465*9119bafbSConrad Meyer uint32_t r = pcg_mcg_64_xsh_rr_32_random_r(rng); 1466*9119bafbSConrad Meyer if (r >= threshold) 1467*9119bafbSConrad Meyer return r % bound; 1468*9119bafbSConrad Meyer } 1469*9119bafbSConrad Meyer } 1470*9119bafbSConrad Meyer 1471*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1472*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng) 1473*9119bafbSConrad Meyer { 1474*9119bafbSConrad Meyer pcg_mcg_128_step_r(rng); 1475*9119bafbSConrad Meyer return pcg_output_xsh_rr_128_64(rng->state); 1476*9119bafbSConrad Meyer } 1477*9119bafbSConrad Meyer #endif 1478*9119bafbSConrad Meyer 1479*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1480*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, 1481*9119bafbSConrad Meyer uint64_t bound) 1482*9119bafbSConrad Meyer { 1483*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1484*9119bafbSConrad Meyer for (;;) { 1485*9119bafbSConrad Meyer uint64_t r = pcg_mcg_128_xsh_rr_64_random_r(rng); 1486*9119bafbSConrad Meyer if (r >= threshold) 1487*9119bafbSConrad Meyer return r % bound; 1488*9119bafbSConrad Meyer } 1489*9119bafbSConrad Meyer } 1490*9119bafbSConrad Meyer #endif 1491*9119bafbSConrad Meyer 1492*9119bafbSConrad Meyer /* Generation functions for RXS M XS (no MCG versions because they 1493*9119bafbSConrad Meyer * don't make sense when you want to use the entire state) 1494*9119bafbSConrad Meyer */ 1495*9119bafbSConrad Meyer 1496*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng) 1497*9119bafbSConrad Meyer { 1498*9119bafbSConrad Meyer uint8_t oldstate = rng->state; 1499*9119bafbSConrad Meyer pcg_oneseq_8_step_r(rng); 1500*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_8_8(oldstate); 1501*9119bafbSConrad Meyer } 1502*9119bafbSConrad Meyer 1503*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng, 1504*9119bafbSConrad Meyer uint8_t bound) 1505*9119bafbSConrad Meyer { 1506*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1507*9119bafbSConrad Meyer for (;;) { 1508*9119bafbSConrad Meyer uint8_t r = pcg_oneseq_8_rxs_m_xs_8_random_r(rng); 1509*9119bafbSConrad Meyer if (r >= threshold) 1510*9119bafbSConrad Meyer return r % bound; 1511*9119bafbSConrad Meyer } 1512*9119bafbSConrad Meyer } 1513*9119bafbSConrad Meyer 1514*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng) 1515*9119bafbSConrad Meyer { 1516*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1517*9119bafbSConrad Meyer pcg_oneseq_16_step_r(rng); 1518*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_16_16(oldstate); 1519*9119bafbSConrad Meyer } 1520*9119bafbSConrad Meyer 1521*9119bafbSConrad Meyer inline uint16_t 1522*9119bafbSConrad Meyer pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng, 1523*9119bafbSConrad Meyer uint16_t bound) 1524*9119bafbSConrad Meyer { 1525*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1526*9119bafbSConrad Meyer for (;;) { 1527*9119bafbSConrad Meyer uint16_t r = pcg_oneseq_16_rxs_m_xs_16_random_r(rng); 1528*9119bafbSConrad Meyer if (r >= threshold) 1529*9119bafbSConrad Meyer return r % bound; 1530*9119bafbSConrad Meyer } 1531*9119bafbSConrad Meyer } 1532*9119bafbSConrad Meyer 1533*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng) 1534*9119bafbSConrad Meyer { 1535*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1536*9119bafbSConrad Meyer pcg_oneseq_32_step_r(rng); 1537*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_32_32(oldstate); 1538*9119bafbSConrad Meyer } 1539*9119bafbSConrad Meyer 1540*9119bafbSConrad Meyer inline uint32_t 1541*9119bafbSConrad Meyer pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng, 1542*9119bafbSConrad Meyer uint32_t bound) 1543*9119bafbSConrad Meyer { 1544*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1545*9119bafbSConrad Meyer for (;;) { 1546*9119bafbSConrad Meyer uint32_t r = pcg_oneseq_32_rxs_m_xs_32_random_r(rng); 1547*9119bafbSConrad Meyer if (r >= threshold) 1548*9119bafbSConrad Meyer return r % bound; 1549*9119bafbSConrad Meyer } 1550*9119bafbSConrad Meyer } 1551*9119bafbSConrad Meyer 1552*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng) 1553*9119bafbSConrad Meyer { 1554*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1555*9119bafbSConrad Meyer pcg_oneseq_64_step_r(rng); 1556*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_64_64(oldstate); 1557*9119bafbSConrad Meyer } 1558*9119bafbSConrad Meyer 1559*9119bafbSConrad Meyer inline uint64_t 1560*9119bafbSConrad Meyer pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng, 1561*9119bafbSConrad Meyer uint64_t bound) 1562*9119bafbSConrad Meyer { 1563*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1564*9119bafbSConrad Meyer for (;;) { 1565*9119bafbSConrad Meyer uint64_t r = pcg_oneseq_64_rxs_m_xs_64_random_r(rng); 1566*9119bafbSConrad Meyer if (r >= threshold) 1567*9119bafbSConrad Meyer return r % bound; 1568*9119bafbSConrad Meyer } 1569*9119bafbSConrad Meyer } 1570*9119bafbSConrad Meyer 1571*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1572*9119bafbSConrad Meyer inline pcg128_t pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng) 1573*9119bafbSConrad Meyer { 1574*9119bafbSConrad Meyer pcg_oneseq_128_step_r(rng); 1575*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_128_128(rng->state); 1576*9119bafbSConrad Meyer } 1577*9119bafbSConrad Meyer #endif 1578*9119bafbSConrad Meyer 1579*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1580*9119bafbSConrad Meyer inline pcg128_t 1581*9119bafbSConrad Meyer pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng, 1582*9119bafbSConrad Meyer pcg128_t bound) 1583*9119bafbSConrad Meyer { 1584*9119bafbSConrad Meyer pcg128_t threshold = -bound % bound; 1585*9119bafbSConrad Meyer for (;;) { 1586*9119bafbSConrad Meyer pcg128_t r = pcg_oneseq_128_rxs_m_xs_128_random_r(rng); 1587*9119bafbSConrad Meyer if (r >= threshold) 1588*9119bafbSConrad Meyer return r % bound; 1589*9119bafbSConrad Meyer } 1590*9119bafbSConrad Meyer } 1591*9119bafbSConrad Meyer #endif 1592*9119bafbSConrad Meyer 1593*9119bafbSConrad Meyer inline uint16_t pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng) 1594*9119bafbSConrad Meyer { 1595*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1596*9119bafbSConrad Meyer pcg_unique_16_step_r(rng); 1597*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_16_16(oldstate); 1598*9119bafbSConrad Meyer } 1599*9119bafbSConrad Meyer 1600*9119bafbSConrad Meyer inline uint16_t 1601*9119bafbSConrad Meyer pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng, 1602*9119bafbSConrad Meyer uint16_t bound) 1603*9119bafbSConrad Meyer { 1604*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1605*9119bafbSConrad Meyer for (;;) { 1606*9119bafbSConrad Meyer uint16_t r = pcg_unique_16_rxs_m_xs_16_random_r(rng); 1607*9119bafbSConrad Meyer if (r >= threshold) 1608*9119bafbSConrad Meyer return r % bound; 1609*9119bafbSConrad Meyer } 1610*9119bafbSConrad Meyer } 1611*9119bafbSConrad Meyer 1612*9119bafbSConrad Meyer inline uint32_t pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng) 1613*9119bafbSConrad Meyer { 1614*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1615*9119bafbSConrad Meyer pcg_unique_32_step_r(rng); 1616*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_32_32(oldstate); 1617*9119bafbSConrad Meyer } 1618*9119bafbSConrad Meyer 1619*9119bafbSConrad Meyer inline uint32_t 1620*9119bafbSConrad Meyer pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng, 1621*9119bafbSConrad Meyer uint32_t bound) 1622*9119bafbSConrad Meyer { 1623*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1624*9119bafbSConrad Meyer for (;;) { 1625*9119bafbSConrad Meyer uint32_t r = pcg_unique_32_rxs_m_xs_32_random_r(rng); 1626*9119bafbSConrad Meyer if (r >= threshold) 1627*9119bafbSConrad Meyer return r % bound; 1628*9119bafbSConrad Meyer } 1629*9119bafbSConrad Meyer } 1630*9119bafbSConrad Meyer 1631*9119bafbSConrad Meyer inline uint64_t pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng) 1632*9119bafbSConrad Meyer { 1633*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1634*9119bafbSConrad Meyer pcg_unique_64_step_r(rng); 1635*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_64_64(oldstate); 1636*9119bafbSConrad Meyer } 1637*9119bafbSConrad Meyer 1638*9119bafbSConrad Meyer inline uint64_t 1639*9119bafbSConrad Meyer pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng, 1640*9119bafbSConrad Meyer uint64_t bound) 1641*9119bafbSConrad Meyer { 1642*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1643*9119bafbSConrad Meyer for (;;) { 1644*9119bafbSConrad Meyer uint64_t r = pcg_unique_64_rxs_m_xs_64_random_r(rng); 1645*9119bafbSConrad Meyer if (r >= threshold) 1646*9119bafbSConrad Meyer return r % bound; 1647*9119bafbSConrad Meyer } 1648*9119bafbSConrad Meyer } 1649*9119bafbSConrad Meyer 1650*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1651*9119bafbSConrad Meyer inline pcg128_t pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng) 1652*9119bafbSConrad Meyer { 1653*9119bafbSConrad Meyer pcg_unique_128_step_r(rng); 1654*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_128_128(rng->state); 1655*9119bafbSConrad Meyer } 1656*9119bafbSConrad Meyer #endif 1657*9119bafbSConrad Meyer 1658*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1659*9119bafbSConrad Meyer inline pcg128_t 1660*9119bafbSConrad Meyer pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng, 1661*9119bafbSConrad Meyer pcg128_t bound) 1662*9119bafbSConrad Meyer { 1663*9119bafbSConrad Meyer pcg128_t threshold = -bound % bound; 1664*9119bafbSConrad Meyer for (;;) { 1665*9119bafbSConrad Meyer pcg128_t r = pcg_unique_128_rxs_m_xs_128_random_r(rng); 1666*9119bafbSConrad Meyer if (r >= threshold) 1667*9119bafbSConrad Meyer return r % bound; 1668*9119bafbSConrad Meyer } 1669*9119bafbSConrad Meyer } 1670*9119bafbSConrad Meyer #endif 1671*9119bafbSConrad Meyer 1672*9119bafbSConrad Meyer inline uint8_t pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng) 1673*9119bafbSConrad Meyer { 1674*9119bafbSConrad Meyer uint8_t oldstate = rng->state; 1675*9119bafbSConrad Meyer pcg_setseq_8_step_r(rng); 1676*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_8_8(oldstate); 1677*9119bafbSConrad Meyer } 1678*9119bafbSConrad Meyer 1679*9119bafbSConrad Meyer inline uint8_t 1680*9119bafbSConrad Meyer pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng, 1681*9119bafbSConrad Meyer uint8_t bound) 1682*9119bafbSConrad Meyer { 1683*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1684*9119bafbSConrad Meyer for (;;) { 1685*9119bafbSConrad Meyer uint8_t r = pcg_setseq_8_rxs_m_xs_8_random_r(rng); 1686*9119bafbSConrad Meyer if (r >= threshold) 1687*9119bafbSConrad Meyer return r % bound; 1688*9119bafbSConrad Meyer } 1689*9119bafbSConrad Meyer } 1690*9119bafbSConrad Meyer 1691*9119bafbSConrad Meyer inline uint16_t 1692*9119bafbSConrad Meyer pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng) 1693*9119bafbSConrad Meyer { 1694*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1695*9119bafbSConrad Meyer pcg_setseq_16_step_r(rng); 1696*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_16_16(oldstate); 1697*9119bafbSConrad Meyer } 1698*9119bafbSConrad Meyer 1699*9119bafbSConrad Meyer inline uint16_t 1700*9119bafbSConrad Meyer pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng, 1701*9119bafbSConrad Meyer uint16_t bound) 1702*9119bafbSConrad Meyer { 1703*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1704*9119bafbSConrad Meyer for (;;) { 1705*9119bafbSConrad Meyer uint16_t r = pcg_setseq_16_rxs_m_xs_16_random_r(rng); 1706*9119bafbSConrad Meyer if (r >= threshold) 1707*9119bafbSConrad Meyer return r % bound; 1708*9119bafbSConrad Meyer } 1709*9119bafbSConrad Meyer } 1710*9119bafbSConrad Meyer 1711*9119bafbSConrad Meyer inline uint32_t 1712*9119bafbSConrad Meyer pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng) 1713*9119bafbSConrad Meyer { 1714*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1715*9119bafbSConrad Meyer pcg_setseq_32_step_r(rng); 1716*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_32_32(oldstate); 1717*9119bafbSConrad Meyer } 1718*9119bafbSConrad Meyer 1719*9119bafbSConrad Meyer inline uint32_t 1720*9119bafbSConrad Meyer pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng, 1721*9119bafbSConrad Meyer uint32_t bound) 1722*9119bafbSConrad Meyer { 1723*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1724*9119bafbSConrad Meyer for (;;) { 1725*9119bafbSConrad Meyer uint32_t r = pcg_setseq_32_rxs_m_xs_32_random_r(rng); 1726*9119bafbSConrad Meyer if (r >= threshold) 1727*9119bafbSConrad Meyer return r % bound; 1728*9119bafbSConrad Meyer } 1729*9119bafbSConrad Meyer } 1730*9119bafbSConrad Meyer 1731*9119bafbSConrad Meyer inline uint64_t 1732*9119bafbSConrad Meyer pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng) 1733*9119bafbSConrad Meyer { 1734*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1735*9119bafbSConrad Meyer pcg_setseq_64_step_r(rng); 1736*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_64_64(oldstate); 1737*9119bafbSConrad Meyer } 1738*9119bafbSConrad Meyer 1739*9119bafbSConrad Meyer inline uint64_t 1740*9119bafbSConrad Meyer pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng, 1741*9119bafbSConrad Meyer uint64_t bound) 1742*9119bafbSConrad Meyer { 1743*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1744*9119bafbSConrad Meyer for (;;) { 1745*9119bafbSConrad Meyer uint64_t r = pcg_setseq_64_rxs_m_xs_64_random_r(rng); 1746*9119bafbSConrad Meyer if (r >= threshold) 1747*9119bafbSConrad Meyer return r % bound; 1748*9119bafbSConrad Meyer } 1749*9119bafbSConrad Meyer } 1750*9119bafbSConrad Meyer 1751*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1752*9119bafbSConrad Meyer inline pcg128_t 1753*9119bafbSConrad Meyer pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng) 1754*9119bafbSConrad Meyer { 1755*9119bafbSConrad Meyer pcg_setseq_128_step_r(rng); 1756*9119bafbSConrad Meyer return pcg_output_rxs_m_xs_128_128(rng->state); 1757*9119bafbSConrad Meyer } 1758*9119bafbSConrad Meyer #endif 1759*9119bafbSConrad Meyer 1760*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1761*9119bafbSConrad Meyer inline pcg128_t 1762*9119bafbSConrad Meyer pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng, 1763*9119bafbSConrad Meyer pcg128_t bound) 1764*9119bafbSConrad Meyer { 1765*9119bafbSConrad Meyer pcg128_t threshold = -bound % bound; 1766*9119bafbSConrad Meyer for (;;) { 1767*9119bafbSConrad Meyer pcg128_t r = pcg_setseq_128_rxs_m_xs_128_random_r(rng); 1768*9119bafbSConrad Meyer if (r >= threshold) 1769*9119bafbSConrad Meyer return r % bound; 1770*9119bafbSConrad Meyer } 1771*9119bafbSConrad Meyer } 1772*9119bafbSConrad Meyer #endif 1773*9119bafbSConrad Meyer 1774*9119bafbSConrad Meyer /* Generation functions for RXS M */ 1775*9119bafbSConrad Meyer 1776*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_rxs_m_8_random_r(struct pcg_state_16* rng) 1777*9119bafbSConrad Meyer { 1778*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1779*9119bafbSConrad Meyer pcg_oneseq_16_step_r(rng); 1780*9119bafbSConrad Meyer return pcg_output_rxs_m_16_8(oldstate); 1781*9119bafbSConrad Meyer } 1782*9119bafbSConrad Meyer 1783*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng, 1784*9119bafbSConrad Meyer uint8_t bound) 1785*9119bafbSConrad Meyer { 1786*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1787*9119bafbSConrad Meyer for (;;) { 1788*9119bafbSConrad Meyer uint8_t r = pcg_oneseq_16_rxs_m_8_random_r(rng); 1789*9119bafbSConrad Meyer if (r >= threshold) 1790*9119bafbSConrad Meyer return r % bound; 1791*9119bafbSConrad Meyer } 1792*9119bafbSConrad Meyer } 1793*9119bafbSConrad Meyer 1794*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_rxs_m_16_random_r(struct pcg_state_32* rng) 1795*9119bafbSConrad Meyer { 1796*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1797*9119bafbSConrad Meyer pcg_oneseq_32_step_r(rng); 1798*9119bafbSConrad Meyer return pcg_output_rxs_m_32_16(oldstate); 1799*9119bafbSConrad Meyer } 1800*9119bafbSConrad Meyer 1801*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng, 1802*9119bafbSConrad Meyer uint16_t bound) 1803*9119bafbSConrad Meyer { 1804*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1805*9119bafbSConrad Meyer for (;;) { 1806*9119bafbSConrad Meyer uint16_t r = pcg_oneseq_32_rxs_m_16_random_r(rng); 1807*9119bafbSConrad Meyer if (r >= threshold) 1808*9119bafbSConrad Meyer return r % bound; 1809*9119bafbSConrad Meyer } 1810*9119bafbSConrad Meyer } 1811*9119bafbSConrad Meyer 1812*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_rxs_m_32_random_r(struct pcg_state_64* rng) 1813*9119bafbSConrad Meyer { 1814*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1815*9119bafbSConrad Meyer pcg_oneseq_64_step_r(rng); 1816*9119bafbSConrad Meyer return pcg_output_rxs_m_64_32(oldstate); 1817*9119bafbSConrad Meyer } 1818*9119bafbSConrad Meyer 1819*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng, 1820*9119bafbSConrad Meyer uint32_t bound) 1821*9119bafbSConrad Meyer { 1822*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1823*9119bafbSConrad Meyer for (;;) { 1824*9119bafbSConrad Meyer uint32_t r = pcg_oneseq_64_rxs_m_32_random_r(rng); 1825*9119bafbSConrad Meyer if (r >= threshold) 1826*9119bafbSConrad Meyer return r % bound; 1827*9119bafbSConrad Meyer } 1828*9119bafbSConrad Meyer } 1829*9119bafbSConrad Meyer 1830*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1831*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_rxs_m_64_random_r(struct pcg_state_128* rng) 1832*9119bafbSConrad Meyer { 1833*9119bafbSConrad Meyer pcg_oneseq_128_step_r(rng); 1834*9119bafbSConrad Meyer return pcg_output_rxs_m_128_64(rng->state); 1835*9119bafbSConrad Meyer } 1836*9119bafbSConrad Meyer #endif 1837*9119bafbSConrad Meyer 1838*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1839*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng, 1840*9119bafbSConrad Meyer uint64_t bound) 1841*9119bafbSConrad Meyer { 1842*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1843*9119bafbSConrad Meyer for (;;) { 1844*9119bafbSConrad Meyer uint64_t r = pcg_oneseq_128_rxs_m_64_random_r(rng); 1845*9119bafbSConrad Meyer if (r >= threshold) 1846*9119bafbSConrad Meyer return r % bound; 1847*9119bafbSConrad Meyer } 1848*9119bafbSConrad Meyer } 1849*9119bafbSConrad Meyer #endif 1850*9119bafbSConrad Meyer 1851*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_rxs_m_8_random_r(struct pcg_state_16* rng) 1852*9119bafbSConrad Meyer { 1853*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1854*9119bafbSConrad Meyer pcg_unique_16_step_r(rng); 1855*9119bafbSConrad Meyer return pcg_output_rxs_m_16_8(oldstate); 1856*9119bafbSConrad Meyer } 1857*9119bafbSConrad Meyer 1858*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng, 1859*9119bafbSConrad Meyer uint8_t bound) 1860*9119bafbSConrad Meyer { 1861*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1862*9119bafbSConrad Meyer for (;;) { 1863*9119bafbSConrad Meyer uint8_t r = pcg_unique_16_rxs_m_8_random_r(rng); 1864*9119bafbSConrad Meyer if (r >= threshold) 1865*9119bafbSConrad Meyer return r % bound; 1866*9119bafbSConrad Meyer } 1867*9119bafbSConrad Meyer } 1868*9119bafbSConrad Meyer 1869*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_rxs_m_16_random_r(struct pcg_state_32* rng) 1870*9119bafbSConrad Meyer { 1871*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1872*9119bafbSConrad Meyer pcg_unique_32_step_r(rng); 1873*9119bafbSConrad Meyer return pcg_output_rxs_m_32_16(oldstate); 1874*9119bafbSConrad Meyer } 1875*9119bafbSConrad Meyer 1876*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng, 1877*9119bafbSConrad Meyer uint16_t bound) 1878*9119bafbSConrad Meyer { 1879*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1880*9119bafbSConrad Meyer for (;;) { 1881*9119bafbSConrad Meyer uint16_t r = pcg_unique_32_rxs_m_16_random_r(rng); 1882*9119bafbSConrad Meyer if (r >= threshold) 1883*9119bafbSConrad Meyer return r % bound; 1884*9119bafbSConrad Meyer } 1885*9119bafbSConrad Meyer } 1886*9119bafbSConrad Meyer 1887*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_rxs_m_32_random_r(struct pcg_state_64* rng) 1888*9119bafbSConrad Meyer { 1889*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1890*9119bafbSConrad Meyer pcg_unique_64_step_r(rng); 1891*9119bafbSConrad Meyer return pcg_output_rxs_m_64_32(oldstate); 1892*9119bafbSConrad Meyer } 1893*9119bafbSConrad Meyer 1894*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng, 1895*9119bafbSConrad Meyer uint32_t bound) 1896*9119bafbSConrad Meyer { 1897*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1898*9119bafbSConrad Meyer for (;;) { 1899*9119bafbSConrad Meyer uint32_t r = pcg_unique_64_rxs_m_32_random_r(rng); 1900*9119bafbSConrad Meyer if (r >= threshold) 1901*9119bafbSConrad Meyer return r % bound; 1902*9119bafbSConrad Meyer } 1903*9119bafbSConrad Meyer } 1904*9119bafbSConrad Meyer 1905*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1906*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_rxs_m_64_random_r(struct pcg_state_128* rng) 1907*9119bafbSConrad Meyer { 1908*9119bafbSConrad Meyer pcg_unique_128_step_r(rng); 1909*9119bafbSConrad Meyer return pcg_output_rxs_m_128_64(rng->state); 1910*9119bafbSConrad Meyer } 1911*9119bafbSConrad Meyer #endif 1912*9119bafbSConrad Meyer 1913*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1914*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng, 1915*9119bafbSConrad Meyer uint64_t bound) 1916*9119bafbSConrad Meyer { 1917*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1918*9119bafbSConrad Meyer for (;;) { 1919*9119bafbSConrad Meyer uint64_t r = pcg_unique_128_rxs_m_64_random_r(rng); 1920*9119bafbSConrad Meyer if (r >= threshold) 1921*9119bafbSConrad Meyer return r % bound; 1922*9119bafbSConrad Meyer } 1923*9119bafbSConrad Meyer } 1924*9119bafbSConrad Meyer #endif 1925*9119bafbSConrad Meyer 1926*9119bafbSConrad Meyer inline uint8_t pcg_setseq_16_rxs_m_8_random_r(struct pcg_state_setseq_16* rng) 1927*9119bafbSConrad Meyer { 1928*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 1929*9119bafbSConrad Meyer pcg_setseq_16_step_r(rng); 1930*9119bafbSConrad Meyer return pcg_output_rxs_m_16_8(oldstate); 1931*9119bafbSConrad Meyer } 1932*9119bafbSConrad Meyer 1933*9119bafbSConrad Meyer inline uint8_t 1934*9119bafbSConrad Meyer pcg_setseq_16_rxs_m_8_boundedrand_r(struct pcg_state_setseq_16* rng, 1935*9119bafbSConrad Meyer uint8_t bound) 1936*9119bafbSConrad Meyer { 1937*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 1938*9119bafbSConrad Meyer for (;;) { 1939*9119bafbSConrad Meyer uint8_t r = pcg_setseq_16_rxs_m_8_random_r(rng); 1940*9119bafbSConrad Meyer if (r >= threshold) 1941*9119bafbSConrad Meyer return r % bound; 1942*9119bafbSConrad Meyer } 1943*9119bafbSConrad Meyer } 1944*9119bafbSConrad Meyer 1945*9119bafbSConrad Meyer inline uint16_t pcg_setseq_32_rxs_m_16_random_r(struct pcg_state_setseq_32* rng) 1946*9119bafbSConrad Meyer { 1947*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 1948*9119bafbSConrad Meyer pcg_setseq_32_step_r(rng); 1949*9119bafbSConrad Meyer return pcg_output_rxs_m_32_16(oldstate); 1950*9119bafbSConrad Meyer } 1951*9119bafbSConrad Meyer 1952*9119bafbSConrad Meyer inline uint16_t 1953*9119bafbSConrad Meyer pcg_setseq_32_rxs_m_16_boundedrand_r(struct pcg_state_setseq_32* rng, 1954*9119bafbSConrad Meyer uint16_t bound) 1955*9119bafbSConrad Meyer { 1956*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 1957*9119bafbSConrad Meyer for (;;) { 1958*9119bafbSConrad Meyer uint16_t r = pcg_setseq_32_rxs_m_16_random_r(rng); 1959*9119bafbSConrad Meyer if (r >= threshold) 1960*9119bafbSConrad Meyer return r % bound; 1961*9119bafbSConrad Meyer } 1962*9119bafbSConrad Meyer } 1963*9119bafbSConrad Meyer 1964*9119bafbSConrad Meyer inline uint32_t pcg_setseq_64_rxs_m_32_random_r(struct pcg_state_setseq_64* rng) 1965*9119bafbSConrad Meyer { 1966*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 1967*9119bafbSConrad Meyer pcg_setseq_64_step_r(rng); 1968*9119bafbSConrad Meyer return pcg_output_rxs_m_64_32(oldstate); 1969*9119bafbSConrad Meyer } 1970*9119bafbSConrad Meyer 1971*9119bafbSConrad Meyer inline uint32_t 1972*9119bafbSConrad Meyer pcg_setseq_64_rxs_m_32_boundedrand_r(struct pcg_state_setseq_64* rng, 1973*9119bafbSConrad Meyer uint32_t bound) 1974*9119bafbSConrad Meyer { 1975*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 1976*9119bafbSConrad Meyer for (;;) { 1977*9119bafbSConrad Meyer uint32_t r = pcg_setseq_64_rxs_m_32_random_r(rng); 1978*9119bafbSConrad Meyer if (r >= threshold) 1979*9119bafbSConrad Meyer return r % bound; 1980*9119bafbSConrad Meyer } 1981*9119bafbSConrad Meyer } 1982*9119bafbSConrad Meyer 1983*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1984*9119bafbSConrad Meyer inline uint64_t 1985*9119bafbSConrad Meyer pcg_setseq_128_rxs_m_64_random_r(struct pcg_state_setseq_128* rng) 1986*9119bafbSConrad Meyer { 1987*9119bafbSConrad Meyer pcg_setseq_128_step_r(rng); 1988*9119bafbSConrad Meyer return pcg_output_rxs_m_128_64(rng->state); 1989*9119bafbSConrad Meyer } 1990*9119bafbSConrad Meyer #endif 1991*9119bafbSConrad Meyer 1992*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 1993*9119bafbSConrad Meyer inline uint64_t 1994*9119bafbSConrad Meyer pcg_setseq_128_rxs_m_64_boundedrand_r(struct pcg_state_setseq_128* rng, 1995*9119bafbSConrad Meyer uint64_t bound) 1996*9119bafbSConrad Meyer { 1997*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 1998*9119bafbSConrad Meyer for (;;) { 1999*9119bafbSConrad Meyer uint64_t r = pcg_setseq_128_rxs_m_64_random_r(rng); 2000*9119bafbSConrad Meyer if (r >= threshold) 2001*9119bafbSConrad Meyer return r % bound; 2002*9119bafbSConrad Meyer } 2003*9119bafbSConrad Meyer } 2004*9119bafbSConrad Meyer #endif 2005*9119bafbSConrad Meyer 2006*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_rxs_m_8_random_r(struct pcg_state_16* rng) 2007*9119bafbSConrad Meyer { 2008*9119bafbSConrad Meyer uint16_t oldstate = rng->state; 2009*9119bafbSConrad Meyer pcg_mcg_16_step_r(rng); 2010*9119bafbSConrad Meyer return pcg_output_rxs_m_16_8(oldstate); 2011*9119bafbSConrad Meyer } 2012*9119bafbSConrad Meyer 2013*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng, 2014*9119bafbSConrad Meyer uint8_t bound) 2015*9119bafbSConrad Meyer { 2016*9119bafbSConrad Meyer uint8_t threshold = ((uint8_t)(-bound)) % bound; 2017*9119bafbSConrad Meyer for (;;) { 2018*9119bafbSConrad Meyer uint8_t r = pcg_mcg_16_rxs_m_8_random_r(rng); 2019*9119bafbSConrad Meyer if (r >= threshold) 2020*9119bafbSConrad Meyer return r % bound; 2021*9119bafbSConrad Meyer } 2022*9119bafbSConrad Meyer } 2023*9119bafbSConrad Meyer 2024*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_rxs_m_16_random_r(struct pcg_state_32* rng) 2025*9119bafbSConrad Meyer { 2026*9119bafbSConrad Meyer uint32_t oldstate = rng->state; 2027*9119bafbSConrad Meyer pcg_mcg_32_step_r(rng); 2028*9119bafbSConrad Meyer return pcg_output_rxs_m_32_16(oldstate); 2029*9119bafbSConrad Meyer } 2030*9119bafbSConrad Meyer 2031*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng, 2032*9119bafbSConrad Meyer uint16_t bound) 2033*9119bafbSConrad Meyer { 2034*9119bafbSConrad Meyer uint16_t threshold = ((uint16_t)(-bound)) % bound; 2035*9119bafbSConrad Meyer for (;;) { 2036*9119bafbSConrad Meyer uint16_t r = pcg_mcg_32_rxs_m_16_random_r(rng); 2037*9119bafbSConrad Meyer if (r >= threshold) 2038*9119bafbSConrad Meyer return r % bound; 2039*9119bafbSConrad Meyer } 2040*9119bafbSConrad Meyer } 2041*9119bafbSConrad Meyer 2042*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_rxs_m_32_random_r(struct pcg_state_64* rng) 2043*9119bafbSConrad Meyer { 2044*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 2045*9119bafbSConrad Meyer pcg_mcg_64_step_r(rng); 2046*9119bafbSConrad Meyer return pcg_output_rxs_m_64_32(oldstate); 2047*9119bafbSConrad Meyer } 2048*9119bafbSConrad Meyer 2049*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng, 2050*9119bafbSConrad Meyer uint32_t bound) 2051*9119bafbSConrad Meyer { 2052*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 2053*9119bafbSConrad Meyer for (;;) { 2054*9119bafbSConrad Meyer uint32_t r = pcg_mcg_64_rxs_m_32_random_r(rng); 2055*9119bafbSConrad Meyer if (r >= threshold) 2056*9119bafbSConrad Meyer return r % bound; 2057*9119bafbSConrad Meyer } 2058*9119bafbSConrad Meyer } 2059*9119bafbSConrad Meyer 2060*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2061*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_rxs_m_64_random_r(struct pcg_state_128* rng) 2062*9119bafbSConrad Meyer { 2063*9119bafbSConrad Meyer pcg_mcg_128_step_r(rng); 2064*9119bafbSConrad Meyer return pcg_output_rxs_m_128_64(rng->state); 2065*9119bafbSConrad Meyer } 2066*9119bafbSConrad Meyer #endif 2067*9119bafbSConrad Meyer 2068*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2069*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng, 2070*9119bafbSConrad Meyer uint64_t bound) 2071*9119bafbSConrad Meyer { 2072*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 2073*9119bafbSConrad Meyer for (;;) { 2074*9119bafbSConrad Meyer uint64_t r = pcg_mcg_128_rxs_m_64_random_r(rng); 2075*9119bafbSConrad Meyer if (r >= threshold) 2076*9119bafbSConrad Meyer return r % bound; 2077*9119bafbSConrad Meyer } 2078*9119bafbSConrad Meyer } 2079*9119bafbSConrad Meyer #endif 2080*9119bafbSConrad Meyer 2081*9119bafbSConrad Meyer /* Generation functions for XSL RR (only defined for "large" types) */ 2082*9119bafbSConrad Meyer 2083*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng) 2084*9119bafbSConrad Meyer { 2085*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 2086*9119bafbSConrad Meyer pcg_oneseq_64_step_r(rng); 2087*9119bafbSConrad Meyer return pcg_output_xsl_rr_64_32(oldstate); 2088*9119bafbSConrad Meyer } 2089*9119bafbSConrad Meyer 2090*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, 2091*9119bafbSConrad Meyer uint32_t bound) 2092*9119bafbSConrad Meyer { 2093*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 2094*9119bafbSConrad Meyer for (;;) { 2095*9119bafbSConrad Meyer uint32_t r = pcg_oneseq_64_xsl_rr_32_random_r(rng); 2096*9119bafbSConrad Meyer if (r >= threshold) 2097*9119bafbSConrad Meyer return r % bound; 2098*9119bafbSConrad Meyer } 2099*9119bafbSConrad Meyer } 2100*9119bafbSConrad Meyer 2101*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2102*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng) 2103*9119bafbSConrad Meyer { 2104*9119bafbSConrad Meyer pcg_oneseq_128_step_r(rng); 2105*9119bafbSConrad Meyer return pcg_output_xsl_rr_128_64(rng->state); 2106*9119bafbSConrad Meyer } 2107*9119bafbSConrad Meyer #endif 2108*9119bafbSConrad Meyer 2109*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2110*9119bafbSConrad Meyer inline uint64_t 2111*9119bafbSConrad Meyer pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, 2112*9119bafbSConrad Meyer uint64_t bound) 2113*9119bafbSConrad Meyer { 2114*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 2115*9119bafbSConrad Meyer for (;;) { 2116*9119bafbSConrad Meyer uint64_t r = pcg_oneseq_128_xsl_rr_64_random_r(rng); 2117*9119bafbSConrad Meyer if (r >= threshold) 2118*9119bafbSConrad Meyer return r % bound; 2119*9119bafbSConrad Meyer } 2120*9119bafbSConrad Meyer } 2121*9119bafbSConrad Meyer #endif 2122*9119bafbSConrad Meyer 2123*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng) 2124*9119bafbSConrad Meyer { 2125*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 2126*9119bafbSConrad Meyer pcg_unique_64_step_r(rng); 2127*9119bafbSConrad Meyer return pcg_output_xsl_rr_64_32(oldstate); 2128*9119bafbSConrad Meyer } 2129*9119bafbSConrad Meyer 2130*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, 2131*9119bafbSConrad Meyer uint32_t bound) 2132*9119bafbSConrad Meyer { 2133*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 2134*9119bafbSConrad Meyer for (;;) { 2135*9119bafbSConrad Meyer uint32_t r = pcg_unique_64_xsl_rr_32_random_r(rng); 2136*9119bafbSConrad Meyer if (r >= threshold) 2137*9119bafbSConrad Meyer return r % bound; 2138*9119bafbSConrad Meyer } 2139*9119bafbSConrad Meyer } 2140*9119bafbSConrad Meyer 2141*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2142*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng) 2143*9119bafbSConrad Meyer { 2144*9119bafbSConrad Meyer pcg_unique_128_step_r(rng); 2145*9119bafbSConrad Meyer return pcg_output_xsl_rr_128_64(rng->state); 2146*9119bafbSConrad Meyer } 2147*9119bafbSConrad Meyer #endif 2148*9119bafbSConrad Meyer 2149*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2150*9119bafbSConrad Meyer inline uint64_t 2151*9119bafbSConrad Meyer pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, 2152*9119bafbSConrad Meyer uint64_t bound) 2153*9119bafbSConrad Meyer { 2154*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 2155*9119bafbSConrad Meyer for (;;) { 2156*9119bafbSConrad Meyer uint64_t r = pcg_unique_128_xsl_rr_64_random_r(rng); 2157*9119bafbSConrad Meyer if (r >= threshold) 2158*9119bafbSConrad Meyer return r % bound; 2159*9119bafbSConrad Meyer } 2160*9119bafbSConrad Meyer } 2161*9119bafbSConrad Meyer #endif 2162*9119bafbSConrad Meyer 2163*9119bafbSConrad Meyer inline uint32_t 2164*9119bafbSConrad Meyer pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng) 2165*9119bafbSConrad Meyer { 2166*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 2167*9119bafbSConrad Meyer pcg_setseq_64_step_r(rng); 2168*9119bafbSConrad Meyer return pcg_output_xsl_rr_64_32(oldstate); 2169*9119bafbSConrad Meyer } 2170*9119bafbSConrad Meyer 2171*9119bafbSConrad Meyer inline uint32_t 2172*9119bafbSConrad Meyer pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng, 2173*9119bafbSConrad Meyer uint32_t bound) 2174*9119bafbSConrad Meyer { 2175*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 2176*9119bafbSConrad Meyer for (;;) { 2177*9119bafbSConrad Meyer uint32_t r = pcg_setseq_64_xsl_rr_32_random_r(rng); 2178*9119bafbSConrad Meyer if (r >= threshold) 2179*9119bafbSConrad Meyer return r % bound; 2180*9119bafbSConrad Meyer } 2181*9119bafbSConrad Meyer } 2182*9119bafbSConrad Meyer 2183*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2184*9119bafbSConrad Meyer inline uint64_t 2185*9119bafbSConrad Meyer pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng) 2186*9119bafbSConrad Meyer { 2187*9119bafbSConrad Meyer pcg_setseq_128_step_r(rng); 2188*9119bafbSConrad Meyer return pcg_output_xsl_rr_128_64(rng->state); 2189*9119bafbSConrad Meyer } 2190*9119bafbSConrad Meyer #endif 2191*9119bafbSConrad Meyer 2192*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2193*9119bafbSConrad Meyer inline uint64_t 2194*9119bafbSConrad Meyer pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng, 2195*9119bafbSConrad Meyer uint64_t bound) 2196*9119bafbSConrad Meyer { 2197*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 2198*9119bafbSConrad Meyer for (;;) { 2199*9119bafbSConrad Meyer uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng); 2200*9119bafbSConrad Meyer if (r >= threshold) 2201*9119bafbSConrad Meyer return r % bound; 2202*9119bafbSConrad Meyer } 2203*9119bafbSConrad Meyer } 2204*9119bafbSConrad Meyer #endif 2205*9119bafbSConrad Meyer 2206*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng) 2207*9119bafbSConrad Meyer { 2208*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 2209*9119bafbSConrad Meyer pcg_mcg_64_step_r(rng); 2210*9119bafbSConrad Meyer return pcg_output_xsl_rr_64_32(oldstate); 2211*9119bafbSConrad Meyer } 2212*9119bafbSConrad Meyer 2213*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, 2214*9119bafbSConrad Meyer uint32_t bound) 2215*9119bafbSConrad Meyer { 2216*9119bafbSConrad Meyer uint32_t threshold = -bound % bound; 2217*9119bafbSConrad Meyer for (;;) { 2218*9119bafbSConrad Meyer uint32_t r = pcg_mcg_64_xsl_rr_32_random_r(rng); 2219*9119bafbSConrad Meyer if (r >= threshold) 2220*9119bafbSConrad Meyer return r % bound; 2221*9119bafbSConrad Meyer } 2222*9119bafbSConrad Meyer } 2223*9119bafbSConrad Meyer 2224*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2225*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng) 2226*9119bafbSConrad Meyer { 2227*9119bafbSConrad Meyer pcg_mcg_128_step_r(rng); 2228*9119bafbSConrad Meyer return pcg_output_xsl_rr_128_64(rng->state); 2229*9119bafbSConrad Meyer } 2230*9119bafbSConrad Meyer #endif 2231*9119bafbSConrad Meyer 2232*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2233*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, 2234*9119bafbSConrad Meyer uint64_t bound) 2235*9119bafbSConrad Meyer { 2236*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 2237*9119bafbSConrad Meyer for (;;) { 2238*9119bafbSConrad Meyer uint64_t r = pcg_mcg_128_xsl_rr_64_random_r(rng); 2239*9119bafbSConrad Meyer if (r >= threshold) 2240*9119bafbSConrad Meyer return r % bound; 2241*9119bafbSConrad Meyer } 2242*9119bafbSConrad Meyer } 2243*9119bafbSConrad Meyer #endif 2244*9119bafbSConrad Meyer 2245*9119bafbSConrad Meyer /* Generation functions for XSL RR RR (only defined for "large" types) */ 2246*9119bafbSConrad Meyer 2247*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng) 2248*9119bafbSConrad Meyer { 2249*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 2250*9119bafbSConrad Meyer pcg_oneseq_64_step_r(rng); 2251*9119bafbSConrad Meyer return pcg_output_xsl_rr_rr_64_64(oldstate); 2252*9119bafbSConrad Meyer } 2253*9119bafbSConrad Meyer 2254*9119bafbSConrad Meyer inline uint64_t 2255*9119bafbSConrad Meyer pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng, 2256*9119bafbSConrad Meyer uint64_t bound) 2257*9119bafbSConrad Meyer { 2258*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 2259*9119bafbSConrad Meyer for (;;) { 2260*9119bafbSConrad Meyer uint64_t r = pcg_oneseq_64_xsl_rr_rr_64_random_r(rng); 2261*9119bafbSConrad Meyer if (r >= threshold) 2262*9119bafbSConrad Meyer return r % bound; 2263*9119bafbSConrad Meyer } 2264*9119bafbSConrad Meyer } 2265*9119bafbSConrad Meyer 2266*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2267*9119bafbSConrad Meyer inline pcg128_t pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng) 2268*9119bafbSConrad Meyer { 2269*9119bafbSConrad Meyer pcg_oneseq_128_step_r(rng); 2270*9119bafbSConrad Meyer return pcg_output_xsl_rr_rr_128_128(rng->state); 2271*9119bafbSConrad Meyer } 2272*9119bafbSConrad Meyer #endif 2273*9119bafbSConrad Meyer 2274*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2275*9119bafbSConrad Meyer inline pcg128_t 2276*9119bafbSConrad Meyer pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng, 2277*9119bafbSConrad Meyer pcg128_t bound) 2278*9119bafbSConrad Meyer { 2279*9119bafbSConrad Meyer pcg128_t threshold = -bound % bound; 2280*9119bafbSConrad Meyer for (;;) { 2281*9119bafbSConrad Meyer pcg128_t r = pcg_oneseq_128_xsl_rr_rr_128_random_r(rng); 2282*9119bafbSConrad Meyer if (r >= threshold) 2283*9119bafbSConrad Meyer return r % bound; 2284*9119bafbSConrad Meyer } 2285*9119bafbSConrad Meyer } 2286*9119bafbSConrad Meyer #endif 2287*9119bafbSConrad Meyer 2288*9119bafbSConrad Meyer inline uint64_t pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng) 2289*9119bafbSConrad Meyer { 2290*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 2291*9119bafbSConrad Meyer pcg_unique_64_step_r(rng); 2292*9119bafbSConrad Meyer return pcg_output_xsl_rr_rr_64_64(oldstate); 2293*9119bafbSConrad Meyer } 2294*9119bafbSConrad Meyer 2295*9119bafbSConrad Meyer inline uint64_t 2296*9119bafbSConrad Meyer pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng, 2297*9119bafbSConrad Meyer uint64_t bound) 2298*9119bafbSConrad Meyer { 2299*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 2300*9119bafbSConrad Meyer for (;;) { 2301*9119bafbSConrad Meyer uint64_t r = pcg_unique_64_xsl_rr_rr_64_random_r(rng); 2302*9119bafbSConrad Meyer if (r >= threshold) 2303*9119bafbSConrad Meyer return r % bound; 2304*9119bafbSConrad Meyer } 2305*9119bafbSConrad Meyer } 2306*9119bafbSConrad Meyer 2307*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2308*9119bafbSConrad Meyer inline pcg128_t pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng) 2309*9119bafbSConrad Meyer { 2310*9119bafbSConrad Meyer pcg_unique_128_step_r(rng); 2311*9119bafbSConrad Meyer return pcg_output_xsl_rr_rr_128_128(rng->state); 2312*9119bafbSConrad Meyer } 2313*9119bafbSConrad Meyer #endif 2314*9119bafbSConrad Meyer 2315*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2316*9119bafbSConrad Meyer inline pcg128_t 2317*9119bafbSConrad Meyer pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng, 2318*9119bafbSConrad Meyer pcg128_t bound) 2319*9119bafbSConrad Meyer { 2320*9119bafbSConrad Meyer pcg128_t threshold = -bound % bound; 2321*9119bafbSConrad Meyer for (;;) { 2322*9119bafbSConrad Meyer pcg128_t r = pcg_unique_128_xsl_rr_rr_128_random_r(rng); 2323*9119bafbSConrad Meyer if (r >= threshold) 2324*9119bafbSConrad Meyer return r % bound; 2325*9119bafbSConrad Meyer } 2326*9119bafbSConrad Meyer } 2327*9119bafbSConrad Meyer #endif 2328*9119bafbSConrad Meyer 2329*9119bafbSConrad Meyer inline uint64_t 2330*9119bafbSConrad Meyer pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng) 2331*9119bafbSConrad Meyer { 2332*9119bafbSConrad Meyer uint64_t oldstate = rng->state; 2333*9119bafbSConrad Meyer pcg_setseq_64_step_r(rng); 2334*9119bafbSConrad Meyer return pcg_output_xsl_rr_rr_64_64(oldstate); 2335*9119bafbSConrad Meyer } 2336*9119bafbSConrad Meyer 2337*9119bafbSConrad Meyer inline uint64_t 2338*9119bafbSConrad Meyer pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng, 2339*9119bafbSConrad Meyer uint64_t bound) 2340*9119bafbSConrad Meyer { 2341*9119bafbSConrad Meyer uint64_t threshold = -bound % bound; 2342*9119bafbSConrad Meyer for (;;) { 2343*9119bafbSConrad Meyer uint64_t r = pcg_setseq_64_xsl_rr_rr_64_random_r(rng); 2344*9119bafbSConrad Meyer if (r >= threshold) 2345*9119bafbSConrad Meyer return r % bound; 2346*9119bafbSConrad Meyer } 2347*9119bafbSConrad Meyer } 2348*9119bafbSConrad Meyer 2349*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2350*9119bafbSConrad Meyer inline pcg128_t 2351*9119bafbSConrad Meyer pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng) 2352*9119bafbSConrad Meyer { 2353*9119bafbSConrad Meyer pcg_setseq_128_step_r(rng); 2354*9119bafbSConrad Meyer return pcg_output_xsl_rr_rr_128_128(rng->state); 2355*9119bafbSConrad Meyer } 2356*9119bafbSConrad Meyer #endif 2357*9119bafbSConrad Meyer 2358*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2359*9119bafbSConrad Meyer inline pcg128_t 2360*9119bafbSConrad Meyer pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng, 2361*9119bafbSConrad Meyer pcg128_t bound) 2362*9119bafbSConrad Meyer { 2363*9119bafbSConrad Meyer pcg128_t threshold = -bound % bound; 2364*9119bafbSConrad Meyer for (;;) { 2365*9119bafbSConrad Meyer pcg128_t r = pcg_setseq_128_xsl_rr_rr_128_random_r(rng); 2366*9119bafbSConrad Meyer if (r >= threshold) 2367*9119bafbSConrad Meyer return r % bound; 2368*9119bafbSConrad Meyer } 2369*9119bafbSConrad Meyer } 2370*9119bafbSConrad Meyer #endif 2371*9119bafbSConrad Meyer 2372*9119bafbSConrad Meyer /*** Typedefs */ 2373*9119bafbSConrad Meyer typedef struct pcg_state_setseq_64 pcg32_random_t; 2374*9119bafbSConrad Meyer typedef struct pcg_state_64 pcg32s_random_t; 2375*9119bafbSConrad Meyer typedef struct pcg_state_64 pcg32u_random_t; 2376*9119bafbSConrad Meyer typedef struct pcg_state_64 pcg32f_random_t; 2377*9119bafbSConrad Meyer /*** random_r */ 2378*9119bafbSConrad Meyer #define pcg32_random_r pcg_setseq_64_xsh_rr_32_random_r 2379*9119bafbSConrad Meyer #define pcg32s_random_r pcg_oneseq_64_xsh_rr_32_random_r 2380*9119bafbSConrad Meyer #define pcg32u_random_r pcg_unique_64_xsh_rr_32_random_r 2381*9119bafbSConrad Meyer #define pcg32f_random_r pcg_mcg_64_xsh_rs_32_random_r 2382*9119bafbSConrad Meyer /*** boundedrand_r */ 2383*9119bafbSConrad Meyer #define pcg32_boundedrand_r pcg_setseq_64_xsh_rr_32_boundedrand_r 2384*9119bafbSConrad Meyer #define pcg32s_boundedrand_r pcg_oneseq_64_xsh_rr_32_boundedrand_r 2385*9119bafbSConrad Meyer #define pcg32u_boundedrand_r pcg_unique_64_xsh_rr_32_boundedrand_r 2386*9119bafbSConrad Meyer #define pcg32f_boundedrand_r pcg_mcg_64_xsh_rs_32_boundedrand_r 2387*9119bafbSConrad Meyer /*** srandom_r */ 2388*9119bafbSConrad Meyer #define pcg32_srandom_r pcg_setseq_64_srandom_r 2389*9119bafbSConrad Meyer #define pcg32s_srandom_r pcg_oneseq_64_srandom_r 2390*9119bafbSConrad Meyer #define pcg32u_srandom_r pcg_unique_64_srandom_r 2391*9119bafbSConrad Meyer #define pcg32f_srandom_r pcg_mcg_64_srandom_r 2392*9119bafbSConrad Meyer /*** advance_r */ 2393*9119bafbSConrad Meyer #define pcg32_advance_r pcg_setseq_64_advance_r 2394*9119bafbSConrad Meyer #define pcg32s_advance_r pcg_oneseq_64_advance_r 2395*9119bafbSConrad Meyer #define pcg32u_advance_r pcg_unique_64_advance_r 2396*9119bafbSConrad Meyer #define pcg32f_advance_r pcg_mcg_64_advance_r 2397*9119bafbSConrad Meyer 2398*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2399*9119bafbSConrad Meyer /*** Typedefs */ 2400*9119bafbSConrad Meyer typedef struct pcg_state_setseq_128 pcg64_random_t; 2401*9119bafbSConrad Meyer typedef struct pcg_state_128 pcg64s_random_t; 2402*9119bafbSConrad Meyer typedef struct pcg_state_128 pcg64u_random_t; 2403*9119bafbSConrad Meyer typedef struct pcg_state_128 pcg64f_random_t; 2404*9119bafbSConrad Meyer /*** random_r */ 2405*9119bafbSConrad Meyer #define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r 2406*9119bafbSConrad Meyer #define pcg64s_random_r pcg_oneseq_128_xsl_rr_64_random_r 2407*9119bafbSConrad Meyer #define pcg64u_random_r pcg_unique_128_xsl_rr_64_random_r 2408*9119bafbSConrad Meyer #define pcg64f_random_r pcg_mcg_128_xsl_rr_64_random_r 2409*9119bafbSConrad Meyer /*** boundedrand_r */ 2410*9119bafbSConrad Meyer #define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r 2411*9119bafbSConrad Meyer #define pcg64s_boundedrand_r pcg_oneseq_128_xsl_rr_64_boundedrand_r 2412*9119bafbSConrad Meyer #define pcg64u_boundedrand_r pcg_unique_128_xsl_rr_64_boundedrand_r 2413*9119bafbSConrad Meyer #define pcg64f_boundedrand_r pcg_mcg_128_xsl_rr_64_boundedrand_r 2414*9119bafbSConrad Meyer /*** srandom_r */ 2415*9119bafbSConrad Meyer #define pcg64_srandom_r pcg_setseq_128_srandom_r 2416*9119bafbSConrad Meyer #define pcg64s_srandom_r pcg_oneseq_128_srandom_r 2417*9119bafbSConrad Meyer #define pcg64u_srandom_r pcg_unique_128_srandom_r 2418*9119bafbSConrad Meyer #define pcg64f_srandom_r pcg_mcg_128_srandom_r 2419*9119bafbSConrad Meyer /*** advance_r */ 2420*9119bafbSConrad Meyer #define pcg64_advance_r pcg_setseq_128_advance_r 2421*9119bafbSConrad Meyer #define pcg64s_advance_r pcg_oneseq_128_advance_r 2422*9119bafbSConrad Meyer #define pcg64u_advance_r pcg_unique_128_advance_r 2423*9119bafbSConrad Meyer #define pcg64f_advance_r pcg_mcg_128_advance_r 2424*9119bafbSConrad Meyer #endif 2425*9119bafbSConrad Meyer 2426*9119bafbSConrad Meyer /*** Typedefs */ 2427*9119bafbSConrad Meyer typedef struct pcg_state_8 pcg8si_random_t; 2428*9119bafbSConrad Meyer typedef struct pcg_state_16 pcg16si_random_t; 2429*9119bafbSConrad Meyer typedef struct pcg_state_32 pcg32si_random_t; 2430*9119bafbSConrad Meyer typedef struct pcg_state_64 pcg64si_random_t; 2431*9119bafbSConrad Meyer /*** random_r */ 2432*9119bafbSConrad Meyer #define pcg8si_random_r pcg_oneseq_8_rxs_m_xs_8_random_r 2433*9119bafbSConrad Meyer #define pcg16si_random_r pcg_oneseq_16_rxs_m_xs_16_random_r 2434*9119bafbSConrad Meyer #define pcg32si_random_r pcg_oneseq_32_rxs_m_xs_32_random_r 2435*9119bafbSConrad Meyer #define pcg64si_random_r pcg_oneseq_64_rxs_m_xs_64_random_r 2436*9119bafbSConrad Meyer /*** boundedrand_r */ 2437*9119bafbSConrad Meyer #define pcg8si_boundedrand_r pcg_oneseq_8_rxs_m_xs_8_boundedrand_r 2438*9119bafbSConrad Meyer #define pcg16si_boundedrand_r pcg_oneseq_16_rxs_m_xs_16_boundedrand_r 2439*9119bafbSConrad Meyer #define pcg32si_boundedrand_r pcg_oneseq_32_rxs_m_xs_32_boundedrand_r 2440*9119bafbSConrad Meyer #define pcg64si_boundedrand_r pcg_oneseq_64_rxs_m_xs_64_boundedrand_r 2441*9119bafbSConrad Meyer /*** srandom_r */ 2442*9119bafbSConrad Meyer #define pcg8si_srandom_r pcg_oneseq_8_srandom_r 2443*9119bafbSConrad Meyer #define pcg16si_srandom_r pcg_oneseq_16_srandom_r 2444*9119bafbSConrad Meyer #define pcg32si_srandom_r pcg_oneseq_32_srandom_r 2445*9119bafbSConrad Meyer #define pcg64si_srandom_r pcg_oneseq_64_srandom_r 2446*9119bafbSConrad Meyer /*** advance_r */ 2447*9119bafbSConrad Meyer #define pcg8si_advance_r pcg_oneseq_8_advance_r 2448*9119bafbSConrad Meyer #define pcg16si_advance_r pcg_oneseq_16_advance_r 2449*9119bafbSConrad Meyer #define pcg32si_advance_r pcg_oneseq_32_advance_r 2450*9119bafbSConrad Meyer #define pcg64si_advance_r pcg_oneseq_64_advance_r 2451*9119bafbSConrad Meyer 2452*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2453*9119bafbSConrad Meyer typedef struct pcg_state_128 pcg128si_random_t; 2454*9119bafbSConrad Meyer #define pcg128si_random_r pcg_oneseq_128_rxs_m_xs_128_random_r 2455*9119bafbSConrad Meyer #define pcg128si_boundedrand_r pcg_oneseq_128_rxs_m_xs_128_boundedrand_r 2456*9119bafbSConrad Meyer #define pcg128si_srandom_r pcg_oneseq_128_srandom_r 2457*9119bafbSConrad Meyer #define pcg128si_advance_r pcg_oneseq_128_advance_r 2458*9119bafbSConrad Meyer #endif 2459*9119bafbSConrad Meyer 2460*9119bafbSConrad Meyer /*** Typedefs */ 2461*9119bafbSConrad Meyer typedef struct pcg_state_setseq_8 pcg8i_random_t; 2462*9119bafbSConrad Meyer typedef struct pcg_state_setseq_16 pcg16i_random_t; 2463*9119bafbSConrad Meyer typedef struct pcg_state_setseq_32 pcg32i_random_t; 2464*9119bafbSConrad Meyer typedef struct pcg_state_setseq_64 pcg64i_random_t; 2465*9119bafbSConrad Meyer /*** random_r */ 2466*9119bafbSConrad Meyer #define pcg8i_random_r pcg_setseq_8_rxs_m_xs_8_random_r 2467*9119bafbSConrad Meyer #define pcg16i_random_r pcg_setseq_16_rxs_m_xs_16_random_r 2468*9119bafbSConrad Meyer #define pcg32i_random_r pcg_setseq_32_rxs_m_xs_32_random_r 2469*9119bafbSConrad Meyer #define pcg64i_random_r pcg_setseq_64_rxs_m_xs_64_random_r 2470*9119bafbSConrad Meyer /*** boundedrand_r */ 2471*9119bafbSConrad Meyer #define pcg8i_boundedrand_r pcg_setseq_8_rxs_m_xs_8_boundedrand_r 2472*9119bafbSConrad Meyer #define pcg16i_boundedrand_r pcg_setseq_16_rxs_m_xs_16_boundedrand_r 2473*9119bafbSConrad Meyer #define pcg32i_boundedrand_r pcg_setseq_32_rxs_m_xs_32_boundedrand_r 2474*9119bafbSConrad Meyer #define pcg64i_boundedrand_r pcg_setseq_64_rxs_m_xs_64_boundedrand_r 2475*9119bafbSConrad Meyer /*** srandom_r */ 2476*9119bafbSConrad Meyer #define pcg8i_srandom_r pcg_setseq_8_srandom_r 2477*9119bafbSConrad Meyer #define pcg16i_srandom_r pcg_setseq_16_srandom_r 2478*9119bafbSConrad Meyer #define pcg32i_srandom_r pcg_setseq_32_srandom_r 2479*9119bafbSConrad Meyer #define pcg64i_srandom_r pcg_setseq_64_srandom_r 2480*9119bafbSConrad Meyer /*** advance_r */ 2481*9119bafbSConrad Meyer #define pcg8i_advance_r pcg_setseq_8_advance_r 2482*9119bafbSConrad Meyer #define pcg16i_advance_r pcg_setseq_16_advance_r 2483*9119bafbSConrad Meyer #define pcg32i_advance_r pcg_setseq_32_advance_r 2484*9119bafbSConrad Meyer #define pcg64i_advance_r pcg_setseq_64_advance_r 2485*9119bafbSConrad Meyer 2486*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2487*9119bafbSConrad Meyer typedef struct pcg_state_setseq_128 pcg128i_random_t; 2488*9119bafbSConrad Meyer #define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r 2489*9119bafbSConrad Meyer #define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r 2490*9119bafbSConrad Meyer #define pcg128i_srandom_r pcg_setseq_128_srandom_r 2491*9119bafbSConrad Meyer #define pcg128i_advance_r pcg_setseq_128_advance_r 2492*9119bafbSConrad Meyer #endif 2493*9119bafbSConrad Meyer 2494*9119bafbSConrad Meyer extern uint32_t pcg32_random(void); 2495*9119bafbSConrad Meyer extern uint32_t pcg32_boundedrand(uint32_t bound); 2496*9119bafbSConrad Meyer extern void pcg32_srandom(uint64_t seed, uint64_t seq); 2497*9119bafbSConrad Meyer extern void pcg32_advance(uint64_t delta); 2498*9119bafbSConrad Meyer 2499*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2500*9119bafbSConrad Meyer extern uint64_t pcg64_random(void); 2501*9119bafbSConrad Meyer extern uint64_t pcg64_boundedrand(uint64_t bound); 2502*9119bafbSConrad Meyer extern void pcg64_srandom(pcg128_t seed, pcg128_t seq); 2503*9119bafbSConrad Meyer extern void pcg64_advance(pcg128_t delta); 2504*9119bafbSConrad Meyer #endif 2505*9119bafbSConrad Meyer 2506*9119bafbSConrad Meyer /* 2507*9119bafbSConrad Meyer * Static initialization constants (if you can't call srandom for some 2508*9119bafbSConrad Meyer * bizarre reason). 2509*9119bafbSConrad Meyer */ 2510*9119bafbSConrad Meyer 2511*9119bafbSConrad Meyer #define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER 2512*9119bafbSConrad Meyer #define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER 2513*9119bafbSConrad Meyer #define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER 2514*9119bafbSConrad Meyer #define PCG32F_INITIALIZER PCG_STATE_MCG_64_INITIALIZER 2515*9119bafbSConrad Meyer 2516*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2517*9119bafbSConrad Meyer #define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER 2518*9119bafbSConrad Meyer #define PCG64U_INITIALIZER PCG_STATE_UNIQUE_128_INITIALIZER 2519*9119bafbSConrad Meyer #define PCG64S_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER 2520*9119bafbSConrad Meyer #define PCG64F_INITIALIZER PCG_STATE_MCG_128_INITIALIZER 2521*9119bafbSConrad Meyer #endif 2522*9119bafbSConrad Meyer 2523*9119bafbSConrad Meyer #define PCG8SI_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER 2524*9119bafbSConrad Meyer #define PCG16SI_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER 2525*9119bafbSConrad Meyer #define PCG32SI_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER 2526*9119bafbSConrad Meyer #define PCG64SI_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER 2527*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2528*9119bafbSConrad Meyer #define PCG128SI_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER 2529*9119bafbSConrad Meyer #endif 2530*9119bafbSConrad Meyer 2531*9119bafbSConrad Meyer #define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER 2532*9119bafbSConrad Meyer #define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER 2533*9119bafbSConrad Meyer #define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER 2534*9119bafbSConrad Meyer #define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER 2535*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS 2536*9119bafbSConrad Meyer #define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER 2537*9119bafbSConrad Meyer #endif 2538*9119bafbSConrad Meyer 2539*9119bafbSConrad Meyer #if __cplusplus 2540*9119bafbSConrad Meyer } 2541*9119bafbSConrad Meyer #endif 2542*9119bafbSConrad Meyer 2543*9119bafbSConrad Meyer #endif /* PCG_VARIANTS_H_INCLUDED */ 2544*9119bafbSConrad Meyer 2545