1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/patches/gmp/4.2.4/120-perfpow.patch Sat Apr 10 23:42:28 2010 +0200
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;