digitalmars.D.bugs - [Issue 21381] New: std.random.uniform!T(urng) when T is long or
- d-bugmail puremagic.com (46/46) Nov 12 2020 https://issues.dlang.org/show_bug.cgi?id=21381
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 puremagic.com Reporter: n8sh.secondary 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. } --- --
Nov 12 2020