Skip to content

Commit 59f1a3d

Browse files
committed
Add unittest for Mersenne Twisters with non-standard word size
The word size for `MersenneTwisterEngine` is determined by the template parameter `w`, not `UIntType`. For example, a generator with identical parameters to the standard `Mt19937` but with a `ulong` wordtype should not produce different results to the standard `uint`-based generator. This patch adds unittests for the first and 10_000'th values of the sequences generated by a variety of Mersenne Twister implementations with non-standard template parameter values. The values in this unittest can be validated by comparison to C++11 by compiling and running the following C++ program: /****************************************************************/ template<class UIntType, size_t w> void mt_result () { std::mersenne_twister_engine< UIntType, w, 624, 397, 31, 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15, 0xefc60000, 18, 1812433253> gen; gen.seed(std::mt19937::default_seed); std::cout << gen() << std::endl; for (int i = 0; i < 9998; ++i) gen(); std::cout << gen() << std::endl; std::cout << std::endl; } int main () { mt_result<uint32_t, 32>(); mt_result<uint64_t, 32>(); mt_result<uint64_t, 48>(); mt_result<uint64_t, 64>(); } /****************************************************************/ Note that the `for` loop in this example advances the generator 9998 times compared to the D unittest's `popFrontN(9999)` because the first `gen()` call already advances the generator once.
1 parent 45c515f commit 59f1a3d

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

std/random.d

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,8 +956,20 @@ alias Mt19937_64 = MersenneTwisterEngine!(ulong, 64, 312, 156, 31,
956956
0x9d2c5680, 15,
957957
0xefc60000, 18, 1812433253);
958958

959-
foreach (R; std.meta.AliasSeq!(MT!(uint, 32), MT!(ulong, 32), MT!(ulong, 48), MT!(ulong, 64)))
959+
ulong[] expectedFirstValue = [3499211612uL, 3499211612uL,
960+
171143175841277uL, 1145028863177033374uL];
961+
962+
ulong[] expected10kValue = [4123659995uL, 4123659995uL,
963+
51991688252792uL, 3031481165133029945uL];
964+
965+
foreach (i, R; std.meta.AliasSeq!(MT!(uint, 32), MT!(ulong, 32), MT!(ulong, 48), MT!(ulong, 64)))
966+
{
960967
auto a = R();
968+
a.seed(a.defaultSeed); // checks that some alternative paths in `seed` are utilized
969+
assert(a.front == expectedFirstValue[i]);
970+
a.popFrontN(9999);
971+
assert(a.front == expected10kValue[i]);
972+
}
961973
}
962974

963975

0 commit comments

Comments
 (0)