Comment #0 by n8sh.secondary — 2020-11-13T02:44:47Z
std.random.uniform!T(urng) when T is an integer type and urng.front is floating point is completely broken
std.random.uniform!T(urng) when T is an integer type and urng.front is floating point is completely broken. No predefined generators in std.random have floating point ElementType but user-defined generators might.
Demonstration:
---
void main()
{
import std.random : isUniformRNG, uniform;
static bool isEveryResultZero(T,RNG)(ref RNG rng, size_t numTrials)
{
foreach (_; 0 .. numTrials)
if (uniform!T(rng) != 0)
return false;
return true;
}
static struct Double01PRNG
{
enum bool isUniformRandom = true;
enum double min = 0.0;
enum double max = (ulong.max >>> (64 - 53)) * 0x1p-53;
enum bool empty = false;
ulong state;
@property double front() const {
auto result = (state >>> (64 - 53)) * 0x1p-53;
assert(result >= 0 && result < 1);
return result;
}
void popFront() { state = state * 2862933555777941757 + 1; }
}
static assert(isUniformRNG!Double01PRNG);
// The following assertions pass but should not.
auto double01PRNG = Double01PRNG(123456789);
assert(isEveryResultZero!int(double01PRNG, 1_000_000));
assert(isEveryResultZero!uint(double01PRNG, 1_000_000));
assert(isEveryResultZero!long(double01PRNG, 1_000_000));
assert(isEveryResultZero!ulong(double01PRNG, 1_000_000));
}
---
Comment #1 by dlang-bot — 2020-11-17T22:23:26Z
@n8sh created dlang/phobos pull request #7697 "std.random.uniform!T(urng) when T is an integer type and urng.front is floating point is broken" fixing this issue:
- Fix Issue 21382 - std.random.uniform!T(urng) when T is an integer type and urng.front is floating point is broken
https://github.com/dlang/phobos/pull/7697
Comment #2 by robert.schadek — 2024-12-01T16:37:53Z