Permalink
Browse files

refactored new method _check_two_and_even, test suite for it

  • Loading branch information...
1 parent f8333c8 commit 20f51cf11461e58363efd20ffd31ca5dfaff15f2 Bob Kuo committed Jun 2, 2009
Showing with 33 additions and 12 deletions.
  1. +21 −9 lib/Math/Primality.pm
  2. +1 −1 t/is_prime.t
  3. +5 −1 t/is_strong_lucas_pseudoprime.t
  4. +6 −1 t/is_strong_pseudoprime.t
View
@@ -104,9 +104,8 @@ sub is_strong_pseudoprime($;$)
$base = GMP->new($base);
$n = GMP->new($n);
- my $cmp = Rmpz_cmp_ui($n, 2 );
- return 1 if $cmp == 0;
- return 0 if $cmp < 0;
+ my $cmp = _check_two_and_even($n);
+ return $cmp if $cmp != 2;
# unnecessary but faster if $n is even
return 0 if Rmpz_even_p($n);
@@ -172,10 +171,8 @@ sub is_strong_lucas_pseudoprime($)
return 0;
}
# we also need to weed out all N < 3 and all even N
- my $cmp = Rmpz_cmp_ui($n, 2 );
- return 1 if $cmp == 0;
- return 0 if $cmp < 0;
- return 0 if Rmpz_even_p($n);
+ my $cmp = _check_two_and_even($n);
+ return $cmp if $cmp != 2;
# determine Selfridge parameters D, P and Q
my ($D, $P, $Q) = _find_dpq_selfridge($n);
if ($D == 0) { #_find_dpq_selfridge found a factor of N
@@ -271,7 +268,7 @@ sub is_strong_lucas_pseudoprime($)
return 0;
}
-#selfridge's method for finding the tuple (D,P,Q) for is_strong_lucas_pseudoprime
+# selfridge's method for finding the tuple (D,P,Q) for is_strong_lucas_pseudoprime
sub _find_dpq_selfridge($) {
my $n = GMP->new($_[0]);
my ($d,$sign,$wd) = (5,1,0);
@@ -305,18 +302,33 @@ sub _find_dpq_selfridge($) {
# Q = (1 - D) / 4
$q = (1 - $wd) / 4;
}
+ debug "found P and Q: ($p, $q)";
return ($wd, $p, $q);
}
-#alternate method for finding the tuple (D,P,Q) for is_strong_lucas_pseudoprime
+# alternate method for finding the tuple (D,P,Q) for is_strong_lucas_pseudoprime
sub _find_dpq_alternate($) {
}
+# method returns 0 if N < two or even, returns 1 if N == 2
+# returns 2 if N > 2 and odd
+sub _check_two_and_even($) {
+ my $n = GMP->new($_[0]);
+
+ my $cmp = Rmpz_cmp_ui($n, 2 );
+ return 1 if $cmp == 0;
+ return 0 if $cmp < 0;
+ return 0 if Rmpz_even_p($n);
+ return 2;
+}
+
# should do exactly what it says - returns true if number is prime, false if number is composite
sub is_prime($) {
my $n = GMP->new($_[0]);
# first eliminate all n < 2 and even n > 3
+ my $cmp = _check_two_and_even($n);
+ return $cmp if $cmp != 2;
# trial division of n up to some small number (perhaps a thousand)
# try Miller-Rabin strong psuedoprime test with base 2
# try Lucas-Selfridge strong psuedoprime test
View
@@ -11,11 +11,11 @@ use Math::GMPz;
my $z = Math::GMPz->new(3);
ok( is_prime(3), "is_prime should handle Math::GMPz objects, three is prime" );
ok( is_prime(2), "is_prime should handle 2 as a prime");
+ok( !is_prime(20), "is_prime should even numbers");
TODO: {
local $TODO = "is_prime is being worked on";
- ok( !is_prime(20), "is_prime should even numbers");
### test small numbers (<1000) ###
### test known Miller-Rabin psuedoprimes base 2 ###
### test Carmichael numbers ###
@@ -2,7 +2,7 @@
use strict;
use warnings;
-use Test::More tests => 20;
+use Test::More tests => 23;
use Math::Primality qw/ is_strong_lucas_pseudoprime/;
use Math::GMPz;
@@ -15,6 +15,10 @@ ok(is_strong_lucas_pseudoprime($z), "is_strong_lucas_pseudoprime should handle M
ok(!is_strong_lucas_pseudoprime(9), 'is_strong_lucas_pseudoprime deals with perfect squares');
ok(!is_strong_lucas_pseudoprime(16), 'is_strong_lucas_pseudoprime deals with perfect squares');
ok(!is_strong_lucas_pseudoprime(100), 'is_strong_lucas_pseudoprime deals with perfect squares');
+### test _check_two_and_even ###
+ok (Math::Primality::_check_two_and_even(2) == 1, '_check_two_and_even(2) should return 1');
+ok (Math::Primality::_check_two_and_even(20) == 0, '_check_two_and_even(20) should return 0');
+ok (Math::Primality::_check_two_and_even(1) == 0, '_check_two_and_even(1) should return 0');
### first five strong Lucas psuedoprimes ###
ok(is_strong_lucas_pseudoprime(5459), "is_strong_lucas_pseudoprime should return true for the first lucas pseudoprime");
ok(is_strong_lucas_pseudoprime(5777), "is_strong_lucas_pseudoprime should return true for the second lucas pseudoprime");
@@ -2,13 +2,18 @@
use strict;
use warnings;
-use Test::More tests => 509;
+use Test::More tests => 512;
use Math::Primality qw/ is_strong_pseudoprime /;
use Math::GMPz;
my $z = Math::GMPz->new(3);
ok(is_strong_pseudoprime($z), 'is_strong_pseudoprime groks Math::GMPz objects');
+### test _check_two_and_even ###
+ok (Math::Primality::_check_two_and_even(2) == 1, '_check_two_and_even(2) should return 1');
+ok (Math::Primality::_check_two_and_even(20) == 0, '_check_two_and_even(20) should return 0');
+ok (Math::Primality::_check_two_and_even(1) == 0, '_check_two_and_even(1) should return 0');
+### test is_strong_pseudoprime ###
ok(!is_strong_pseudoprime(-1),'-1 is not a spsp' );
ok(!is_strong_pseudoprime(0),'0 is not a spsp' );
ok(!is_strong_pseudoprime(1),'1 is not a spsp' );

0 comments on commit 20f51cf

Please sign in to comment.