Source file src/pkg/rand/rand.go
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 func (r *Rand) Int63n(n int64) int64 { 53 if n <= 0 { 54 return 0 55 } 56 max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) 57 v := r.Int63() 58 for v > max { 59 v = r.Int63() 60 } 61 return v % n 62 } 63 64 // Int31n returns, as an int32, a non-negative pseudo-random number in [0,n). 65 func (r *Rand) Int31n(n int32) int32 { 66 if n <= 0 { 67 return 0 68 } 69 max := int32((1 << 31) - 1 - (1<<31)%uint32(n)) 70 v := r.Int31() 71 for v > max { 72 v = r.Int31() 73 } 74 return v % n 75 } 76 77 // Intn returns, as an int, a non-negative pseudo-random number in [0,n). 78 func (r *Rand) Intn(n int) int { 79 if n <= 1<<31-1 { 80 return int(r.Int31n(int32(n))) 81 } 82 return int(r.Int63n(int64(n))) 83 } 84 85 // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0). 86 func (r *Rand) Float64() float64 { return float64(r.Int63()) / (1 << 63) } 87 88 // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0). 89 func (r *Rand) Float32() float32 { return float32(r.Float64()) } 90 91 // Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n). 92 func (r *Rand) Perm(n int) []int { 93 m := make([]int, n) 94 for i := 0; i < n; i++ { 95 m[i] = i 96 } 97 for i := 0; i < n; i++ { 98 j := r.Intn(i + 1) 99 m[i], m[j] = m[j], m[i] 100 } 101 return m 102 } 103 104 /* 105 * Top-level convenience functions 106 */ 107 108 var globalRand = New(&lockedSource{src: NewSource(1)}) 109 110 // Seed uses the provided seed value to initialize the generator to a deterministic state. 111 func Seed(seed int64) { globalRand.Seed(seed) } 112 113 // Int63 returns a non-negative pseudo-random 63-bit integer as an int64. 114 func Int63() int64 { return globalRand.Int63() } 115 116 // Uint32 returns a pseudo-random 32-bit value as a uint32. 117 func Uint32() uint32 { return globalRand.Uint32() } 118 119 // Int31 returns a non-negative pseudo-random 31-bit integer as an int32. 120 func Int31() int32 { return globalRand.Int31() } 121 122 // Int returns a non-negative pseudo-random int. 123 func Int() int { return globalRand.Int() } 124 125 // Int63n returns, as an int64, a non-negative pseudo-random number in [0,n). 126 func Int63n(n int64) int64 { return globalRand.Int63n(n) } 127 128 // Int31n returns, as an int32, a non-negative pseudo-random number in [0,n). 129 func Int31n(n int32) int32 { return globalRand.Int31n(n) } 130 131 // Intn returns, as an int, a non-negative pseudo-random number in [0,n). 132 func Intn(n int) int { return globalRand.Intn(n) } 133 134 // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0). 135 func Float64() float64 { return globalRand.Float64() } 136 137 // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0). 138 func Float32() float32 { return globalRand.Float32() } 139 140 // Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n). 141 func Perm(n int) []int { return globalRand.Perm(n) } 142 143 // NormFloat64 returns a normally distributed float64 in the range 144 // [-math.MaxFloat64, +math.MaxFloat64] with 145 // standard normal distribution (mean = 0, stddev = 1). 146 // To produce a different normal distribution, callers can 147 // adjust the output using: 148 // 149 // sample = NormFloat64() * desiredStdDev + desiredMean 150 // 151 func NormFloat64() float64 { return globalRand.NormFloat64() } 152 153 // ExpFloat64 returns an exponentially distributed float64 in the range 154 // (0, +math.MaxFloat64] with an exponential distribution whose rate parameter 155 // (lambda) is 1 and whose mean is 1/lambda (1). 156 // To produce a distribution with a different rate parameter, 157 // callers can adjust the output using: 158 // 159 // sample = ExpFloat64() / desiredRateParameter 160 // 161 func ExpFloat64() float64 { return globalRand.ExpFloat64() } 162 163 type lockedSource struct { 164 lk sync.Mutex 165 src Source 166 } 167 168 func (r *lockedSource) Int63() (n int64) { 169 r.lk.Lock() 170 n = r.src.Int63() 171 r.lk.Unlock() 172 return 173 } 174 175 func (r *lockedSource) Seed(seed int64) { 176 r.lk.Lock() 177 r.src.Seed(seed) 178 r.lk.Unlock() 179 }