真の一様分布を得るため、分布で割った余りを使用する方法から
分布でスケーリングした範囲を割り算する方法に変更
+static const u32b Rand_Xorshift_max = 0xFFFFFFFF;
+
/*
* Initialize the RNG using a new seed
*/
/*
* Initialize the RNG using a new seed
*/
/*
* Extract a "random" number from 0 to m-1, via "division"
*/
/*
* Extract a "random" number from 0 to m-1, via "division"
*/
+static s32b Rand_div_impl(s32b m, u32b* state)
+ u32b scaling;
+ u32b past;
+ u32b ret;
+
/* Hack -- simple case */
if (m <= 1) return (0);
/* Hack -- simple case */
if (m <= 1) return (0);
- /* Use the value */
- return Rand_Xorshift(Rand_state) % m;
+ scaling = Rand_Xorshift_max / m;
+ past = scaling * m;
+
+ do {
+ ret = Rand_Xorshift(state);
+ } while (ret >= past);
+
+ return ret / scaling;
+}
+
+s32b Rand_div(s32b m)
+{
+ return Rand_div_impl(m, Rand_state);
- return Rand_Xorshift(Rand_state_external) % m;
+ return Rand_div_impl(m, Rand_state_external);
extern void Rand_state_init(u32b seed);
extern void Rand_state_backup(u32b* backup_state);
extern void Rand_state_restore(u32b* backup_state);
extern void Rand_state_init(u32b seed);
extern void Rand_state_backup(u32b* backup_state);
extern void Rand_state_restore(u32b* backup_state);
-extern s32b Rand_div(u32b m);
+extern s32b Rand_div(s32b m);
extern s16b randnor(int mean, int stand);
extern s16b damroll(int num, int sides);
extern s16b maxroll(int num, int sides);
extern s16b randnor(int mean, int stand);
extern s16b damroll(int num, int sides);
extern s16b maxroll(int num, int sides);