[libmath-prime-util-perl] 07/59: Speedup for PP is_prime and factor
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:44:52 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.10
in repository libmath-prime-util-perl.
commit 5c2f08309a3466269a71a938ca06df705e5dc37a
Author: Dana Jacobsen <dana at acm.org>
Date: Thu Jun 28 12:48:24 2012 -0600
Speedup for PP is_prime and factor
---
lib/Math/Prime/Util/PP.pm | 51 ++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 20 deletions(-)
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index d49901d..3c0e81a 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -68,24 +68,35 @@ my @_nextwheel30 = (1,7,7,7,7,7,7,11,11,11,11,13,13,17,17,17,17,19,19,23,23,23,2
my @_prevwheel30 = (29,29,1,1,1,1,1,1,7,7,7,7,11,11,13,13,13,13,17,17,19,19,19,19,23,23,23,23,23,23);
sub _is_prime7 { # n must not be divisible by 2, 3, or 5
- my($x) = @_;
- my $q;
- foreach my $i (qw/7 11 13 17 19 23 29 31 37 41 43 47 53 59/) {
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i);
- }
+ my($n) = @_;
- return is_prob_prime($x) if $x > 10_000_000;
+ return is_prob_prime($n) if (~0 == 18446744073709551615) && ($n > 10_000_000);
- my $i = 61; # mod-30 loop
+ foreach my $i (qw/7 11 13 17 19 23 29/) {
+ return 2 if $i*$i > $n;
+ return 0 if ($n % $i) == 0;
+ }
+ my $limit = int(sqrt($n));
+ my $i = 31;
+ while (($i+30) <= $limit) {
+ return 0 if ($n % $i) == 0; $i += 6;
+ return 0 if ($n % $i) == 0; $i += 4;
+ return 0 if ($n % $i) == 0; $i += 2;
+ return 0 if ($n % $i) == 0; $i += 4;
+ return 0 if ($n % $i) == 0; $i += 2;
+ return 0 if ($n % $i) == 0; $i += 4;
+ return 0 if ($n % $i) == 0; $i += 6;
+ return 0 if ($n % $i) == 0; $i += 2;
+ }
while (1) {
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i); $i += 6;
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i); $i += 4;
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i); $i += 2;
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i); $i += 4;
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i); $i += 2;
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i); $i += 4;
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i); $i += 6;
- $q = int($x/$i); return 2 if $q < $i; return 0 if $x == ($q*$i); $i += 2;
+ last if $i > $limit; return 0 if ($n % $i) == 0; $i += 6;
+ last if $i > $limit; return 0 if ($n % $i) == 0; $i += 4;
+ last if $i > $limit; return 0 if ($n % $i) == 0; $i += 2;
+ last if $i > $limit; return 0 if ($n % $i) == 0; $i += 4;
+ last if $i > $limit; return 0 if ($n % $i) == 0; $i += 2;
+ last if $i > $limit; return 0 if ($n % $i) == 0; $i += 4;
+ last if $i > $limit; return 0 if ($n % $i) == 0; $i += 6;
+ last if $i > $limit; return 0 if ($n % $i) == 0; $i += 2;
}
2;
}
@@ -93,9 +104,9 @@ sub _is_prime7 { # n must not be divisible by 2, 3, or 5
sub is_prime {
my($n) = @_;
croak "Input must be an integer" unless defined $_[0];
- return 0 if $n < 2; # 0 and 1 are composite
return 2 if ($n == 2) || ($n == 3) || ($n == 5); # 2, 3, 5 are prime
- # multiples of 2,3,5 are composite
+ return 0 if $n < 7; # everything else below 7 is composite
+ # multiples of 2,3,5 are composite
return 0 if (($n % 2) == 0) || (($n % 3) == 0) || (($n % 5) == 0);
return _is_prime7($n);
@@ -664,7 +675,7 @@ sub is_prob_prime {
# Run our selected set of Miller-Rabin strong probability tests
my $prob_prime = miller_rabin($n, @bases);
# We're deterministic for 64-bit numbers
- $prob_prime *= 2 if $n <= ~0;
+ $prob_prime *= 2 if $n <= 18446744073709551615;
$prob_prime;
}
@@ -675,7 +686,7 @@ sub _basic_factor {
while ( ($_[0] % 2) == 0 ) { push @factors, 2; $_[0] /= 2; }
while ( ($_[0] % 3) == 0 ) { push @factors, 3; $_[0] /= 3; }
while ( ($_[0] % 5) == 0 ) { push @factors, 5; $_[0] /= 5; }
- if (is_prime($_[0])) {
+ if ( ($_[0] > 1) && _is_prime7($_[0]) ) {
push @factors, $_[0];
$_[0] = 1;
}
@@ -726,7 +737,7 @@ sub factor {
while (@nstack) {
$n = pop @nstack;
#print "Looking at $n with stack ", join(",", at nstack), "\n";
- while ( ($n >= (31*31)) && !is_prime($n) ) {
+ while ( ($n >= (31*31)) && !_is_prime7($n) ) {
my @ftry;
@ftry = prho_factor($n, 64*1024);
@ftry = holf_factor($n, 64*1024) if scalar @ftry == 1;
--
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