OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package rand implements pseudo-random number generators. | 5 // Package rand implements pseudo-random number generators. |
6 // | 6 // |
7 // Random numbers are generated by a Source. Top-level functions, such as | 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 | 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 | 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. | 10 // initialize the default Source if different behavior is required for each run. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 if n <= 0 { | 94 if n <= 0 { |
95 panic("invalid argument to Intn") | 95 panic("invalid argument to Intn") |
96 } | 96 } |
97 if n <= 1<<31-1 { | 97 if n <= 1<<31-1 { |
98 return int(r.Int31n(int32(n))) | 98 return int(r.Int31n(int32(n))) |
99 } | 99 } |
100 return int(r.Int63n(int64(n))) | 100 return int(r.Int63n(int64(n))) |
101 } | 101 } |
102 | 102 |
103 // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0). | 103 // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0). |
104 func (r *Rand) Float64() float64 { return float64(r.Int63n(1<<53)) / (1 << 53) } | 104 func (r *Rand) Float64() float64 { |
| 105 » // A clearer, simpler implementation would be: |
| 106 » //» return float64(r.Int63n(1<<53)) / (1<<53) |
| 107 » // However, Go 1 shipped with |
| 108 » //» return float64(r.Int63()) / (1 << 63) |
| 109 » // and we want to preserve that value stream. |
| 110 » // |
| 111 » // There is one bug in the value stream: r.Int63() may be so close |
| 112 » // to 1<<63 that the division rounds up to 1.0, and we've guaranteed |
| 113 » // that the result is always less than 1.0. To fix that, we treat the |
| 114 » // range as cyclic and map 1 back to 0. This is justified by observing |
| 115 » // that while some of the values rounded down to 0, nothing was |
| 116 » // rounding up to 0, so 0 was underrepresented in the results. |
| 117 » // Mapping 1 back to zero restores some balance. |
| 118 » // (The balance is not perfect because the implementation |
| 119 » // returns denormalized numbers for very small r.Int63(), |
| 120 » // and those steal from what would normally be 0 results.) |
| 121 » // The remapping only happens 1/2⁵³ of the time, so most clients |
| 122 » // will not observe it anyway. |
| 123 » f := float64(r.Int63()) / (1 << 63) |
| 124 » if f == 1 { |
| 125 » » f = 0 |
| 126 » } |
| 127 » return f |
| 128 } |
105 | 129 |
106 // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0). | 130 // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0). |
107 func (r *Rand) Float32() float32 { return float32(r.Int31n(1<<24)) / (1 << 24) } | 131 func (r *Rand) Float32() float32 { |
| 132 » // Same rationale as in Float64: we want to preserve the Go 1 value |
| 133 » // stream except we want to fix it not to return 1.0 |
| 134 » // There is a double rounding going on here, but the argument for |
| 135 » // mapping 1 to 0 still applies: 0 was underrepresented before, |
| 136 » // so mapping 1 to 0 doesn't cause too many 0s. |
| 137 » // This only happens 1/2²⁴ of the time (plus the 1/2⁵³ of the time in Fl
oat64). |
| 138 » f := float32(r.Float64()) |
| 139 » if f == 1 { |
| 140 » » f = 0 |
| 141 » } |
| 142 » return f |
| 143 } |
108 | 144 |
109 // Perm returns, as a slice of n ints, a pseudo-random permutation of the intege
rs [0,n). | 145 // Perm returns, as a slice of n ints, a pseudo-random permutation of the intege
rs [0,n). |
110 func (r *Rand) Perm(n int) []int { | 146 func (r *Rand) Perm(n int) []int { |
111 m := make([]int, n) | 147 m := make([]int, n) |
112 for i := 0; i < n; i++ { | 148 for i := 0; i < n; i++ { |
113 j := r.Intn(i + 1) | 149 j := r.Intn(i + 1) |
114 m[i] = m[j] | 150 m[i] = m[j] |
115 m[j] = i | 151 m[j] = i |
116 } | 152 } |
117 return m | 153 return m |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 n = r.src.Int63() | 237 n = r.src.Int63() |
202 r.lk.Unlock() | 238 r.lk.Unlock() |
203 return | 239 return |
204 } | 240 } |
205 | 241 |
206 func (r *lockedSource) Seed(seed int64) { | 242 func (r *lockedSource) Seed(seed int64) { |
207 r.lk.Lock() | 243 r.lk.Lock() |
208 r.src.Seed(seed) | 244 r.src.Seed(seed) |
209 r.lk.Unlock() | 245 r.lk.Unlock() |
210 } | 246 } |
OLD | NEW |