-
Notifications
You must be signed in to change notification settings - Fork 0
/
mt.go
56 lines (47 loc) · 1.2 KB
/
mt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//伪随机算法(梅森旋转)
package mt
type Random struct {
index int
mt [624]uint32
}
func UInt32(x int64) uint32 {
return uint32(0xFFFFFFFF & x)
}
func NewRandom(seed uint32) *Random {
random := &Random{index:624}
random.mt[0] = seed
for i := 1; i < 624; i++ {
random.mt[i] = UInt32(1812433253*(int64(random.mt[i-1])^int64(random.mt[i-1])>>30) + int64(i))
}
return random
}
func (random *Random) twist() {
for i := 0; i < 624; i++ {
y := UInt32((int64(random.mt[i]) & 0x80000000) + (int64(random.mt[(i+1)%624]) & 0x7fffffff))
random.mt[i] = random.mt[(i+397)%624] ^ y>>1
if y%2 != 0 {
random.mt[i] = random.mt[i] ^ 0x9908b0df
}
}
random.index = 0
}
func (random *Random) Next() uint32 {
if random.index >= 624 {
random.twist()
}
y := int64(random.mt[random.index])
//Right shift by 11 bits
y = y ^ y>>11
//Shift y left by 7 and take the bitwise and of 2636928640
y = y ^ y<<7&2636928640
//Shift y left by 15 and take the bitwise and of y and 4022730752
y = y ^ y<<15&4022730752
//Right shift by 18 bits
y = y ^ y>>18
random.index = random.index + 1
return UInt32(y)
}
func (random *Random) Rand(max int) int {
rand := random.Next()
return int(rand%uint32(max)) + 1
}