Skip to content

Commit 594aed8

Browse files
committed
seed_from_u64: use newpavlov's suggestion
1 parent eb4b8a4 commit 594aed8

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

rand_core/src/lib.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,20 +300,30 @@ pub trait SeedableRng: Sized {
300300
/// considered a value-breaking change.
301301
fn seed_from_u64(mut state: u64) -> Self {
302302
// We use PCG32 to generate a u32 sequence, and copy to the seed
303-
const MUL: u64 = 6364136223846793005;
304-
const INC: u64 = 11634580027462260723;
303+
fn pcg32(state: &mut u64) -> [u8; 4] {
304+
const MUL: u64 = 6364136223846793005;
305+
const INC: u64 = 11634580027462260723;
305306

306-
let mut seed = Self::Seed::default();
307-
for chunk in seed.as_mut().chunks_mut(4) {
308307
// We advance the state first (to get away from the input value,
309308
// in case it has low Hamming Weight).
310-
state = state.wrapping_mul(MUL).wrapping_add(INC);
309+
*state = state.wrapping_mul(MUL).wrapping_add(INC);
310+
let state = *state;
311311

312312
// Use PCG output function with to_le to generate x:
313313
let xorshifted = (((state >> 18) ^ state) >> 27) as u32;
314314
let rot = (state >> 59) as u32;
315315
let x = xorshifted.rotate_right(rot);
316-
chunk.copy_from_slice(&x.to_le_bytes()[..chunk.len()]);
316+
x.to_le_bytes()
317+
}
318+
319+
let mut seed = Self::Seed::default();
320+
let mut iter = seed.as_mut().chunks_exact_mut(4);
321+
for chunk in &mut iter {
322+
chunk.copy_from_slice(&pcg32(&mut state));
323+
}
324+
let rem = iter.into_remainder();
325+
if !rem.is_empty() {
326+
rem.copy_from_slice(&pcg32(&mut state)[..rem.len()]);
317327
}
318328

319329
Self::from_seed(seed)

0 commit comments

Comments
 (0)