Commit a2ffe3e6 authored by weeellz's avatar weeellz Committed by Brad Fitzpatrick

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/107135Reviewed-by: default avatarDaniel Martí <mvdan@mvdan.cc>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent aba0775a
...@@ -12,19 +12,16 @@ package rand ...@@ -12,19 +12,16 @@ package rand
*/ */
const ( const (
_LEN = 607 rngLen = 607
_TAP = 273 rngTap = 273
_MAX = 1 << 63 rngMax = 1 << 63
_MASK = _MAX - 1 rngMask = rngMax - 1
_A = 48271 int32max = (1 << 31) - 1
_M = (1 << 31) - 1
_Q = 44488
_R = 3399
) )
var ( var (
// Used for seeding. See gen_cooked.go for details. // rngCooked used for seeding. See gen_cooked.go for details.
rng_cooked [_LEN]int64 = [...]int64{ rngCooked [rngLen]int64 = [...]int64{
-4181792142133755926, -4576982950128230565, 1395769623340756751, 5333664234075297259, -4181792142133755926, -4576982950128230565, 1395769623340756751, 5333664234075297259,
-6347679516498800754, 9033628115061424579, 7143218595135194537, 4812947590706362721, -6347679516498800754, 9033628115061424579, 7143218595135194537, 4812947590706362721,
7937252194349799378, 5307299880338848416, 8209348851763925077, -7107630437535961764, 7937252194349799378, 5307299880338848416, 8209348851763925077, -7107630437535961764,
...@@ -181,18 +178,24 @@ var ( ...@@ -181,18 +178,24 @@ var (
) )
type rngSource struct { type rngSource struct {
tap int // index into vec tap int // index into vec
feed int // index into vec feed int // index into vec
vec [_LEN]int64 // current feedback register vec [rngLen]int64 // current feedback register
} }
// seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1) // seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1)
func seedrand(x int32) int32 { func seedrand(x int32) int32 {
hi := x / _Q const (
lo := x % _Q A = 48271
x = _A*lo - _R*hi Q = 44488
R = 3399
)
hi := x / Q
lo := x % Q
x = A*lo - R*hi
if x < 0 { if x < 0 {
x += _M x += int32max
} }
return x return x
} }
...@@ -200,18 +203,18 @@ func seedrand(x int32) int32 { ...@@ -200,18 +203,18 @@ func seedrand(x int32) int32 {
// Seed uses the provided seed value to initialize the generator to a deterministic state. // Seed uses the provided seed value to initialize the generator to a deterministic state.
func (rng *rngSource) Seed(seed int64) { func (rng *rngSource) Seed(seed int64) {
rng.tap = 0 rng.tap = 0
rng.feed = _LEN - _TAP rng.feed = rngLen - rngTap
seed = seed % _M seed = seed % int32max
if seed < 0 { if seed < 0 {
seed += _M seed += int32max
} }
if seed == 0 { if seed == 0 {
seed = 89482311 seed = 89482311
} }
x := int32(seed) x := int32(seed)
for i := -20; i < _LEN; i++ { for i := -20; i < rngLen; i++ {
x = seedrand(x) x = seedrand(x)
if i >= 0 { if i >= 0 {
var u int64 var u int64
...@@ -220,7 +223,7 @@ func (rng *rngSource) Seed(seed int64) { ...@@ -220,7 +223,7 @@ func (rng *rngSource) Seed(seed int64) {
u ^= int64(x) << 20 u ^= int64(x) << 20
x = seedrand(x) x = seedrand(x)
u ^= int64(x) u ^= int64(x)
u ^= rng_cooked[i] u ^= rngCooked[i]
rng.vec[i] = u rng.vec[i] = u
} }
} }
...@@ -228,19 +231,19 @@ func (rng *rngSource) Seed(seed int64) { ...@@ -228,19 +231,19 @@ func (rng *rngSource) Seed(seed int64) {
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64. // Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
func (rng *rngSource) Int63() 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. // Uint64 returns a non-negative pseudo-random 64-bit integer as an uint64.
func (rng *rngSource) Uint64() uint64 { func (rng *rngSource) Uint64() uint64 {
rng.tap-- rng.tap--
if rng.tap < 0 { if rng.tap < 0 {
rng.tap += _LEN rng.tap += rngLen
} }
rng.feed-- rng.feed--
if rng.feed < 0 { if rng.feed < 0 {
rng.feed += _LEN rng.feed += rngLen
} }
x := rng.vec[rng.feed] + rng.vec[rng.tap] x := rng.vec[rng.feed] + rng.vec[rng.tap]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment