[libmath-prime-util-perl] 41/55: Full Kronenburg extension for binomial

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


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

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

commit 84b1ee99b50f51eeb1538df87e5b9d9d4272aea9
Author: Dana Jacobsen <dana at acm.org>
Date:   Tue May 13 20:20:50 2014 -0700

    Full Kronenburg extension for binomial
---
 XS.xs                     | 11 +++++++----
 lib/Math/Prime/Util/PP.pm |  7 ++++---
 t/19-moebius.t            |  3 ++-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/XS.xs b/XS.xs
index 4c589dc..4147ef5 100644
--- a/XS.xs
+++ b/XS.xs
@@ -775,16 +775,19 @@ znorder(IN SV* sva, IN SV* svn)
       switch (ix) {
         case 0:  ret = znorder(a, n);
                  break;
-        case 1:  if (nstatus == -1) {
-                   ret = 0;
-                 } else if (astatus == -1) {
+        case 1:  if ( (astatus == 1 && (nstatus == -1 || n > a)) ||
+                      (astatus ==-1 && (nstatus == -1 && n > a)) )
+                   { ret = 0; break; }
+                 if (nstatus == -1)
+                   n = a - n; /* n<0,k<=n:  (-1)^(n-k) * binomial(-k-1,n-k) */
+                 if (astatus == -1) {
                    ret = binomial( -my_sviv(sva)+n-1, n );
                    if (ret > 0 && ret <= (UV)IV_MAX)
                      XSRETURN_IV( (IV)ret * ((n&1) ? -1 : 1) );
                    goto overflow;
                  } else {
                    ret = binomial(a, n);
-                   if (ret == 0 && n <= a)
+                   if (ret == 0)
                      goto overflow;
                  }
                  break;
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index 4e5d244..86c0596 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -1787,13 +1787,14 @@ sub kronecker {
 }
 sub binomial {
   my($n, $k) = @_;
-  if ($k <= 0) { return ($k == 0) ? 1 : 0; }
+  return 0 if $n >= 0 && ($k < 0 || $k > $n);
+  return 0 if $n < 0  && $k < 0 && $k > $n;
   my $r;
   if ($n >= 0) {
     $r = Math::BigInt->new("$n")->bnok("$k");
     $r = _bigint_to_int($r) if $r->bacmp(''.~0) <= 0;
-  } else {
-    # Math::BigInt is incorrect for negative n
+  } else { # Math::BigInt is incorrect for negative n
+    $k = $n-$k if $k < 0;
     $r = Math::BigInt->new( ''.(-$n+$k-1) )->bnok("$k");
     if ($k & 1) {
       $r->bneg;
diff --git a/t/19-moebius.t b/t/19-moebius.t
index b9409b0..aeb074e 100644
--- a/t/19-moebius.t
+++ b/t/19-moebius.t
@@ -413,7 +413,8 @@ my @binomials = (
  [ -10,5, -2002 ],
  [ -11,22, 64512240 ],
  [ -12,23, -286097760 ],
- [ -12,-23, 0 ],
+ [ -23,-26, -2300 ],     # Kronenburg extension
+ [ -12,-23, -705432 ],   # same
  [  12,-23, 0 ],
  [  12,-12, 0 ],
  [ -12,0, 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