v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/fastrand/alg/xoshiro256plusplus/xoshiro256plusplus.go (about)

     1  /******************************************************************************
     2  
     3  Original C code: https://prng.di.unimi.it/xoshiro256plusplus.c
     4  Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
     5  
     6  To the extent possible under law, the author has dedicated all copyright
     7  and related and neighboring rights to this software to the public domain
     8  worldwide. This software is distributed without any warranty.
     9  
    10  See <http://creativecommons.org/publicdomain/zero/1.0/>.
    11  
    12  *******************************************************************************/
    13  
    14  package xoshiro256plusplus
    15  
    16  import (
    17  	"sync"
    18  
    19  	"v8.run/go/exp/fastrand/alg/splitmix64"
    20  )
    21  
    22  type State [4]uint64
    23  
    24  func rotl(x uint64, k uint) uint64 {
    25  	return (x << k) | (x >> (64 - k))
    26  }
    27  
    28  func (s *State) Next() uint64 {
    29  	var result uint64 = rotl(s[0]+s[3], 23) + s[0]
    30  	var t uint64 = s[1] << 17
    31  
    32  	s[2] ^= s[0]
    33  	s[3] ^= s[1]
    34  	s[1] ^= s[2]
    35  	s[0] ^= s[3]
    36  
    37  	s[2] ^= t
    38  
    39  	s[3] = rotl(s[3], 45)
    40  
    41  	return result
    42  }
    43  
    44  func (s *State) init(seed uint64) {
    45  	seed = splitmix64.Splitmix64(&seed)
    46  	s[0] = splitmix64.Splitmix64(&seed)
    47  	s[1] = splitmix64.Splitmix64(&seed)
    48  	s[2] = splitmix64.Splitmix64(&seed)
    49  	s[3] = splitmix64.Splitmix64(&seed)
    50  }
    51  
    52  // NewState initializes xoshiro256++ state.
    53  func NewState() State {
    54  	var s State
    55  	s.init(splitmix64.Next())
    56  	return s
    57  }
    58  
    59  // NewStateWithSeed initializes xoshiro256++ state with a seed.
    60  func NewStateWithSeed(seed uint64) State {
    61  	var s State
    62  	s.init(seed)
    63  	return s
    64  }
    65  
    66  const seed uint64 = 9674114761913717981
    67  
    68  var gState State = NewStateWithSeed(seed)
    69  var mu sync.Mutex
    70  
    71  func Next() uint64 {
    72  	mu.Lock()
    73  	v := gState.Next()
    74  	mu.Unlock()
    75  	return v
    76  }