Class: Okmain::Xoshiro256PlusPlus
- Inherits:
-
Object
- Object
- Okmain::Xoshiro256PlusPlus
- Defined in:
- lib/okmain/xoshiro.rb
Overview
Xoshiro256++ PRNG, matching Rust’s rand_xoshiro crate exactly. Seeding via SplitMix64 matches Rust’s SeedableRng::seed_from_u64.
Constant Summary collapse
- MASK64 =
(1 << 64) - 1
Instance Method Summary collapse
-
#initialize(seed) ⇒ Xoshiro256PlusPlus
constructor
A new instance of Xoshiro256PlusPlus.
-
#next_u64 ⇒ Object
Generate next u64.
-
#random_f32 ⇒ Object
Uniform f32 in [0, 1), matching Rust’s rand StandardUniform for f32.
-
#random_range(range) ⇒ Object
Uniform integer in 0…range, using Lemire’s method (matching Rust’s rand crate).
Constructor Details
#initialize(seed) ⇒ Xoshiro256PlusPlus
Returns a new instance of Xoshiro256PlusPlus.
9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/okmain/xoshiro.rb', line 9 def initialize(seed) # SplitMix64 seeding (matches Rust's SeedableRng::seed_from_u64) sm = seed & MASK64 @s = Array.new(4) do sm = (sm + 0x9e3779b97f4a7c15) & MASK64 z = sm z = ((z ^ (z >> 30)) * 0xbf58476d1ce4e5b9) & MASK64 z = ((z ^ (z >> 27)) * 0x94d049bb133111eb) & MASK64 z ^ (z >> 31) end end |
Instance Method Details
#next_u64 ⇒ Object
Generate next u64
22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/okmain/xoshiro.rb', line 22 def next_u64 s = @s result = (rotl(s[0] + s[3], 23) + s[0]) & MASK64 t = (s[1] << 17) & MASK64 s[2] ^= s[0] s[3] ^= s[1] s[1] ^= s[2] s[0] ^= s[3] s[2] ^= t s[3] = rotl(s[3], 45) result end |
#random_f32 ⇒ Object
Uniform f32 in [0, 1), matching Rust’s rand StandardUniform for f32. Xoshiro256++.next_u32() returns next_u64() >> 32 (upper bits). Then StandardUniform takes top 24 bits of the u32.
54 55 56 57 58 |
# File 'lib/okmain/xoshiro.rb', line 54 def random_f32 u64 = next_u64 u32 = u64 >> 32 # Rust's next_u32() for Xoshiro256++ (u32 >> 8).to_f / 16777216.0 # top 24 bits / 2^24 end |
#random_range(range) ⇒ Object
Uniform integer in 0…range, using Lemire’s method (matching Rust’s rand crate)
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/okmain/xoshiro.rb', line 36 def random_range(range) full = next_u64 * range hi = full >> 64 lo = full & MASK64 if lo < range threshold = (MASK64 - range + 1) % range # (2^64 - range) % range while lo < threshold full = next_u64 * range hi = full >> 64 lo = full & MASK64 end end hi end |