-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxorshift.go
131 lines (114 loc) · 2.62 KB
/
xorshift.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"fmt"
"os"
"strconv"
)
var initial_seed = 88172645463325252
var xorshift64_state_var = xorshift64_state{a: uint64(initial_seed)}
const XORSHIFT128_STATE_CAPACITY = 4
type xorshift32_state struct {
a uint32
}
type xorshift64_state struct {
a uint64
}
type xorshift128_state struct {
x [XORSHIFT128_STATE_CAPACITY]uint32
}
//The state word must be initialized to non-zero
func xorshift32(state *xorshift32_state) uint32 {
// Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs"
x := state.a
x ^= (x << 13)
x ^= (x >> 17)
x ^= (x << 5)
state.a = x
return x
}
func xorshift64(state *xorshift64_state) uint64 {
x := state.a
x ^= (x << 13)
x ^= (x >> 7)
x ^= (x << 17)
state.a = x
return x
}
// The state array must be initialized to not be all zero
func xorshift128(state *xorshift128_state) uint32 {
t := state.x[3]
s := state.x[0] //Perform a contrived 32-bit shift.
state.x[3] = state.x[2]
state.x[2] = state.x[1]
state.x[1] = s
t ^= t << 11
t ^= t >> 8
tss := t ^ s ^ (s >> 19)
state.x[0] = tss
return tss
}
func squeeze_range_float(ll uint64, ul uint64, r float64) float64 {
val := float64(ll) + float64((ul-ll+1))*r
return val
}
func squeeze_range_int(ll int64, ul int64, r float64) int64 {
val := float64(ll) + float64((ul-ll+1))*r
return int64(val)
}
func generate_random_number() float64 {
xorshift64(&xorshift64_state_var)
ran := float64(xorshift64_state_var.a) / float64(1<<63)
if ran > 1 {
ran = ran - float64(int64(ran))
}
return ran
}
func generate(ll int64, ul int64, how_many int64) []int64 {
i := 0
var m_a_p = make(map[int64]string)
var x = make([]int64, how_many)
for i < int(how_many) {
ran_num := squeeze_range_int(ll, ul, generate_random_number())
_, ok := m_a_p[ran_num]
if !ok {
x[i] = ran_num
m_a_p[ran_num] = ""
i++
}
}
return x
}
func usage() {
fmt.Printf("Usage: go run xorshift.go <lower-limit> <upper-limit> <how-many>\n")
}
func validate_args() (int64, int64, int64) {
var temp = make([]int64, 3)
for i := 1; i < len(os.Args); i++ {
el, err := strconv.Atoi(string(os.Args[i]))
if err != nil {
fmt.Println(err)
os.Exit(2)
}
temp[i-1] = int64(el)
}
if temp[2] > temp[1]-temp[0]+1 {
usage()
panic("LimitsMismatch")
}
if temp[0] > temp[1] {
usage()
panic("LimitsMismatch")
}
return temp[0], temp[1], temp[2]
}
func main() {
if len(os.Args) < 4 {
usage()
os.Exit(1)
}
m1, m2, n := validate_args()
res := generate(m1, m2, n)
for i := 0; i < len(res); i++ {
fmt.Println(res[i])
}
}