4
4
// Arranged by DWANGO Co., Ltd.
5
5
6
6
export class Xorshift {
7
- private _state0U ! : number ;
8
- private _state0L ! : number ;
9
- private _state1U ! : number ;
10
- private _state1L ! : number ;
7
+ private _state0U : number ;
8
+ private _state0L : number ;
9
+ private _state1U : number ;
10
+ private _state1L : number ;
11
11
12
12
static deserialize ( ser : XorshiftSerialization ) : Xorshift {
13
- const ret = new Xorshift ( 0 ) ;
14
- ret . _state0U = ser . _state0U ;
15
- ret . _state0L = ser . _state0L ;
16
- ret . _state1U = ser . _state1U ;
17
- ret . _state1L = ser . _state1L ;
13
+ const ret = new Xorshift ( [ ser . _state0U , ser . _state0L , ser . _state1U , ser . _state1L ] ) ;
18
14
return ret ;
19
15
}
20
16
21
- constructor ( seed : number ) {
22
- this . initState ( seed ) ;
17
+ constructor ( seed : number | [ number , number , number , number ] ) {
18
+ const seeds = Array . isArray ( seed ) ? seed : this . generateSeeds ( seed ) ;
19
+
20
+ this . _state0U = seeds [ 0 ] | 0 ;
21
+ this . _state0L = seeds [ 1 ] | 0 ;
22
+ this . _state1U = seeds [ 2 ] | 0 ;
23
+ this . _state1L = seeds [ 3 ] | 0 ;
23
24
}
24
25
25
- // シード値が1つの場合にどのようにして初期状態を定義するかは特に定まっていない
26
- // このコードはロジック的な裏付けは無いが採用例が多いために採用した
27
- // 以下採用例
28
- // http://meme.biology.tohoku.ac.jp/klabo-wiki/index.php?cmd=read&page=%B7%D7%BB%BB%B5%A1%2FC%2B%2B#y919a7e1
29
- // http://hexadrive.sblo.jp/article/63660775.html
30
- // http://meme.biology.tohoku.ac.jp/students/iwasaki/cxx/random.html#xorshift
31
26
initState ( seed : number ) : void {
32
- const factor = 1812433253 ;
33
- seed = factor * ( seed ^ ( seed >> 30 ) ) + 1 ;
34
- this . _state0U = seed ;
35
- seed = factor * ( seed ^ ( seed >> 30 ) ) + 2 ;
36
- this . _state0L = seed ;
37
- seed = factor * ( seed ^ ( seed >> 30 ) ) + 3 ;
38
- this . _state1U = seed ;
39
- seed = factor * ( seed ^ ( seed >> 30 ) ) + 4 ;
40
- this . _state1L = seed ;
27
+ const seeds = this . generateSeeds ( seed ) ;
28
+ this . _state0L = seeds [ 0 ] | 0 ;
29
+ this . _state0U = seeds [ 1 ] | 0 ;
30
+ this . _state1L = seeds [ 2 ] | 0 ;
31
+ this . _state1U = seeds [ 3 ] | 0 ;
41
32
}
42
33
43
- randomInt ( ) : number [ ] {
34
+ randomInt ( ) : [ number , number ] {
44
35
let s1U = this . _state0U ;
45
36
let s1L = this . _state0L ;
46
37
const s0U = this . _state1U ;
47
38
const s0L = this . _state1L ;
48
39
40
+ const sumL = ( s0L >>> 0 ) + ( s1L >>> 0 ) ;
41
+ const resU = ( s0U + s1U + ( ( sumL / 2 ) >>> 31 ) ) >>> 0 ;
42
+ const resL = sumL >>> 0 ;
43
+
49
44
this . _state0U = s0U ;
50
45
this . _state0L = s0L ;
51
46
@@ -64,14 +59,14 @@ export class Xorshift {
64
59
t1U = s1U ^ s0U ;
65
60
t1L = s1L ^ s0L ;
66
61
67
- const a2 = 17 ;
62
+ const a2 = 18 ;
68
63
const m2 = 0xffffffff >>> ( 32 - a2 ) ;
69
64
t2U = s1U >>> a2 ;
70
65
t2L = ( s1L >>> a2 ) | ( ( s1U & m2 ) << ( 32 - a2 ) ) ;
71
66
t1U = t1U ^ t2U ;
72
67
t1L = t1L ^ t2L ;
73
68
74
- const a3 = 26 ;
69
+ const a3 = 5 ;
75
70
const m3 = 0xffffffff >>> ( 32 - a3 ) ;
76
71
t2U = s0U >>> a3 ;
77
72
t2L = ( s0L >>> a3 ) | ( ( s0U & m3 ) << ( 32 - a3 ) ) ;
@@ -81,16 +76,14 @@ export class Xorshift {
81
76
this . _state1U = t1U ;
82
77
this . _state1L = t1L ;
83
78
84
- const sumL = ( t1L >>> 0 ) + ( s0L >>> 0 ) ;
85
- t2U = ( t1U + s0U + ( ( sumL / 2 ) >>> 31 ) ) >>> 0 ;
86
- t2L = sumL >>> 0 ;
87
-
88
- return [ t2U , t2L ] ;
79
+ return [ resU , resL ] ;
89
80
}
90
81
91
82
random ( ) : number {
92
83
const t2 = this . randomInt ( ) ;
93
- return ( t2 [ 0 ] * 4294967296 + t2 [ 1 ] ) / 18446744073709551616 ;
84
+ // Math.pow(2, -32) = 2.3283064365386963e-10
85
+ // Math.pow(2, -52) = 2.220446049250313e-16
86
+ return t2 [ 0 ] * 2.3283064365386963e-10 + ( t2 [ 1 ] >>> 12 ) * 2.220446049250313e-16 ;
94
87
}
95
88
96
89
nextInt ( min : number , sup : number ) : number {
@@ -105,12 +98,30 @@ export class Xorshift {
105
98
_state1L : this . _state1L
106
99
} ;
107
100
}
101
+
102
+ // シード値が1つの場合にどのようにして初期状態を定義するかは特に定まっていない
103
+ // このコードはロジック的な裏付けは無いが採用例が多いために採用した
104
+ // 以下採用例
105
+ // http://meme.biology.tohoku.ac.jp/klabo-wiki/index.php?cmd=read&page=%B7%D7%BB%BB%B5%A1%2FC%2B%2B#y919a7e1
106
+ // http://hexadrive.sblo.jp/article/63660775.html
107
+ // http://meme.biology.tohoku.ac.jp/students/iwasaki/cxx/random.html#xorshift
108
+ private generateSeeds ( seed : number ) : [ number , number , number , number ] {
109
+ const factor = 1812433253 ;
110
+ seed = factor * ( seed ^ ( seed >> 30 ) ) + 1 ;
111
+ const seed1 = seed ;
112
+ seed = factor * ( seed ^ ( seed >> 30 ) ) + 2 ;
113
+ const seed2 = seed ;
114
+ seed = factor * ( seed ^ ( seed >> 30 ) ) + 3 ;
115
+ const seed3 = seed ;
116
+ seed = factor * ( seed ^ ( seed >> 30 ) ) + 4 ;
117
+ const seed4 = seed ;
118
+ return [ seed1 , seed2 , seed3 , seed4 ] ;
119
+ }
108
120
}
109
121
110
122
/**
111
123
* serialize/deserialize用のインターフェース
112
124
*/
113
-
114
125
export interface XorshiftSerialization {
115
126
/**
116
127
* @ignore
0 commit comments