[libmath-prime-util-perl] 24/29: Push full primality test into PP from Util.pm
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:48:17 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.27
in repository libmath-prime-util-perl.
commit 4bd921bf467a805b00b60dd908f7cb9978e6302a
Author: Dana Jacobsen <dana at acm.org>
Date: Sun May 19 00:15:56 2013 -0700
Push full primality test into PP from Util.pm
---
lib/Math/Prime/Util/PP.pm | 78 +++++++++++++++++++++++++++++++----------------
1 file changed, 51 insertions(+), 27 deletions(-)
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index d499f16..6d76fcd 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -140,31 +140,56 @@ sub _is_prime7 { # n must not be divisible by 2, 3, or 5
!($n % 37) || !($n % 41) || !($n % 43) || !($n % 47) ||
!($n % 53) || !($n % 59);
- return Math::Prime::Util::is_prob_prime($n) if $n > 10_000_000;
-
- my $limit = int(sqrt($n));
- my $i = 61;
- while (($i+30) <= $limit) {
- return 0 if !($n % $i); $i += 6;
- return 0 if !($n % $i); $i += 4;
- return 0 if !($n % $i); $i += 2;
- return 0 if !($n % $i); $i += 4;
- return 0 if !($n % $i); $i += 2;
- return 0 if !($n % $i); $i += 4;
- return 0 if !($n % $i); $i += 6;
- return 0 if !($n % $i); $i += 2;
+ if ($n <= 10_000_000) {
+ my $limit = int(sqrt($n));
+ my $i = 61;
+ while (($i+30) <= $limit) {
+ return 0 if !($n % $i); $i += 6;
+ return 0 if !($n % $i); $i += 4;
+ return 0 if !($n % $i); $i += 2;
+ return 0 if !($n % $i); $i += 4;
+ return 0 if !($n % $i); $i += 2;
+ return 0 if !($n % $i); $i += 4;
+ return 0 if !($n % $i); $i += 6;
+ return 0 if !($n % $i); $i += 2;
+ }
+ while (1) {
+ last if $i > $limit; return 0 if !($n % $i); $i += 6;
+ last if $i > $limit; return 0 if !($n % $i); $i += 4;
+ last if $i > $limit; return 0 if !($n % $i); $i += 2;
+ last if $i > $limit; return 0 if !($n % $i); $i += 4;
+ last if $i > $limit; return 0 if !($n % $i); $i += 2;
+ last if $i > $limit; return 0 if !($n % $i); $i += 4;
+ last if $i > $limit; return 0 if !($n % $i); $i += 6;
+ last if $i > $limit; return 0 if !($n % $i); $i += 2;
+ }
+ return 2;
}
- while (1) {
- last if $i > $limit; return 0 if !($n % $i); $i += 6;
- last if $i > $limit; return 0 if !($n % $i); $i += 4;
- last if $i > $limit; return 0 if !($n % $i); $i += 2;
- last if $i > $limit; return 0 if !($n % $i); $i += 4;
- last if $i > $limit; return 0 if !($n % $i); $i += 2;
- last if $i > $limit; return 0 if !($n % $i); $i += 4;
- last if $i > $limit; return 0 if !($n % $i); $i += 6;
- last if $i > $limit; return 0 if !($n % $i); $i += 2;
- }
- 2;
+
+ if ($n < 105936894253) { # BPSW seems to be faster after this
+ # Deterministic set of Miller-Rabin tests. If the MR routines can handle
+ # bases greater than n, then this can be simplified.
+ my @bases;
+ if ($n < 9080191) { @bases = (31, 73); }
+ elsif ($n < 19471033) { @bases = ( 2, 299417); }
+ elsif ($n < 38010307) { @bases = ( 2, 9332593); }
+ elsif ($n < 316349281) { @bases = ( 11000544, 31481107); }
+ elsif ($n < 4759123141) { @bases = ( 2, 7, 61); }
+ elsif ($n < 105936894253) { @bases = ( 2, 1005905886, 1340600841); }
+ elsif ($n < 31858317218647) { @bases = ( 2, 642735, 553174392, 3046413974); }
+ elsif ($n < 3071837692357849) { @bases = ( 2, 75088, 642735, 203659041, 3613982119); }
+ else { @bases = ( 2, 325, 9375, 28178, 450775, 9780504, 1795265022); }
+ return miller_rabin($n, @bases) ? 2 : 0;
+ }
+
+ # BPSW probable prime. No composites are known to have passed this test
+ # since it was published in 1980, though we know infinitely many exist.
+ # It has also been verified that no 64-bit composite will return true.
+ # Slow since it's all in PP, but it's the Right Thing To Do.
+
+ return 0 unless miller_rabin($n, 2);
+ return 0 unless is_strong_lucas_pseudoprime($n);
+ return ($n <= 18446744073709551615) ? 2 : 1;
}
sub is_prime {
@@ -173,7 +198,6 @@ sub is_prime {
return 2 if ($n == 2) || ($n == 3) || ($n == 5); # 2, 3, 5 are prime
return 0 if $n < 7; # everything else below 7 is composite
- # multiples of 2,3,5 are composite
return 0 if !($n % 2) || !($n % 3) || !($n % 5);
return _is_prime7($n);
}
@@ -1147,7 +1171,7 @@ sub trial_factor {
$n = int($n->bstr) if ref($n) eq 'Math::BigInt' && $n <= ''.~0;
return @factors if $n < 4;
- my $limit = int( sqrt($n) + 0.001);
+ my $limit = int(sqrt($n) + 0.001);
$limit = $maxlim if $limit > $maxlim;
my $f = 7;
SEARCH: while ($f <= $limit) {
@@ -1946,7 +1970,7 @@ sub primality_proof_bls75 {
next unless scalar @ftry > 1;
# Process each factor
foreach my $f (@ftry) {
- croak "Invalid factoring" if $f == 1 || $f == $m || ($B%$f) != 0;
+ croak "Invalid factoring: B=$B m=$m f=$f" if $f == 1 || $f == $m || ($B%$f) != 0;
if (Math::Prime::Util::is_prob_prime($f)) {
push @factors, $f;
do { $B /= $f; $A *= $f; } while (($B % $f) == 0);
--
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