• R/O
  • HTTP
  • SSH
  • HTTPS

hengband: コミット

変愚蛮怒のメインリポジトリです


コミットメタ情報

リビジョン37914826914741b0a391907e8d60bd79d7501bbd (tree)
日時2017-07-26 00:27:54
作者Habu <habu@user...>
コミッターHabu

ログメッセージ

RNGをXoroshiro128+に変更

Xoroshiro128+はXorshift系のRNGで、現在最も質が良く速いとされている。
通常は64bit型変数で実装するが、変愚蛮怒は歴史上32bit型変数までしか使用しないので32bitの変数2つを1組として扱い、64bitのXOR・シフト・ローテート・足し算を自前で実装した。

変更サマリ

差分

--- a/src/z-rand.c
+++ b/src/z-rand.c
@@ -70,6 +70,65 @@ u32b Rand_state[RAND_DEG] = {
7070 };
7171
7272
73+typedef struct {
74+ u32b dw[2];
75+} u64b;
76+
77+static u64b u64b_xor(u64b a, u64b b)
78+{
79+ u64b result;
80+
81+ result.dw[0] = a.dw[0] ^ b.dw[0];
82+ result.dw[1] = a.dw[1] ^ b.dw[1];
83+
84+ return result;
85+}
86+
87+static u64b u64b_shiftl(u64b x, int k)
88+{
89+ u64b result;
90+
91+ if (k < 32) {
92+ result.dw[1] = (x.dw[1] << k) | (x.dw[0] >> (32 - k));
93+ result.dw[0] = (x.dw[0] << k);
94+ }
95+ else {
96+ result.dw[1] = (x.dw[0] << (k - 32));
97+ result.dw[0] = 0;
98+ }
99+
100+ return result;
101+}
102+
103+static u64b u64b_rotl(u64b x, int k)
104+{
105+ u64b result;
106+
107+ if (k < 32) {
108+ result.dw[0] = (x.dw[0] << k) | (x.dw[1] >> (32 - k));
109+ result.dw[1] = (x.dw[1] << k) | (x.dw[0] >> (32 - k));
110+ }
111+ else {
112+ result.dw[0] = (x.dw[0] >> (64 - k)) | (x.dw[1] << (k - 32));
113+ result.dw[1] = (x.dw[1] >> (64 - k)) | (x.dw[0] << (k - 32));
114+ }
115+
116+ return result;
117+}
118+
119+static u64b u64b_add(u64b a, u64b b)
120+{
121+ u64b result;
122+
123+ result.dw[0] = a.dw[0] + b.dw[0];
124+ result.dw[1] = a.dw[1] + b.dw[1];
125+
126+ if (result.dw[0] < a.dw[0])
127+ result.dw[1] ++;
128+
129+ return result;
130+}
131+
73132 /*
74133 * Initialize Xorshift Algorithm state
75134 */
@@ -84,6 +143,7 @@ static void Rand_Xorshift_seed(u32b seed, u32b* state)
84143 }
85144 }
86145
146+#if 0
87147 /*
88148 * Xorshift Algorithm
89149 */
@@ -99,6 +159,23 @@ static u32b Rand_Xorshift(u32b* state)
99159
100160 return state[3];
101161 }
162+#endif
163+
164+/*
165+ * Xoroshiro128+ Algorithm
166+ */
167+static u32b Rand_Xoroshiro128plus(u32b* state)
168+{
169+ const u64b s0 = *((u64b*)state);
170+ u64b s1 = *((u64b*)state + 1);
171+ const u64b result = u64b_add(s0, s1);
172+
173+ s1 = u64b_xor(s0, s1);
174+ *((u64b*)state) = u64b_xor(u64b_xor(u64b_rotl(s0, 55), s1), u64b_shiftl(s1, 14));
175+ *((u64b*)state + 1) = u64b_rotl(s1, 36);
176+
177+ return result.dw[0];
178+}
102179
103180 static const u32b Rand_Xorshift_max = 0xFFFFFFFF;
104181
@@ -189,7 +266,7 @@ static s32b Rand_div_impl(s32b m, u32b* state)
189266 past = scaling * m;
190267
191268 do {
192- ret = Rand_Xorshift(state);
269+ ret = Rand_Xoroshiro128plus(state);
193270 } while (ret >= past);
194271
195272 return ret / scaling;
旧リポジトリブラウザで表示