github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/math/rand/rand.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package rand implements pseudo-random number generators. 6 package rand 7 8 import "sync" 9 10 // A Source represents a source of uniformly-distributed 11 // pseudo-random int64 values in the range [0, 1<<63). 12 type Source interface { 13 Int63() int64 14 Seed(seed int64) 15 } 16 17 // NewSource returns a new pseudo-random Source seeded with the given value. 18 func NewSource(seed int64) Source { 19 var rng rngSource 20 rng.Seed(seed) 21 return &rng 22 } 23 24 // A Rand is a source of random numbers. 25 type Rand struct { 26 src Source 27 } 28 29 // New returns a new Rand that uses random values from src 30 // to generate other random values. 31 func New(src Source) *Rand { return &Rand{src} } 32 33 // Seed uses the provided seed value to initialize the generator to a deterministic state. 34 func (r *Rand) Seed(seed int64) { r.src.Seed(seed) } 35 36 // Int63 returns a non-negative pseudo-random 63-bit integer as an int64. 37 func (r *Rand) Int63() int64 { return r.src.Int63() } 38 39 // Uint32 returns a pseudo-random 32-bit value as a uint32. 40 func (r *Rand) Uint32() uint32 { return uint32(r.Int63() >> 31) } 41 42 // Int31 returns a non-negative pseudo-random 31-bit integer as an int32. 43 func (r *Rand) Int31() int32 { return int32(r.Int63() >> 32) } 44 45 // Int returns a non-negative pseudo-random int. 46 func (r *Rand) Int() int { 47 u := uint(r.Int63()) 48 return int(u << 1 >> 1) // clear sign bit if int == int32 49 } 50 51 // Int63n returns, as an int64, a non-negative pseudo-random number in [0,n). 52 // It panics if n <= 0. 53 func (r *Rand) Int63n(n int64) int64 { 54 if n <= 0 { 55 panic("invalid argument to Int63n") 56 } 57 max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) 58 v := r.Int63() 59 for v > max { 60 v = r.Int63() 61 } 62 return v % n 63 } 64 65 // Int31n returns, as an int32, a non-negative pseudo-random number in [0,n). 66 // It panics if n <= 0. 67 func (r *Rand) Int31n(n int32) int32 { 68 if n <= 0 { 69 panic("invalid argument to Int31n") 70 } 71 max := int32((1 << 31) - 1 - (1<<31)%uint32(n)) 72 v := r.Int31() 73 for v > max { 74 v = r.Int31() 75 } 76 return v % n 77 } 78 79 // Intn returns, as an int, a non-negative pseudo-random number in [0,n). 80 // It panics if n <= 0. 81 func (r *Rand) Intn(n int) int { 82 if n <= 0 { 83 panic("invalid argument to Intn") 84 } 85 if n <= 1<<31-1 { 86 return int(r.Int31n(int32(n))) 87 } 88 return int(r.Int63n(int64(n))) 89 } 90 91 // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0). 92 func (r *Rand) Float64() float64 { return float64(r.Int63()) / (1 << 63) } 93 94 // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0). 95 func (r *Rand) Float32() float32 { return float32(r.Float64()) } 96 97 // Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n). 98 func (r *Rand) Perm(n int) []int { 99 m := make([]int, n) 100 for i := 0; i < n; i++ { 101 m[i] = i 102 } 103 for i := 0; i < n; i++ { 104 j := r.Intn(i + 1) 105 m[i], m[j] = m[j], m[i] 106 } 107 return m 108 } 109 110 /* 111 * Top-level convenience functions 112 */ 113 114 var globalRand = New(&lockedSource{src: NewSource(1)}) 115 116 // Seed uses the provided seed value to initialize the generator to a 117 // deterministic state. If Seed is not called, the generator behaves as 118 // if seeded by Seed(1). 119 func Seed(seed int64) { globalRand.Seed(seed) } 120 121 // Int63 returns a non-negative pseudo-random 63-bit integer as an int64. 122 func Int63() int64 { return globalRand.Int63() } 123 124 // Uint32 returns a pseudo-random 32-bit value as a uint32. 125 func Uint32() uint32 { return globalRand.Uint32() } 126 127 // Int31 returns a non-negative pseudo-random 31-bit integer as an int32. 128 func Int31() int32 { return globalRand.Int31() } 129 130 // Int returns a non-negative pseudo-random int. 131 func Int() int { return globalRand.Int() } 132 133 // Int63n returns, as an int64, a non-negative pseudo-random number in [0,n). 134 // It panics if n <= 0. 135 func Int63n(n int64) int64 { return globalRand.Int63n(n) } 136 137 // Int31n returns, as an int32, a non-negative pseudo-random number in [0,n). 138 // It panics if n <= 0. 139 func Int31n(n int32) int32 { return globalRand.Int31n(n) } 140 141 // Intn returns, as an int, a non-negative pseudo-random number in [0,n). 142 // It panics if n <= 0. 143 func Intn(n int) int { return globalRand.Intn(n) } 144 145 // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0). 146 func Float64() float64 { return globalRand.Float64() } 147 148 // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0). 149 func Float32() float32 { return globalRand.Float32() } 150 151 // Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n). 152 func Perm(n int) []int { return globalRand.Perm(n) } 153 154 // NormFloat64 returns a normally distributed float64 in the range 155 // [-math.MaxFloat64, +math.MaxFloat64] with 156 // standard normal distribution (mean = 0, stddev = 1). 157 // To produce a different normal distribution, callers can 158 // adjust the output using: 159 // 160 // sample = NormFloat64() * desiredStdDev + desiredMean 161 // 162 func NormFloat64() float64 { return globalRand.NormFloat64() } 163 164 // ExpFloat64 returns an exponentially distributed float64 in the range 165 // (0, +math.MaxFloat64] with an exponential distribution whose rate parameter 166 // (lambda) is 1 and whose mean is 1/lambda (1). 167 // To produce a distribution with a different rate parameter, 168 // callers can adjust the output using: 169 // 170 // sample = ExpFloat64() / desiredRateParameter 171 // 172 func ExpFloat64() float64 { return globalRand.ExpFloat64() } 173 174 type lockedSource struct { 175 lk sync.Mutex 176 src Source 177 } 178 179 func (r *lockedSource) Int63() (n int64) { 180 r.lk.Lock() 181 n = r.src.Int63() 182 r.lk.Unlock() 183 return 184 } 185 186 func (r *lockedSource) Seed(seed int64) { 187 r.lk.Lock() 188 r.src.Seed(seed) 189 r.lk.Unlock() 190 }