[Issue 21382] New: std.random.uniform!T(urng) when T is an integer type and urng.front is floating point is completely broken
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Nov 13 02:44:47 UTC 2020
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 at puremagic.com
Reporter: n8sh.secondary at 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));
}
---
--
More information about the Digitalmars-d-bugs
mailing list