patches/gmp/4.2.4/120-perfpow.patch
changeset 3103 a8bf927f6e37
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/patches/gmp/4.2.4/120-perfpow.patch	Tue Nov 06 17:02:06 2012 +0100
     1.3 @@ -0,0 +1,149 @@
     1.4 +Original patch from: perfpow.c.diff
     1.5 +
     1.6 +-= BEGIN original header =-
     1.7 +Copyright 1998, 1999, 2000, 2001, 2005, 2008 Free Software Foundation, Inc.
     1.8 +
     1.9 +This file is part of the GNU MP Library.
    1.10 +
    1.11 +The GNU MP Library is free software; you can redistribute it and/or modify
    1.12 +it under the terms of the GNU Lesser General Public License as published by
    1.13 +the Free Software Foundation; either version 3 of the License, or (at your
    1.14 +option) any later version.
    1.15 +
    1.16 +The GNU MP Library is distributed in the hope that it will be useful, but
    1.17 +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    1.18 +or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
    1.19 +License for more details.
    1.20 +
    1.21 +You should have received a copy of the GNU Lesser General Public License
    1.22 +along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
    1.23 +
    1.24 +-= END original header =-
    1.25 +
    1.26 +diff -durN gmp-4.2.4.orig/mpz/perfpow.c gmp-4.2.4/mpz/perfpow.c
    1.27 +--- gmp-4.2.4.orig/mpz/perfpow.c	2007-08-30 20:31:41.000000000 +0200
    1.28 ++++ gmp-4.2.4/mpz/perfpow.c	2009-03-08 18:36:16.000000000 +0100
    1.29 +@@ -1,7 +1,7 @@
    1.30 + /* mpz_perfect_power_p(arg) -- Return non-zero if ARG is a perfect power,
    1.31 +    zero otherwise.
    1.32 + 
    1.33 +-Copyright 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
    1.34 ++Copyright 1998, 1999, 2000, 2001, 2005, 2008 Free Software Foundation, Inc.
    1.35 + 
    1.36 + This file is part of the GNU MP Library.
    1.37 + 
    1.38 +@@ -59,6 +59,8 @@
    1.39 + #define SMALLEST_OMITTED_PRIME 1009
    1.40 + 
    1.41 + 
    1.42 ++#define POW2P(a) (((a) & ((a) - 1)) == 0)
    1.43 ++
    1.44 + int
    1.45 + mpz_perfect_power_p (mpz_srcptr u)
    1.46 + {
    1.47 +@@ -72,16 +74,13 @@
    1.48 +   mp_size_t usize = SIZ (u);
    1.49 +   TMP_DECL;
    1.50 + 
    1.51 +-  if (usize == 0)
    1.52 +-    return 1;			/* consider 0 a perfect power */
    1.53 ++  if (mpz_cmpabs_ui (u, 1) <= 0)
    1.54 ++    return 1;			/* -1, 0, and +1 are perfect powers */
    1.55 + 
    1.56 +   n2 = mpz_scan1 (u, 0);
    1.57 +   if (n2 == 1)
    1.58 +     return 0;			/* 2 divides exactly once.  */
    1.59 + 
    1.60 +-  if (n2 != 0 && (n2 & 1) == 0 && usize < 0)
    1.61 +-    return 0;			/* 2 has even multiplicity with negative U */
    1.62 +-
    1.63 +   TMP_MARK;
    1.64 + 
    1.65 +   uns = ABS (usize) - n2 / BITS_PER_MP_LIMB;
    1.66 +@@ -89,6 +88,14 @@
    1.67 +   MPZ_TMP_INIT (u2, uns);
    1.68 + 
    1.69 +   mpz_tdiv_q_2exp (u2, u, n2);
    1.70 ++  mpz_abs (u2, u2);
    1.71 ++
    1.72 ++  if (mpz_cmp_ui (u2, 1) == 0)
    1.73 ++    {
    1.74 ++      TMP_FREE;
    1.75 ++      /* factoring completed; consistent power */
    1.76 ++      return ! (usize < 0 && POW2P(n2));
    1.77 ++    }
    1.78 + 
    1.79 +   if (isprime (n2))
    1.80 +     goto n2prime;
    1.81 +@@ -97,6 +104,9 @@
    1.82 +     {
    1.83 +       prime = primes[i];
    1.84 + 
    1.85 ++      if (mpz_cmp_ui (u2, prime) < 0)
    1.86 ++	break;
    1.87 ++
    1.88 +       if (mpz_divisible_ui_p (u2, prime))	/* divisible by this prime? */
    1.89 + 	{
    1.90 + 	  rem = mpz_tdiv_q_ui (q, u2, prime * prime);
    1.91 +@@ -115,12 +125,6 @@
    1.92 + 	      n++;
    1.93 + 	    }
    1.94 + 
    1.95 +-	  if ((n & 1) == 0 && usize < 0)
    1.96 +-	    {
    1.97 +-	      TMP_FREE;
    1.98 +-	      return 0;		/* even multiplicity with negative U, reject */
    1.99 +-	    }
   1.100 +-
   1.101 + 	  n2 = gcd (n2, n);
   1.102 + 	  if (n2 == 1)
   1.103 + 	    {
   1.104 +@@ -128,10 +132,11 @@
   1.105 + 	      return 0;		/* we have multiplicity 1 of some factor */
   1.106 + 	    }
   1.107 + 
   1.108 +-	  if (mpz_cmpabs_ui (u2, 1) == 0)
   1.109 ++	  if (mpz_cmp_ui (u2, 1) == 0)
   1.110 + 	    {
   1.111 + 	      TMP_FREE;
   1.112 +-	      return 1;		/* factoring completed; consistent power */
   1.113 ++	      /* factoring completed; consistent power */
   1.114 ++	      return ! (usize < 0 && POW2P(n2));
   1.115 + 	    }
   1.116 + 
   1.117 + 	  /* As soon as n2 becomes a prime number, stop factoring.
   1.118 +@@ -169,6 +174,10 @@
   1.119 +   else
   1.120 +     {
   1.121 +       unsigned long int nth;
   1.122 ++
   1.123 ++      if (usize < 0 && POW2P(n2))
   1.124 ++	return 0;
   1.125 ++
   1.126 +       /* We found some factors above.  We just need to consider values of n
   1.127 + 	 that divides n2.  */
   1.128 +       for (nth = 2; nth <= n2; nth++)
   1.129 +@@ -184,8 +193,11 @@
   1.130 + 	    exact = mpz_root (q, u2, nth);
   1.131 + 	  if (exact)
   1.132 + 	    {
   1.133 +-	      TMP_FREE;
   1.134 +-	      return 1;
   1.135 ++	      if (! (usize < 0 && POW2P(nth)))
   1.136 ++		{
   1.137 ++		  TMP_FREE;
   1.138 ++		  return 1;
   1.139 ++		}
   1.140 + 	    }
   1.141 + 	  if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
   1.142 + 	    {
   1.143 +@@ -199,6 +211,9 @@
   1.144 +     }
   1.145 + 
   1.146 + n2prime:
   1.147 ++  if (usize < 0 && POW2P(n2))
   1.148 ++    return 0;
   1.149 ++
   1.150 +   exact = mpz_root (NULL, u2, n2);
   1.151 +   TMP_FREE;
   1.152 +   return exact;