digitalmars.D.bugs - [Issue 21382] New: std.random.uniform!T(urng) when T is an integer
- d-bugmail puremagic.com (55/55) Nov 12 2020 https://issues.dlang.org/show_bug.cgi?id=21382
https://issues.dlang.org/show_bug.cgi?id=21382 Issue ID: 21382 Summary: std.random.uniform!T(urng) when T is an integer type and urng.front is floating point is completely broken Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: phobos Assignee: nobody puremagic.com Reporter: n8sh.secondary hotmail.com 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)); } --- --
Nov 12 2020