[Issue 21381] New: std.random.uniform!T(urng) when T is long or ulong and urng.front is signed int will be biased in its high bits
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Nov 13 02:43:48 UTC 2020
https://issues.dlang.org/show_bug.cgi?id=21381
Issue ID: 21381
Summary: std.random.uniform!T(urng) when T is long or ulong and
urng.front is signed int will be biased in its high
bits
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 long or ulong and urng.front is signed int
will be biased in its high bits. No pseudorandom number generators defined in
std.random produce signed integers but nothing in the function constraints or
documentation advises library users against defining a custom PRNG that does.
Demonstration:
---
void main()
{
import std.random : isUniformRNG, uniform;
import std.stdio : writefln;
static struct SignedIntLCG
{
enum bool isUniformRandom = true;
enum int min = int.min;
enum int max = int.max;
enum bool empty = false;
int front;
void popFront() { front = front * 0xac564b05 + 1; }
}
static assert(isUniformRNG!SignedIntLCG);
// The higher bits of uniform!long(signedIntLCG) are biased towards
// non-zero with increasing probability. The highest bit of
// uniform!ulong(signedIntLCG) has a 75% chance of being non-zero.
auto signedIntLCG = SignedIntLCG(123456789);
size_t timesHighBitWas1 = 0;
foreach (_; 0 .. 1_000_000)
timesHighBitWas1 += uniform!ulong(signedIntLCG) >>> 63;
writefln("%,d", timesHighBitWas1); // Outputs 750,158.
}
---
--
More information about the Digitalmars-d-bugs
mailing list