Skip Menu |
 

This queue is for tickets about the Math-BigInt-Random-OO CPAN distribution.

Report information
The Basics
Id: 81931
Status: new
Priority: 0/
Queue: Math-BigInt-Random-OO

People
Owner: Nobody in particular
Requestors: DANAJ [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.03
Fixed in: (no value)



Subject: Bad interaction with drand48
Download (untitled) / with headers
text/plain 1.7k
This relates to one of the CAVEAT notes in the documentation, and is really the fault of broken drand48, but it occurs on nearly every UNIX system as well as Cygwin, and interacts very badly with a common use case for Math::BigInt::Random::OO. See <https://rt.perl.org/rt3/Ticket/Display.html?id=115928#txn-1177386> for what I wrote up about CORE::rand. I was trying to get random integers of various digit lengths, and noticed that they all came out even. Some lengths work fine (e.g. 14), others do not (e.g. 15, 80). Test: perl -MMath::BigInt::Random::OO -E 'my $gen = Math::BigInt::Random::OO->new(length=>15); my $n = 50000; for (1..$n) { $freq{$gen->generate % 10}++ } printf("%4d %6.3f%%\n", $_, 100.0*$freq{$_}/$n) for sort {$a<=>$b} keys %freq;' 0 20.150% 2 19.964% 4 20.364% 6 19.796% 8 19.726% The final bit of CORE::rand (drand48) alternates. But the way Math::BigInt::Random::OO handles generating numbers of certain lengths guarantees we call the upper bits once, then the lower bits a certain number of times. For length 15 this is once, hence we always get a 0 ending bit. I've reproduced this on Fedora x86_64 64-bit, Debian i386 32-bit, Debian ia64 (Itanium 2) 64-bit, Debian sparc (US T1) 64-bit, Fedora ppc64 (Power7) 64-bit, NetBSD amd64 64-bit, and Cygwin i686 64-bit. Running a C program using drand48 on the x86_64 machine shows that it is the culprit. My preferred solution would be for Perl to make CORE::rand use an O/S specific good default seed, then a better RNG (e.g. MT or ISAAC). But barring that, perhaps something like: my $rand_bits = $Config{randbits}; $rand_bits-- if $rand_bits == 48; # Protect against broken drand48 I realize this is a workaround, and rather hackish, but this one line fix solves the problem on systems I've tested it on.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.