[libmath-prime-util-perl] 28/35: Make sure we don't overflow large divisor counts on 32-bit machines

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:50:05 UTC 2015


This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.33
in repository libmath-prime-util-perl.

commit 2f35ab99804fdb22fa887c75622d53a1a0bd09e4
Author: Dana Jacobsen <dana at acm.org>
Date:   Fri Nov 15 13:00:12 2013 -0800

    Make sure we don't overflow large divisor counts on 32-bit machines
---
 lib/Math/Prime/Util.pm | 25 ++++++++++++++-----------
 t/81-bignum.t          |  9 +++++++--
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index eb1067a..3369053 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -1525,16 +1525,22 @@ sub jordan_totient {
 
 my @_ds_overflow =  # We'll use BigInt math if the input is larger than this.
   (~0 > 4294967295)
-   ? (0, 3000000000000000000, 3000000000, 2487240, 64260, 7026)
-   : (0,           845404560,      52560,    1548,   252,   84);
+   ? (124, 3000000000000000000, 3000000000, 2487240, 64260, 7026)
+   : ( 50,           845404560,      52560,    1548,   252,   84);
 sub divisor_sum {
   my($n, $k) = @_;
   return (0,1)[$n] if defined $n && $n <= 1;
   _validate_num($n) || _validate_positive_integer($n);
 
-  # With no argument, call the XS routine for k=1 immediately if possible.
-  return _XS_divisor_sum($n, 1)
-    if !defined $k && $n <= $_XS_MAXVAL && $n < $_ds_overflow[1];
+  # Call the XS routine for k=0 and k=1 immediately if possible.
+  if ($n <= $_XS_MAXVAL) {
+    if (defined $k) {
+      return _XS_divisor_sum($n, 0) if $k eq '0';
+      return _XS_divisor_sum($n, 1) if $k eq '1' && $n < $_ds_overflow[1];
+    } else {
+      return _XS_divisor_sum($n, 1) if $n < $_ds_overflow[1];
+    }
+  }
 
   if (defined $k && ref($k) eq 'CODE') {
     my $sum = $n-$n;
@@ -1548,12 +1554,9 @@ sub divisor_sum {
     unless !defined $k || _validate_num($k) || _validate_positive_integer($k);
   $k = 1 if !defined $k;
 
-  my $will_overflow = ($k == 0) ? 0
-                    : ($k  > 5) ? 1
-                    : $n >= $_ds_overflow[$k];
-
-  # Given a large enough primorial, even k=0 will overflow.
-  $will_overflow = 1 if $k==0 && ref($n) eq 'Math::BigInt' && $n->length > 123;
+  my $will_overflow = ($k == 0) ? (length($n) >= $_ds_overflow[0])
+                    : ($k <= 5) ? ($n >= $_ds_overflow[$k])
+                    : 1;
 
   return _XS_divisor_sum($n, $k) if $n <= $_XS_MAXVAL && !$will_overflow;
 
diff --git a/t/81-bignum.t b/t/81-bignum.t
index 3dd376f..99dc9bc 100644
--- a/t/81-bignum.t
+++ b/t/81-bignum.t
@@ -75,7 +75,7 @@ plan tests =>  0
              + 6*2*$extra # more PC tests
              + 2*scalar(keys %factors)
              + scalar(keys %allfactors)
-             + 7   # moebius, euler_phi, jordan totient, divsum, znorder
+             + 10  # moebius, euler_phi, jordan totient, divsum, znorder
              + 2   # liouville
              + 15  # random primes
              + 2   # miller-rabin random
@@ -103,6 +103,7 @@ use Math::Prime::Util qw/
   divisor_sum
   znorder
   liouville
+  pn_primorial
   ExponentialIntegral
   LogarithmicIntegral
   RiemannR
@@ -215,7 +216,7 @@ SKIP: {
 ###############################################################################
 
 SKIP: {
-  skip "Your 64-bit Perl is broken, skipping moebius and euler_phi tests", 7 if $broken64;
+  skip "Your 64-bit Perl is broken, skipping moebius,euler_phi,divsum tests", 10 if $broken64;
   my $n;
   $n = 618970019642690137449562110;
   is( moebius($n), -1, "moebius($n)" );
@@ -226,6 +227,10 @@ SKIP: {
   # Done wrong, the following will have a bunch of extra zeros.
   my $hundredfac = Math::BigInt->new(100)->bfac;
   is( divisor_sum($hundredfac), 774026292208877355243820142464115597282472420387824628823543695735957009720184359087194959566149232506852422409529601312686157396490982598473425595924480000000, "Divisor sum of 100!" );
+  # These should yield bigint results.
+  is( divisor_sum(pn_primorial(71),0), 2361183241434822606848, "Divisor count(353#)" );
+  is( divisor_sum(pn_primorial(71),1), 592169807666179080336898884075191344863843751107274613826065194910163387683715846870630955555390054490059876013007363004327526400000000000000000, "Divisor sum(353#)" );
+  is( divisor_sum(pn_primorial(71),2), "12949784465615028275107011121945805610528825503288465119226912396970037707579655747291137846306343809131200618880146749230653882973421307691846381555612687582146340434261447200658536708625570145324567757917046739100833453606420350207262720000000000000000000000000000000000000000000000000", "sigma_2(353#)" );
   # Calc/FastCalc are slugs with this function, so tone things down.
   #is( znorder(82734587234,927208363107752634625923555185111613055040823736157),
   #    4360156780036190093445833597286118936800,

-- 
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