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