[libmath-prime-util-perl] 11/16: Allow random_prime to use overridden rand
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:44:25 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.06
in repository libmath-prime-util-perl.
commit 2c3cc18d8ca3123954859f6bb637890df51724eb
Author: Dana Jacobsen <dana at acm.org>
Date: Mon Jun 11 17:11:37 2012 -0600
Allow random_prime to use overridden rand
---
Changes | 1 +
lib/Math/Prime/Util.pm | 24 +++++++++++++++++++++---
t/16-randomprime.t | 3 +++
util.c | 2 +-
4 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/Changes b/Changes
index 8e6a7e6..8fb3bc0 100644
--- a/Changes
+++ b/Changes
@@ -10,6 +10,7 @@ Revision history for Perl extension Math::Prime::Util.
say prime_count( 10**16, 10**16 + 2**20 )
- Add Ei(x), li(x), and R(x) functions.
- prime_count_approx uses R(x), making it vastly more accurate.
+ - Let user override rand for random_prime.
0.04 7 June 2012
- Didn't do tests on 32-bit machine before release. Test suite caught
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index 1801149..55619f9 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -124,23 +124,31 @@ sub random_prime {
my $range = $high - $low + 1;
my $prime;
+ # Note: I was using rand($range), but Math::Random::MT ignores the argument
+ # instead of following its documentation.
+ my $irandf = (exists &::rand) ? sub { return int(::rand()*shift); }
+ : sub { return int(rand()*shift); };
+
if ($high < 30000) {
# nice deterministic solution, but gets very costly with large values.
my $li = ($low == 2) ? 1 : prime_count($low);
my $hi = prime_count($high);
my $irange = $hi - $li + 1;
- my $rand = int(rand($irange));
+ my $rand = $irandf->($irange);
$prime = nth_prime($li + $rand);
} else {
# random loop
+ my $loop_limit = 2000 * 1000; # To protect against broken rand
if ($range <= 4294967295) {
do {
- $prime = $low + int(rand($range));
+ $prime = $low + $irandf->($range);
+ croak "Random function broken?" if $loop_limit-- < 0;
} while ( !($prime%2) || !($prime%3) || !is_prime($prime) );
} else {
do {
- my $rand = ( (int(rand(4294967295)) << 32) + int(rand(4294967295)) ) % $range;
+ my $rand = ( ($irandf->(4294967295) << 32) + $irandf->(4294967295) ) % $range;
$prime = $low + $rand;
+ croak "Random function broken?" if $loop_limit-- < 0;
} while ( !($prime%2) || !($prime%3) || !is_prime($prime) );
}
}
@@ -505,6 +513,16 @@ L<Crypt::Primes> or something similar. The current L<Math::Prime::Util>
module does not use strong randomness, and its primes are ridiculously small
by cryptographic standards.
+Perl's L<rand> function is normally called, but if the sub C<main::rand>
+exists, it will be used instead. When called with no arguments it should
+return a float value between 0 and 1-epsilon, with 32 bits of randomness.
+Examples:
+
+ # Use Mersenne Twister
+ use Math::Random::MT::Auto qw/rand/;
+
+ # Use my custom random function
+ sub rand { ... }
=head2 random_ndigit_prime
diff --git a/t/16-randomprime.t b/t/16-randomprime.t
index bb51aba..19c3b44 100644
--- a/t/16-randomprime.t
+++ b/t/16-randomprime.t
@@ -3,6 +3,9 @@ use strict;
use warnings;
use Test::More;
+#use Math::Random::MT qw/rand/;
+#use Math::Random::MT::Auto qw/rand/;
+#sub rand { return 0.5; }
use Math::Prime::Util qw/random_prime random_ndigit_prime is_prime/;
my $use64 = Math::Prime::Util::_maxbits > 32;
diff --git a/util.c b/util.c
index 39f5413..b59ec1d 100644
--- a/util.c
+++ b/util.c
@@ -713,7 +713,7 @@ UV nth_prime_approx(UV n)
else if (n < 12000) approx += 3.0 * order;
else if (n <150000) approx += 2.1 * order;
else if (n <200000000) approx += 0.0 * order;
- else approx += -0.023 * order;
+ else approx += -0.010 * order; /* -0.025 is better */
/* For all three analytical functions, it is possible that for a given valid
* input, we will not be able to return an output that fits in the UV type.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git
More information about the Pkg-perl-cvs-commits
mailing list