mirror of
https://github.com/dlang/phobos.git
synced 2025-04-27 05:30:33 +03:00
Fix issue 21609 - LinearCongruentialEngine fails for m = 0
This commit is contained in:
parent
d7b98833ce
commit
df10d1e331
1 changed files with 31 additions and 2 deletions
33
std/random.d
33
std/random.d
|
@ -425,7 +425,7 @@ template isSeedable(Rng)
|
|||
}
|
||||
|
||||
/**
|
||||
Linear Congruential generator.
|
||||
Linear Congruential generator. When m = 0, no modulus is used.
|
||||
*/
|
||||
struct LinearCongruentialEngine(UIntType, UIntType a, UIntType c, UIntType m)
|
||||
if (isUnsigned!UIntType)
|
||||
|
@ -603,7 +603,15 @@ Always `false` (random generators are infinite ranges).
|
|||
*/
|
||||
enum bool empty = false;
|
||||
|
||||
private UIntType _x = m ? (a + c) % m : (a + c);
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21610
|
||||
static if (m)
|
||||
{
|
||||
private UIntType _x = (a + c) % m;
|
||||
}
|
||||
else
|
||||
{
|
||||
private UIntType _x = a + c;
|
||||
}
|
||||
}
|
||||
|
||||
/// Declare your own linear congruential engine
|
||||
|
@ -628,6 +636,27 @@ Always `false` (random generators are infinite ranges).
|
|||
auto n = rnd.front; // different across runs
|
||||
}
|
||||
|
||||
/// Declare your own linear congruential engine
|
||||
@safe unittest
|
||||
{
|
||||
// Visual C++'s LCG
|
||||
alias MSVCLCG = LinearCongruentialEngine!(uint, 214013, 2531011, 0);
|
||||
|
||||
// seed with a constant
|
||||
auto rnd = MSVCLCG(1);
|
||||
auto n = rnd.front; // same for each run
|
||||
assert(n == 2745024);
|
||||
}
|
||||
|
||||
// Ensure that unseeded LCGs produce correct values
|
||||
@safe unittest
|
||||
{
|
||||
alias LGE = LinearCongruentialEngine!(uint, 10000, 19682, 19683);
|
||||
|
||||
LGE rnd;
|
||||
assert(rnd.front == 9999);
|
||||
}
|
||||
|
||||
/**
|
||||
Define $(D_PARAM LinearCongruentialEngine) generators with well-chosen
|
||||
parameters. `MinstdRand0` implements Park and Miller's "minimal
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue