1
0
mirror of https://github.com/golang/go synced 2024-11-18 08:14:41 -07:00

math/rand: refactor rng.go

Made constant names more idiomatic,
moved some constants to function seedrand,
and found better name for _M.

Change-Id: I192172f398378bef486a5bbceb6ba86af48ebcc9
Reviewed-on: https://go-review.googlesource.com/107135
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
weeellz 2018-04-14 18:55:48 +03:00 committed by Brad Fitzpatrick
parent aba0775ad8
commit a2ffe3e625

View File

@ -12,19 +12,16 @@ package rand
*/
const (
_LEN = 607
_TAP = 273
_MAX = 1 << 63
_MASK = _MAX - 1
_A = 48271
_M = (1 << 31) - 1
_Q = 44488
_R = 3399
rngLen = 607
rngTap = 273
rngMax = 1 << 63
rngMask = rngMax - 1
int32max = (1 << 31) - 1
)
var (
// Used for seeding. See gen_cooked.go for details.
rng_cooked [_LEN]int64 = [...]int64{
// rngCooked used for seeding. See gen_cooked.go for details.
rngCooked [rngLen]int64 = [...]int64{
-4181792142133755926, -4576982950128230565, 1395769623340756751, 5333664234075297259,
-6347679516498800754, 9033628115061424579, 7143218595135194537, 4812947590706362721,
7937252194349799378, 5307299880338848416, 8209348851763925077, -7107630437535961764,
@ -181,18 +178,24 @@ var (
)
type rngSource struct {
tap int // index into vec
feed int // index into vec
vec [_LEN]int64 // current feedback register
tap int // index into vec
feed int // index into vec
vec [rngLen]int64 // current feedback register
}
// seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1)
func seedrand(x int32) int32 {
hi := x / _Q
lo := x % _Q
x = _A*lo - _R*hi
const (
A = 48271
Q = 44488
R = 3399
)
hi := x / Q
lo := x % Q
x = A*lo - R*hi
if x < 0 {
x += _M
x += int32max
}
return x
}
@ -200,18 +203,18 @@ func seedrand(x int32) int32 {
// Seed uses the provided seed value to initialize the generator to a deterministic state.
func (rng *rngSource) Seed(seed int64) {
rng.tap = 0
rng.feed = _LEN - _TAP
rng.feed = rngLen - rngTap
seed = seed % _M
seed = seed % int32max
if seed < 0 {
seed += _M
seed += int32max
}
if seed == 0 {
seed = 89482311
}
x := int32(seed)
for i := -20; i < _LEN; i++ {
for i := -20; i < rngLen; i++ {
x = seedrand(x)
if i >= 0 {
var u int64
@ -220,7 +223,7 @@ func (rng *rngSource) Seed(seed int64) {
u ^= int64(x) << 20
x = seedrand(x)
u ^= int64(x)
u ^= rng_cooked[i]
u ^= rngCooked[i]
rng.vec[i] = u
}
}
@ -228,19 +231,19 @@ func (rng *rngSource) Seed(seed int64) {
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
func (rng *rngSource) Int63() int64 {
return int64(rng.Uint64() & _MASK)
return int64(rng.Uint64() & rngMask)
}
// Uint64 returns a non-negative pseudo-random 64-bit integer as an uint64.
func (rng *rngSource) Uint64() uint64 {
rng.tap--
if rng.tap < 0 {
rng.tap += _LEN
rng.tap += rngLen
}
rng.feed--
if rng.feed < 0 {
rng.feed += _LEN
rng.feed += rngLen
}
x := rng.vec[rng.feed] + rng.vec[rng.tap]