This commit is contained in:
2024-11-03 17:48:59 -06:00
parent 583b9234fd
commit 3b1a207b3f
10 changed files with 262 additions and 255 deletions

View File

@@ -0,0 +1,59 @@
import Foundation
public enum Xoshiro256: Equatable {
public typealias State = (UInt64, UInt64, UInt64, UInt64)
internal static var invalidState: State { (0, 0, 0, 0) }
internal static func isValid(state: State) -> Bool {
state != invalidState
}
}
@inlinable
@inline(__always)
internal func rotl(_ x: UInt64, _ k: UInt64) -> UInt64 {
(x << k) | (x >> (64 &- k))
}
struct Xoshiro256Plus: RandomNumberGenerator {
public typealias State = Xoshiro256.State
private var state: State
public init() {
var generator = SystemRandomNumberGenerator()
self.init(seed: generator.next())
}
public init(seed: UInt64) {
var generator = SplitMix64(state: seed)
var state = Xoshiro256.invalidState
repeat {
state = (generator.next(), generator.next(), generator.next(), generator.next())
} while !Xoshiro256.isValid(state: state)
self.init(state: state)
}
public init(state: State) {
precondition(Xoshiro256.isValid(state: state), "The state must not be zero")
self.state = state
}
public mutating func next() -> UInt64 {
let result = state.0 &+ state.3
let t = state.1 << 17
state.2 ^= state.0
state.3 ^= state.1
state.1 ^= state.2
state.0 ^= state.3
state.2 ^= t
state.3 = rotl(state.3, 45)
return result
}
}