updated splitmix64 implementation

This commit is contained in:
Weird Constructor 2021-06-23 05:13:50 +02:00
parent 40c5c2c9c9
commit 845df99ab5

View file

@ -108,29 +108,29 @@ impl RandGen {
} }
// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//- splitmix64 (http://xoroshiro.di.unimi.it/splitmix64.c) //- splitmix64 (http://xoroshiro.di.unimi.it/splitmix64.c)
//"""
// Written in 2015 by Sebastiano Vigna (vigna@acm.org)
// //
// To the extent possible under law, the author has dedicated all copyright /// A splitmix64 random number generator.
// and related and neighboring rights to this software to the public domain ///
// worldwide. This software is distributed without any warranty. /// The splitmix algorithm is not suitable for cryptographic purposes, but is
// /// very fast and has a 64 bit state.
// See <http://creativecommons.org/publicdomain/zero/1.0/>. ///
//""" /// The algorithm used here is translated from [the `splitmix64.c`
// /// reference source code](http://xoshiro.di.unimi.it/splitmix64.c) by
// Written by Alexander Stocko <as@coder.gg> /// Sebastiano Vigna. For `next_u32`, a more efficient mixing function taken
// /// from [`dsiutils`](http://dsiutils.di.unimi.it/) is used.
// To the extent possible under law, the author has dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// See <LICENSE or http://creativecommons.org/publicdomain/zero/1.0/>
/// The `SplitMix64` random number generator.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct SplitMix64(pub u64); pub struct SplitMix64(pub u64);
const PHI: u64 = 0x9e3779b97f4a7c15;
impl SplitMix64 { impl SplitMix64 {
pub fn new(seed: u64) -> Self { Self(seed) } pub fn new(seed: u64) -> Self { Self(seed) }
pub fn new_from_i64(seed: i64) -> Self { pub fn new_from_i64(seed: i64) -> Self {
@ -139,13 +139,11 @@ impl SplitMix64 {
#[inline] #[inline]
pub fn next_u64(&mut self) -> u64 { pub fn next_u64(&mut self) -> u64 {
use std::num::Wrapping as w; self.0 = self.0.wrapping_add(PHI);
let mut z = self.0;
let mut z = w(self.0) + w(0x9E37_79B9_7F4A_7C15_u64); z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
self.0 = z.0; z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);
z = (z ^ (z >> 30)) * w(0xBF58_476D_1CE4_E5B9_u64); z ^ (z >> 31)
z = (z ^ (z >> 27)) * w(0x94D0_49BB_1331_11EB_u64);
(z ^ (z >> 31)).0
} }
#[inline] #[inline]