go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/naivernd.go (about) 1 package fu 2 3 import ( 4 "math" 5 "os" 6 "sync/atomic" 7 "time" 8 ) 9 10 type NaiveRandom struct { 11 Value uint32 12 } 13 14 func (nr *NaiveRandom) Reseed() { 15 atomic.StoreUint32(&nr.Value, uint32(time.Now().UnixNano()+int64(os.Getpid()))) 16 } 17 18 func (nr *NaiveRandom) Uint32() (r uint32) { 19 for { 20 r = atomic.LoadUint32(&nr.Value) 21 rx := r 22 r = r*1664525 + 1013904223 23 if atomic.CompareAndSwapUint32(&nr.Value, rx, r) { 24 break 25 } 26 } 27 return 28 } 29 30 func (nr *NaiveRandom) Uint() uint { 31 return uint(nr.Uint32()) 32 } 33 34 func (nr *NaiveRandom) Int() int { 35 return int(nr.Uint32()) 36 } 37 func (nr *NaiveRandom) Float() float64 { 38 return float64(nr.Uint()) / (float64(math.MaxUint32) + 1) 39 } 40 41 func Seed(seed int) int { 42 if seed != 0 { 43 return seed 44 } 45 return int(time.Now().UnixNano() + int64(os.Getpid())) 46 } 47 48 func Seed32(seed int) uint32 { 49 return uint32(Seed(seed)) 50 } 51 52 func Seed64(seed int) int64 { 53 return int64(Seed(seed)) 54 } 55 56 func RandomInts(seed int, count int) []int { 57 nr := NaiveRandom{Value: uint32(seed)} 58 m := map[int]bool{} 59 for i := 0; i < count; { 60 v := nr.Int() 61 if _, ok := m[v]; !ok { 62 m[v] = true 63 i++ 64 } 65 } 66 r := make([]int, count) 67 i := 0 68 for k := range m { 69 r[i] = k 70 i++ 71 } 72 return r 73 }