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 }