[libmath-prime-util-perl] 21/59: More bignum fun
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:44:55 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 50222dfacb4a3c8186f5355c4ae383aed0cfd1bd
Author: Dana Jacobsen <dana at acm.org>
Date: Mon Jul 2 02:20:28 2012 -0600
More bignum fun
---
lib/Math/Prime/Util.pm | 17 ++++++++++++-----
lib/Math/Prime/Util/PP.pm | 27 +++++++++++++++++++--------
2 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index 633370f..171371a 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -787,10 +787,9 @@ The main development of the module has been for working with Perl UVs, so
support for these types of functions inside Perl now, I recommend L<Math::Pari>.
The module is thread-safe and allows concurrency between Perl threads while
-still sharing a prime cache. It is not itself multithreaded. The one caveat
-is on Win32 (non-Cygwin) where you must use C<precalc> if the function will
-use primes (C<primes>, C<prime_count> greater than 900M,
-C<nth_prime> greater than 45M).
+still sharing a prime cache. It is not itself multithreaded. See the
+L<Limitations|/"LIMITATIONS"> section if you are using Win32 and threads in
+your program.
=head1 BIGNUM SUPPORT
@@ -1300,6 +1299,11 @@ Print pseudoprimes base 17:
perl -MMath::Prime::Util=:all -E 'my $n=$base|1; while(1) { print "$n " if miller_rabin($n,$base) && !is_prime($n); $n+=2; } BEGIN {$|=1; $base=17}'
+Print some primes above 64-bit range:
+
+ perl -MMath::Prime::Util=:all -Mbigint -E 'my $start=100000000000000000000; say join "\n", @{primes($start,$start+1000)}'
+ # Similar behavior:
+ # perl -MMath::Pari=:int,PARI,nextprime -E 'my $start = PARI "100000000000000000000"; my $end = $start+1000; my $p=nextprime($start); while ($p <= $end) { say $p; $p = nextprime($p+1); }'
=head1 LIMITATIONS
@@ -1315,7 +1319,10 @@ to update to a more recent Perl.
The module is thread-safe and should allow good concurrency on all platforms
that support Perl threads except Win32 (Cygwin works). With Win32, either
don't use threads or make sure C<prime_precalc> is called before using
-C<primes>, C<prime_count>, or C<nth_prime> with large inputs.
+C<primes>, C<prime_count>, or C<nth_prime> with large inputs. This is B<only>
+an issue if you use non-Cygwin Win32 and call these routines from within
+Perl threads.
+
=head1 PERFORMANCE
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index e208a1c..684ecb0 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -76,12 +76,13 @@ 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,1
sub _is_prime7 { # n must not be divisible by 2, 3, or 5
my($n) = @_;
- return is_prob_prime($n) if $n > 10_000_000;
-
foreach my $i (qw/7 11 13 17 19 23 29/) {
return 2 if $i*$i > $n;
return 0 if ($n % $i) == 0;
}
+
+ return is_prob_prime($n) if $n > 10_000_000;
+
my $limit = int(sqrt($n));
my $i = 31;
while (($i+30) <= $limit) {
@@ -313,11 +314,21 @@ sub next_prime {
my($n) = @_;
croak "Input must be a positive integer" unless _is_positive_int($n);
return 0 if ($n >= ((_PP_prime_maxbits == 32) ? 4294967291 : 18446744073709551557))
- && (!defined $bigint::VERSION);
+ && (!defined $Math::BigInt::VERSION);
return $_prime_next_small[$n] if $n <= $#_prime_next_small;
- my $d = int($n/30);
- my $m = $n - $d*30;
+ if (ref($n) =~ /^Math::Big/) {
+ $n = $n->numify if $n <= ~0;
+ } elsif ($n > ~0) {
+ $n = Math::BigInt->new($n);
+ }
+
+ # Be careful trying to do:
+ # my $d = int($n/30);
+ # my $m = $n - $d*30;
+ # See: int(9999999999999999403 / 30) => 333333333333333312 (off by 1)
+ my $m = $n % 30;
+ my $d = int( ($n - $m) / 30 );
if ($m == 29) { $d++; $m = 1;} else { $m = $_nextwheel30[$m]; }
while (!_is_prime7($d*30+$m)) {
$m = $_nextwheel30[$m];
@@ -336,7 +347,7 @@ sub prev_prime {
$n++ if ($n % 2) == 0;
do {
$n -= 2;
- } while ( (($n % 3) == 0) || (!is_prime($n)) );
+ } while ( (($n % 3) == 0) || (($n % 5) == 0) || (!_is_prime7($n)) );
$n;
# This is faster for larger intervals, slower for short ones.
@@ -350,8 +361,8 @@ sub prev_prime {
#}
#$n;
- #my $d = int($n/30);
- #my $m = $n - $d*30;
+ #my $m = $n % 30;
+ #my $d = int( ($n - $m) / 30 );
#do {
# $m = $_prevwheel30[$m];
# $d-- if $m == 29;
--
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