[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