1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! Cast-free integer/float index helpers shared by the resampling schemes and
//! the interval estimator.
//!
//! The protected `style.rs` guard bans `as` casts in `src/`, so every
//! `usize`/`f64` conversion here routes through `From`/`TryFrom` or stays in
//! integer arithmetic.
use crateSplitMix64;
/// `2^32`, used to split an integer-valued `f64` into 32-bit halves.
const TWO_POW_32: f64 = 4_294_967_296.0;
/// Widens a `usize` count to `f64` without an `as` cast.
///
/// Splits the value into 32-bit halves (each losslessly representable as `f64`)
/// and recombines them, satisfying the `style.rs` no-`as` guard. Counts far below
/// `2^53` (every realistic sample size) convert exactly.
///
/// # Arguments
///
/// * `n` — the count to widen.
///
/// # Returns
///
/// `n` as an `f64`.
pub
/// Returns `floor(fraction * n)` as a `usize`, computed without an `as` cast.
///
/// Binary-searches the integer ranks in `0..=n`, comparing each candidate's exact
/// `f64` widening against the float target, so no `f64 -> integer` conversion is
/// ever needed (the `style.rs` guard bans `as`). The result lies in `0..=n`.
///
/// # Arguments
///
/// * `fraction` — a probability in `[0, 1]`.
/// * `n` — the sample size.
///
/// # Returns
///
/// `floor(fraction * n)` as a `usize`.
pub
/// Draws a uniform index in `0..n` from `rng`.
///
/// Reduces a full-width `u64` draw modulo `n`, keeping the computation in integer
/// arithmetic so no `f64 -> integer` cast is needed (the `style.rs` guard bans
/// `as`, and a float round-trip would risk an off-by-one at the upper end). The
/// modulo bias is negligible for the small `n` used in resampling (`n` far below
/// `2^32`), and the stream stays byte-identical for a fixed seed.
///
/// # Arguments
///
/// * `rng` — the deterministic generator to draw from.
/// * `n` — collection length; must be `> 0` (callers guarantee this).
///
/// # Returns
///
/// A uniformly distributed index in `0..n`.
pub