MCPcopy Create free account
hub / github.com/numpy/numpy / bounded_lemire_uint64

Function bounded_lemire_uint64

numpy/random/src/distributions/distributions.c:1190–1271  ·  view source on GitHub ↗

Static `Lemire rejection` function called by random_bounded_uint64(...) */

Source from the content-addressed store, hash-verified

1188
1189/* Static `Lemire rejection` function called by random_bounded_uint64(...) */
1190static inline uint64_t bounded_lemire_uint64(bitgen_t *bitgen_state,
1191 uint64_t rng) {
1192 /*
1193 * Uses Lemire's algorithm - https://arxiv.org/abs/1805.10941
1194 *
1195 * Note: `rng` should not be 0xFFFFFFFFFFFFFFFF. When this happens `rng_excl`
1196 * becomes zero.
1197 */
1198 const uint64_t rng_excl = rng + 1;
1199
1200 assert(rng != 0xFFFFFFFFFFFFFFFFULL);
1201
1202#if __SIZEOF_INT128__
1203 /* 128-bit uint available (e.g. GCC/clang). `m` is the __uint128_t scaled
1204 * integer. */
1205 __uint128_t m;
1206 uint64_t leftover;
1207
1208 /* Generate a scaled random number. */
1209 m = ((__uint128_t)next_uint64(bitgen_state)) * rng_excl;
1210
1211 /* Rejection sampling to remove any bias. */
1212 leftover = m & 0xFFFFFFFFFFFFFFFFULL;
1213
1214 if (leftover < rng_excl) {
1215 /* `rng_excl` is a simple upper bound for `threshold`. */
1216 const uint64_t threshold = (UINT64_MAX - rng) % rng_excl;
1217
1218 while (leftover < threshold) {
1219 m = ((__uint128_t)next_uint64(bitgen_state)) * rng_excl;
1220 leftover = m & 0xFFFFFFFFFFFFFFFFULL;
1221 }
1222 }
1223
1224 return (m >> 64);
1225#else
1226 /* 128-bit uint NOT available (e.g. MSVS). `m1` is the upper 64-bits of the
1227 * scaled integer. */
1228 uint64_t m1;
1229 uint64_t x;
1230 uint64_t leftover;
1231
1232 x = next_uint64(bitgen_state);
1233
1234 /* Rejection sampling to remove any bias. */
1235 leftover = x * rng_excl; /* The lower 64-bits of the mult. */
1236
1237 if (leftover < rng_excl) {
1238 /* `rng_excl` is a simple upper bound for `threshold`. */
1239 const uint64_t threshold = (UINT64_MAX - rng) % rng_excl;
1240
1241 while (leftover < threshold) {
1242 x = next_uint64(bitgen_state);
1243 leftover = x * rng_excl;
1244 }
1245 }
1246
1247#if defined(_MSC_VER) && defined(_WIN64)

Callers 2

random_bounded_uint64Function · 0.85

Calls 1

next_uint64Function · 0.85

Tested by

no test coverage detected