pgregory.net/rand@v1.0.3-0.20230808192358-a0b8ce02f4da/sfc64.go (about)

     1  // Copyright 2022 Gregory Petrosyan <gregory.petrosyan@gmail.com>
     2  //
     3  // This Source Code Form is subject to the terms of the Mozilla Public
     4  // License, v. 2.0. If a copy of the MPL was not distributed with this
     5  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
     6  
     7  package rand
     8  
     9  import "math/bits"
    10  
    11  type sfc64 struct {
    12  	a uint64
    13  	b uint64
    14  	c uint64
    15  	w uint64
    16  }
    17  
    18  func (s *sfc64) init(a uint64, b uint64, c uint64) {
    19  	s.a = a
    20  	s.b = b
    21  	s.c = c
    22  	s.w = 1
    23  	for i := 0; i < 12; i++ {
    24  		s.next64()
    25  	}
    26  }
    27  
    28  func (s *sfc64) init0() {
    29  	s.a = rand64()
    30  	s.b = rand64()
    31  	s.c = rand64()
    32  	s.w = 1
    33  }
    34  
    35  func (s *sfc64) init1(u uint64) {
    36  	s.a = u
    37  	s.b = u
    38  	s.c = u
    39  	s.w = 1
    40  	for i := 0; i < 12; i++ {
    41  		s.next64()
    42  	}
    43  }
    44  
    45  func (s *sfc64) init3(a uint64, b uint64, c uint64) {
    46  	s.a = a
    47  	s.b = b
    48  	s.c = c
    49  	s.w = 1
    50  	for i := 0; i < 18; i++ {
    51  		s.next64()
    52  	}
    53  }
    54  
    55  func (s *sfc64) next64() (out uint64) { // named return value lowers inlining cost
    56  	out = s.a + s.b + s.w
    57  	s.w++
    58  	s.a, s.b, s.c = s.b^(s.b>>11), s.c+(s.c<<3), bits.RotateLeft64(s.c, 24)+out // single assignment lowers inlining cost
    59  	return
    60  }